реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> IAR. Динамический размер структуры. Micro Menu. IAR
demiurg1978
сообщение Dec 14 2014, 07:45
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 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 размер структуры зависел от размера текстовой строки?
Go to the top of the page
 
+Quote Post
Xenia
сообщение Dec 14 2014, 07:58
Сообщение #2


Гуру
******

Группа: Модератор 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. В системах меню имена айтемов - обычно всегда константные стринги, а потому никогда не бывает необходимости их куда-то копировать, в том числе и в структуры.
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2014, 08:09
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Чтобы не разбираться, можно просто заменить "char Text[];" на "char *const Text;".
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 14 2014, 08:15
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2014, 08:22
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 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;"
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 14 2014, 08:31
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 14 2014, 08:47
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Иар прекрасно работал с массивами переменной длины. Но при соблюдении трех условий:
1) В соответствии со стандартом этот массив должен быть последим членом структуры (это условие выполнено).
2) В соответствии со стандартом нельзя делать массив из таких структур (gcc имеет такое же требование, значит и это условие выполнено).
3) Файл должен компилироваться в режиме Си, в C++ массивы переменной длины не поддерживаются стандартом что в ИАРе, что в gcc.

Отсюда можно сделать вывод, что у автора вопроса в настройках стоит галочка "компилировать как C++".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 14 2014, 08:49
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



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

А где такая настройка? Полазил в настройках, пока не нашел.
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2014, 09:59
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(demiurg1978 @ Dec 14 2014, 11:31) *
Error[Pa004]: illegal declaration G:\Work\Projects\ATMEL\IAR\C\MENU_TEMPLATE\menu.h 32

А на нормальных процах, где не __flash, а const, отлично работает.
Получается, строки будут сидеть в ОЗУ. М-да, кривой этот яр для авр. Что простительно, так как авр сам кривой (раздельные адресные пространства для ПЗУ и ОЗУ).
Go to the top of the page
 
+Quote Post
Xenia
сообщение Dec 14 2014, 10:30
Сообщение #10


Гуру
******

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



Цитата(scifi @ Dec 14 2014, 12:59) *
А на нормальных процах, где не __flash, а const, отлично работает.
Получается, строки будут сидеть в ОЗУ. М-да, кривой этот яр для авр. Что простительно, так как авр сам кривой (раздельные адресные пространства для ПЗУ и ОЗУ).


Отчего же кривой. sm.gif В данном случае указатель, находящийся внутри структуры, должен указывать на истинный тип стринга. Это не вина указателя в том, что одни програмисты хранят стринги в ОЗУ, а другие в ПЗУ. А если у тех стрингов есть еще какие-то дополнительные атрибуты типа far или huge, то, стало быть, и их придется добавить в тип указателя, иначе его не присвоить.

IAR же в этом отношении не кривой, т.к. позволяет по требованию программиста помещать строковые константы во flash или держать их в OЗУ (последний способ по умолчанию). Там на этот счет у комилятора специальная опция имеется. Тем не менее, в программе тип указателя приходится определять явно - добровольно заменять const на __flash компилятор не станет. И для этого есть очень серьезные основания.

Ну, а в том, что адресные пространства для ПЗУ и ОЗУ раздельные, виноват не IAR, а Гарвардская архитектура.
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 14 2014, 10:50
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Цитата(Xenia @ Dec 14 2014, 16:30) *
Тем не менее, в программе тип указателя приходится определять явно - добровольно заменять const на __flash компилятор не станет. Ну, а в том, что адресные пространства для ПЗУ и ОЗУ раздельные, виноват не IAR, а Гарвардская архитектура.

То есть запись типа char __flash *ptr; вполне нормальна для IAR?
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2014, 10:59
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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 - очень даже гарвардская архитектура, и адресное пространство у него единое.
Так что архитектура ни при чём. Они решали какие-то другие задачи, но вместе с водой выплеснули и ребёнка, ИМХО.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Dec 14 2014, 11:21
Сообщение #13


Гуру
******

Группа: Модератор 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, а имя сегмента надо писать. Впрочем, в отношении стрингов я этого делать не пробовала.
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Dec 14 2014, 11:32
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 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)
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 14 2014, 12:20
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(demiurg1978 @ Dec 14 2014, 13:50) *
То есть запись типа char __flash *ptr; вполне нормальна для IAR?

Виноват, нужно именно так. Я немного запутался, когда написал "char *__flash ptr;" - такая запись для полей структуры довольно бессмысленна.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 08:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.01493 секунд с 7
ELECTRONIX ©2004-2016