|
IAR. Динамический размер структуры. Micro Menu. IAR |
|
|
|
Dec 14 2014, 07:45
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Тут пример Micro Menu. Проект написан для WinAVR (AVR Toolchain). В этом проекте размер структуры зависит от размера текстовой строки. В IAR никак не могу добиться и понять, как мне сделать, чтобы размер структуры зависел от размера текстовой строки. Проект компилируется, только если задать так: Код //======================================================================== typedef struct menu_item { void *Parent; void *Child; void *Next; void *Prev; FuncPtr NumFunc; FuncPtr EnterFunc; FuncPtr MenuFunc; char Text[20]; } menu_item; //======================================================================== Есть ли возможность добиться, чтобы в IAR размер структуры зависел от размера текстовой строки?
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Dec 14 2014, 07:58
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(demiurg1978 @ Dec 14 2014, 10:45)  char Text[20]; Напишите так: const char* Text; Оригинальный вариант const char Text[]; ей эквивалентен, хотя некоторые компиляторы его не любят. Ваш вариат char Text[20]; в данном случае имеет совершенно иной смысл - это вы засандалили в структуру массив целиком, а в оригинале только указатель на него. P.S. В системах меню имена айтемов - обычно всегда константные стринги, а потому никогда не бывает необходимости их куда-то копировать, в том числе и в структуры.
|
|
|
|
|
Dec 14 2014, 08:15
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Ксения, благодарю за подсказку! Сделал так: Код typedef struct menu_item { void *Parent; void *Child; void *Next; void *Prev; FuncPtr NumFunc; FuncPtr EnterFunc; FuncPtr MenuFunc; char __flash *Text; } menu_item; Даже программу не пришлось править. С const IAR выдает ошибки.
Сообщение отредактировал demiurg1978 - Dec 14 2014, 08:16
|
|
|
|
|
Dec 14 2014, 08:22
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Xenia @ Dec 14 2014, 10:58)  Оригинальнй вариант const char Text[]; ей эквивалентен, хотя некоторые компиляторы ее не любят. Нет, совсем не эквивалентен. В стандарте C99 это называется flexible array member. Там не сказано, что будет с таким массивом, если объявить переменную, имеющую тип такой структуры. Поэтому моя версия такова: яр при объявлении переменной игнорирует массив переменной длины и не выделяет для него память, как будто его нет совсем, - то ли поленились реализовать, то ли решили, что стандарт этого не требует (вроде бы так оно и есть). А вот gcc реализовал: выделил память под массив нужной длины и положил туда текст - молодцы, чо. Только в результате получается, что этот код не переносимый. Цитата(demiurg1978 @ Dec 14 2014, 11:15)  Даже программу не пришлось править. С const IAR выдает ошибки. Вот так неправильно: "char __flash *Text;" Вот так правильно: "char *__flash Text;"
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 14 2014, 08:31
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(scifi @ Dec 14 2014, 14:22)  Вот так правильно: "char *__flash Text;" Error[Pa004]: illegal declaration G:\Work\Projects\ATMEL\IAR\C\MENU_TEMPLATE\menu.h 32
|
|
|
|
|
Dec 14 2014, 08:49
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(Сергей Борщ @ Dec 14 2014, 14:47)  Отсюда можно сделать вывод, что у автора вопроса в настройках стоит галочка "компилировать как C++". А где такая настройка? Полазил в настройках, пока не нашел.
|
|
|
|
|
Dec 14 2014, 10:30
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(scifi @ Dec 14 2014, 12:59)  А на нормальных процах, где не __flash, а const, отлично работает. Получается, строки будут сидеть в ОЗУ. М-да, кривой этот яр для авр. Что простительно, так как авр сам кривой (раздельные адресные пространства для ПЗУ и ОЗУ). Отчего же кривой.  В данном случае указатель, находящийся внутри структуры, должен указывать на истинный тип стринга. Это не вина указателя в том, что одни програмисты хранят стринги в ОЗУ, а другие в ПЗУ. А если у тех стрингов есть еще какие-то дополнительные атрибуты типа far или huge, то, стало быть, и их придется добавить в тип указателя, иначе его не присвоить. IAR же в этом отношении не кривой, т.к. позволяет по требованию программиста помещать строковые константы во flash или держать их в OЗУ (последний способ по умолчанию). Там на этот счет у комилятора специальная опция имеется. Тем не менее, в программе тип указателя приходится определять явно - добровольно заменять const на __flash компилятор не станет. И для этого есть очень серьезные основания. Ну, а в том, что адресные пространства для ПЗУ и ОЗУ раздельные, виноват не IAR, а Гарвардская архитектура.
|
|
|
|
|
Dec 14 2014, 10:50
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(Xenia @ Dec 14 2014, 16:30)  Тем не менее, в программе тип указателя приходится определять явно - добровольно заменять const на __flash компилятор не станет. Ну, а в том, что адресные пространства для ПЗУ и ОЗУ раздельные, виноват не IAR, а Гарвардская архитектура. То есть запись типа char __flash *ptr; вполне нормальна для IAR?
|
|
|
|
|
Dec 14 2014, 10:59
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Xenia @ Dec 14 2014, 13:30)  Тем не менее, в программе тип указателя приходится определять явно - добровольно заменять const на __flash компилятор не станет. Ну вот "char *const txt;" работает и делает то, что нужно, а "char *__flash txt;" не работает. Так что заменяй-не заменяй, а нужного результата нет. Да и нет способа написать строковый литерал, автоматически ложащийся в ПЗУ (что-то типа "abc"@FLASH). Цитата(Xenia @ Dec 14 2014, 13:30)  Ну, а в том, что адресные пространства для ПЗУ и ОЗУ раздельные, виноват не IAR, а Гарвардская архитектура. На этот Гарвард столько собак повесили, что диву даёшься :-) Тот же Cortex-M3 - очень даже гарвардская архитектура, и адресное пространство у него единое. Так что архитектура ни при чём. Они решали какие-то другие задачи, но вместе с водой выплеснули и ребёнка, ИМХО.
|
|
|
|
|
Dec 14 2014, 11:21
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(demiurg1978 @ Dec 14 2014, 13:50)  То есть запись типа char __flash *ptr; вполне нормальна для IAR? Да, именно этот атрибут имеют стринги, помещенные во flash. Содержимое хидера pgmspace.h - тому яркое подтверждение (в нем определены printf и scanf, работающие с форматом, лежащем во flash). Цитата(scifi @ Dec 14 2014, 13:59)  Ну вот "char *const txt;" работает и делает то, что нужно, а "char *__flash txt;" не работает. Чему тут удивляться, определение const или __flash должно стоять непосредственно перед указателем, к которому оно относится. Цитата(scifi @ Dec 14 2014, 13:59)  На этот Гарвард столько собак повесили, что диву даёшься :-) Тот же Cortex-M3 - очень даже гарвардская архитектура, и адресное пространство у него единое. 32-битник может себе это позволить, а AVR-ке приходится экономить, чтобы адрес поместился в 2 байта. Цитата(scifi @ Dec 14 2014, 13:59)  Да и нет способа написать строковый литерал, автоматически ложащийся в ПЗУ (что-то типа "abc"@FLASH) IAR вроде бы тоже так умеет, только там не FLASH, а имя сегмента надо писать. Впрочем, в отношении стрингов я этого делать не пробовала.
|
|
|
|
|
Dec 14 2014, 11:32
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(scifi @ Dec 14 2014, 16:59)  ... Не надо на IAR наговаривать. Пусть с флеш у него лишние телодвижения. По сравнению с другими компиляторами - небо и земля. С WinAVR (AVR Toolchain) взаимопонимания у нас не нашлось. Чего стоят эти pgm_read_byte, pgm_read_word. И так далее и тому подобное. WinAVR (AVR Toolchain) позволяет писать функции, переменные как попало. IAR тут же выдает сообщения, что функция,к примеру, объявлена\не объявлена не по феншую... Размер исполяемого кода, опять же, к примеру, гораздо выигрывает, по сравнению с WinAVR (AVR Toolchain)
|
|
|
|
|
Dec 14 2014, 12:47
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Структура меню же не меняется в процессе работы? Может тогда проще __flash сразу ко всем menu_item? Код menu_item __flash submenu1[] = { { .Parent=&main[0], Child=&submenu2[0], .Next=&submenu1[1], .Prev=&submenu1[0], ..., .Text="Submenu1" }, ... } menu_item __flash main[] = { { .Parent=&main[0], Child=&submenu1[0], .Next=&main[0], .Prev=&main[0], ..., .Text="Main" } }
|
|
|
|
|
Dec 14 2014, 18:30
|
Местный
  
Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709

