Да. Можно и так. А можно и без структуры.pokk писал(а):Это будет так ?
Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
- Реклама
Re: Вопросы по С/С++ (СИ)
Да. Можно и так. А можно и без структуры.
Да ну? Как по мне, компилятор такое как число не поймет. Правильнее всего сделать через union.
Код: Выделить всё
typedef union {
int32_t my_long;
uint8_t my_byte[4];
} my_custom_long;
Код: Выделить всё
my_custom_long a,b,c;
uint8_t z;
...
a.my_long=1;
b.my_long=2;
...
c.my_long=a.my_long + b.my_long; \\ в 'c' получится 3
...
z=c.my_byte[3]; \\побайтовый доступ к 'c'
Разница между теорией и практикой на практике гораздо больше, чем в теории.
-
Tolmi
- Говорящий с текстолитом
- Сообщения: 1658
- Зарегистрирован: Вс дек 11, 2011 05:25:04
- Откуда: Киев, Украина
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Нет, скорее так :pokk писал(а): Это будет так ?Код: Выделить всё
typedef struct { char b[3]; } U8long; U8long *u8 = (U8long*)h;
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
int main()
{
float pi=3.141593;
unsigned char c1,c2,c3,c4;
unsigned char *cptr=(unsigned сhar*)π
c1=cptr[0];c2=cptr[1];
c3=cptr[2];c4=cptr[3];
printf(" %.02X %.02X %.02X %.02X\n",c1,c2,c3,c4);
return(0);
}
In theory, theory and practice are the same. In practice, they're not.
Re: Вопросы по С/С++ (СИ)
Скажите, а как передать в функцию в качестве параметра массив из EEPROM в IAR AVR?
Допустим, есть массив:
Объявил функцию:
Но компилятор ругается на несоответствие типов (что и ожидал).
Если я напишу
unsigned char RCU_Decoder(__eeprom unsigned char* RCU_DC, unsigned char n_btn);
Не будет ли компилятор создавать сдуру промежуточный указатель в EEPROM и портить ресурс флешки при каждом вызове функции?
Смысл - будет кнопка типа шифта и хочу сделать разные массивы для двух независимых подфункций устройства, чтобы можно было независимо править коды кнопок.
Допустим, есть массив:
Код: Выделить всё
__eeprom unsigned char eep_RCU_DC[N_BUTTONS]={
0x00, //[0] конпка 0
0x01, //[1] конпка 1
0x02, //[2] конпка 2
0x03, //[3] конпка 3
0x04, //[4] конпка 4
0x05, //[5] конпка 5
0x06, //[6] конпка 6
0x07, //[7] конпка 7
0x08, //[8] конпка 8
0x09, //[9] конпка 9};Код: Выделить всё
unsigned char RCU_Decoder(unsigned char* RCU_DC, unsigned char n_btn);Если я напишу
unsigned char RCU_Decoder(__eeprom unsigned char* RCU_DC, unsigned char n_btn);
Не будет ли компилятор создавать сдуру промежуточный указатель в EEPROM и портить ресурс флешки при каждом вызове функции?
Смысл - будет кнопка типа шифта и хочу сделать разные массивы для двух независимых подфункций устройства, чтобы можно было независимо править коды кнопок.
Re: Вопросы по С/С++ (СИ)
А квалификатор "const" не толкает в EEPROM??aam писал(а):Допустим, есть массив:
- Реклама
Re: Вопросы по С/С++ (СИ)
Что-то я опять не как понять не могу что это вот за штука ? Это единственное место где uip_udp_new используется.
Полностью struct uip_udp_conn * uip_udp_new(u16_t *ripaddr, u16_t rport)
И используют это всё тоже как-то не сильно понятно я понял тут идёт цикл по адресам. Началу цикла присваивается адрес потом его увеличиваем пока не дойдём до конца структуры(uip_udp_conns[UIP_UDP_CONNS]) только вот не понятно как при следующей итерации uip_udp_conn->lport изменится
Код: Выделить всё
struct uip_udp_conn *
uip_udp_new(u16_t *ripaddr, u16_t rport)
{}
struct uip_udp_conn *uip_udp_new(u16_t *ripaddr, u16_t rport);
struct uip_udp_conn {
u16_t ripaddr[2]; /**< The IP address of the remote peer. */
u16_t lport; /**< The local port number in network byte order. */
u16_t rport; /**< The remote port number in network byte order. */
};
Спойлер
Код: Выделить всё
struct uip_udp_conn *
uip_udp_new(u16_t *ripaddr, u16_t rport)
{
register struct uip_udp_conn *conn;
/* Find an unused local port. */
again:
++lastport;
if(lastport >= 32000) {
lastport = 4096;
}
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == lastport) {
goto again;
}
}
conn = 0;
for(c = 0; c < UIP_UDP_CONNS; ++c) {
if(uip_udp_conns[c].lport == 0) {
conn = &uip_udp_conns[c];
break;
}
}
if(conn == 0) {
return 0;
}
conn->lport = HTONS(lastport);
conn->rport = HTONS(rport);
conn->ripaddr[0] = ripaddr[0];
conn->ripaddr[1] = ripaddr[1];
return conn;
}Код: Выделить всё
for(uip_udp_conn = &uip_udp_conns[0];
uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
++uip_udp_conn) {
if(uip_udp_conn->lport != 0 &&
UDPBUF->destport == uip_udp_conn->lport &&
(uip_udp_conn->rport == 0 ||
UDPBUF->srcport == uip_udp_conn->rport) &&
BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
goto udp_found;
}
}Re: Вопросы по С/С++ (СИ)
Что-то запутался как объявлять...
Массив я объявляю так:
Тогда функцию надо объявлять так:
Или куда этот const писать? Я помню, там и так и так можно, но смысл будет разный - в одном случае константный указатель, в другом - указатель на константу. А с учетом "странного" модификатора __eeprom без пол литра не разберешься 
Массив я объявляю так:
Код: Выделить всё
const __eeprom unsigned char eep_RCU_Light[N_BUTTONS]={0, 1....};Код: Выделить всё
unsigned char RCU_Decoder(unsigned char const __eeprom * RCU_DC, unsigned char n_btn);Re: Вопросы по С/С++ (СИ)
__eeprom убрать надо. Iar константный массив кидает во флешь, можно посмотреть в map файле. Можно еще через pragma location, но через const и так норм фурычит.
Re: Вопросы по С/С++ (СИ)
А я в EEPROM именно хотел - ато потом искать этот массив по всей проге. А тут четко ясно где лежит таблица кнопок и нет опасности повредить прогу если просчитаешься.
Re: Вопросы по С/С++ (СИ)
aam писал(а):А я в EEPROM именно хотел
Или я чет не понимаю??Psych писал(а):Iar константный массив кидает во флешь
Зачем искать? eep_RCU_Light -адрес первого элемента.aam писал(а): ато потом искать этот массив по всей проге
Re: Вопросы по С/С++ (СИ)
Написал:
Не катит:
Error[Pe167]: argument of type "unsigned char const __eeprom *" is incompatible with parameter of type "unsigned char const *"
Когда было
прокатывало без ошибок
Код: Выделить всё
unsigned char RCU_Decoder( unsigned char const* RCU_DC, unsigned char n_btn);
const __eeprom unsigned char eep_RCU_Light[]={...};Error[Pe167]: argument of type "unsigned char const __eeprom *" is incompatible with parameter of type "unsigned char const *"
Когда было
Код: Выделить всё
unsigned char RCU_Decoder( unsigned char const __eeprom* RCU_DC, unsigned char n_btn);Re: Вопросы по С/С++ (СИ)
Я имел ввиду так:
Так тоже должно канать.
На счет:
Код: Выделить всё
unsigned char RCU_Decoder( unsigned char const* RCU_DC, unsigned char n_btn);
const unsigned char eep_RCU_Light[]={...};На счет:
Имя массива это константный указатель(адресс известен), при вызове функции компилятор просто передаст число(адресс) в функцию.aam писал(а):если я напишу
unsigned char RCU_Decoder(__eeprom unsigned char* RCU_DC, unsigned char n_btn);
Не будет ли компилятор создавать сдуру промежуточный указатель в EEPROM и портить ресурс флешки при каждом вызове функции?
Re: Вопросы по С/С++ (СИ)
Ну так вот не канает
Насчет
aam писал(а):Написал:
Код:
unsigned char RCU_Decoder( unsigned char const* RCU_DC, unsigned char n_btn);
const __eeprom unsigned char eep_RCU_Light[]={...};
Не катит
Насчет
было интересно, насколько "законна" такая запись с точки зрения спецификации Си. Ато иногда компиляторы "имеют свое мнение", в частности, CodeVision этим славится в плане вычисления арифметических выражений дефайнов (правда там речь идет о препроцессоре)Psych писал(а):при вызове функции компилятор просто передаст число(адресс) в функцию
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
unsigned char RCU_Decoder( unsigned char const* RCU_DC, unsigned char n_btn);
const __eeprom unsigned char eep_RCU_Light[]={...};Код: Выделить всё
unsigned char RCU_Decoder( unsigned char const* RCU_DC, unsigned char n_btn);
const unsigned char eep_RCU_Light[]={...};Си не причем, это:aam писал(а):было интересно, насколько "законна" такая запись с точки зрения спецификации Си
К примеру:aam писал(а): компиляторы "имеют свое мнение"
const int x=10; и #define x 10
Одно и тоже(памяти не выделяется), только в первом случае подставит компилятор, во втором препроцессор. вот только рекомендуют компилятор предпочитать препроцессору...это я так на всякий случай
Re: Вопросы по С/С++ (СИ)
А, все, понял...Psych писал(а):Че прям нет разницы??!!
В этом случае компилятор пихнет массив во флеш. А я (или не я) буду отыскивать этот массив по всей флеше если захочу назначить функциям устройства другие кнопки другого пульта. Собственно поэтому я и засунул массив в EEPROM, т. к. там видно где он лежит, чисто эргономически.
Иначе я вообще забил бы на массивы и тупо вбил бы коды кнопок в кейсы свича.
Насчет препроцессора - это я к слову. Была у меня 1 раз тема, когда препроцессор CVAVR правильно, но "незаконно" вычислял константное выражение, которое неправильно вычислил бы "законный" Сишный компилятор, четко следующий правилам раскрытия скобок и размерам чисел в байтах. Грубо говоря, там просто вышло бы переполнение и неправильный результат, т. к. все переменные были 8-разрядные, константа - тоже, но при вычислении константы на этапе компиляции могло быть "переполнение".
Re: Вопросы по С/С++ (СИ)
Скажите, а как в IAR можно производить запись в EEPROM по указателю?
Допустим, у меня объявлены переменные в EEPROM:
__eeprom unsigned char eep_a;
__eeprom unsigned char eep_b;
__eeprom unsigned char eep_c;
...
В программе у меня увеличивается или уменьшается значение параметров пока удерживается кнопка пульта. Естественно, запись произведенной настройки в EEPROM надо производить после отпускания.
Как правильно написать функцию, которой передаю адрес переменной (например, eep_b) и значение, а функция выкидывает его по указанному адресу?
Могу ли я получить адрес переменной написав &eep_b ?
Что из себя представляет указатель вида
unsigned char __eeprom * Adress ?
Как передавать значение переменной?
Допустим пишу так:
Это правильно? Переменная Adress в этом случае будет представлять из себя unsigned int ?
Допустим, у меня объявлены переменные в EEPROM:
__eeprom unsigned char eep_a;
__eeprom unsigned char eep_b;
__eeprom unsigned char eep_c;
...
В программе у меня увеличивается или уменьшается значение параметров пока удерживается кнопка пульта. Естественно, запись произведенной настройки в EEPROM надо производить после отпускания.
Как правильно написать функцию, которой передаю адрес переменной (например, eep_b) и значение, а функция выкидывает его по указанному адресу?
Могу ли я получить адрес переменной написав &eep_b ?
Что из себя представляет указатель вида
unsigned char __eeprom * Adress ?
Как передавать значение переменной?
Допустим пишу так:
Код: Выделить всё
unsigned char __eeprom * Adress;
unsigned char b; //параметр
__eeprom unsigned char eep_b; //его копия в EEPROM
Adress=&eep_b;
*Adress=b;
Re: Вопросы по С/С++ (СИ)
По-моему, IAR берет запись в EEPROM на себя. Т.е., можно просто присваивать значение, как обычной переменной. Но лучше уточнить в документации.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Вопросы по С/С++ (СИ)
Да я знаю, что присваивать можно, но мне то надо писать конкретную переменную, а не все сразу по событию отпускания одной кнопки.
***
Закончилась моя прога(
До этого смотрел в листинг - вроде памяти еще оставалось. А щас стал в очередной раз компилить, а линкер пишет:
Открыл HEX - Тинька под завязку забита(( Открыл листинг, а там фраза:
Т. е. выходит, по результатам компиляции занято 1421 байта во флэш, которая 2048. А прога не лезет
Как так??
Оптимизацию на максимум поставил по размеру. Прога еще далека от завершения. Вот теперь не знаю что делать...
***
Скажите, а как заставить компилятор гарантированно подставлять inline-функцию?
Либо как объявить дефайнами макрос на много строк?
Просто некоторые куски кода для логичности и модульности я оформил как функции. Но эти куски вызываются в программе только в одном месте, т. е. фактически могут быть заменены на код из тела этих функций. Соответственно, так можно избавиться от всякой лабуды со стеком, которую компилятор обязан пихать в "настоящую" функцию.
Как так сделать?
***
Закончилась моя прога(
До этого смотрел в листинг - вроде памяти еще оставалось. А щас стал в очередной раз компилить, а линкер пишет:
Код: Выделить всё
Error[e16]: Segment TINY_ID (size: 0x2a align: 0) is too long for segment definition. At least 0x2 more bytes needed.
The problem occurred while processing the segment placement command
"-Z(CODE)TINY_ID=_..X_FLASH_BASE-_..X_FLASH_END", where at the moment of placement the available memory
ranges were "CODE:7d8-7ff"
Reserved ranges relevant to this placement:
CODE:26-2e NEAR_F
CODE:2f-32 INITTAB
CODE:33-7d7 CODE
CODE:7d8-7ff TINY_ID
Error while running Linker Код: Выделить всё
20 bytes in segment ABSOLUTE
1 374 bytes in segment CODE
31 bytes in segment EEPROM_I
4 bytes in segment INITTAB
6 bytes in segment INTVEC
9 bytes in segment NEAR_F
38 bytes in segment TINY_I
38 bytes in segment TINY_ID
1 421 bytes of CODE memory (+ 10 bytes shared)
38 bytes of DATA memory (+ 20 bytes shared)
31 bytes of XDATA memory
Errors: none
Warnings: none
Как так??
Оптимизацию на максимум поставил по размеру. Прога еще далека от завершения. Вот теперь не знаю что делать...
***
Скажите, а как заставить компилятор гарантированно подставлять inline-функцию?
Либо как объявить дефайнами макрос на много строк?
Просто некоторые куски кода для логичности и модульности я оформил как функции. Но эти куски вызываются в программе только в одном месте, т. е. фактически могут быть заменены на код из тела этих функций. Соответственно, так можно избавиться от всякой лабуды со стеком, которую компилятор обязан пихать в "настоящую" функцию.
Как так сделать?
Re: Вопросы по С/С++ (СИ)
Ну, можно попробовать выбрать в настройках (у Вас же IAR?) опцию agressive inlining (кажется, так называется).как заставить компилятор гарантированно подставлять inline-функцию?
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Вопросы по С/С++ (СИ)
force inline что-то типо такого