|
Цитата(psL @ Dec 14 2014, 18:47)  ... Что-то как-то сложно у вас... Код MAKE_MENU (L_OUT_MODE, NULL_ENTRY, L1_I1_TEMP, NULL_ENTRY, NULL_ENTRY, show_service_menu, out_mode_init, NULL_FUNC, "ПАРАМЕТРЫ"); MAKE_MENU (L1_I1_TEMP, L_OUT_MODE, L2_I1_TEMP, L1_I2_TIME, NULL_ENTRY, NULL_FUNC, menu_parameters_init, NULL_FUNC, "ТЕМПЕРАТУРА"); MAKE_MENU (L1_I2_TIME, L_OUT_MODE, TIME_I1_COOLING, L1_I3_SPEED, L1_I1_TEMP, NULL_FUNC, menu_parameters_init, NULL_FUNC, "ТАЙМЕРЫ"); MAKE_MENU (L1_I3_SPEED, L_OUT_MODE, SPEED_I1_CLOSE, L1_I4_PRESSURE, L1_I2_TIME, NULL_FUNC, menu_parameters_init, NULL_FUNC, "СКОРОСТЬ");
Сообщение отредактировал demiurg1978 - Dec 14 2014, 18:38
|
|
|
|
|
Dec 14 2014, 20:30
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(demiurg1978 @ Dec 14 2014, 21:30)  Что-то как-то сложно у вас... Код MAKE_MENU (... Это пример. А что, макрос MAKE_MENU делает что-то принципиально иное? Просто подумал, что раз меню статически задается, то нет необходимости в двусвязном списке - можно узлы подуровеня в дереве сразу в массиив положить, тогда поля.Next и .Prev будут не нужны.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|