|
ARM, Keil, C/C++ - программирование, Как разместить константу во флеше? |
|
|
|
Jul 22 2009, 14:51
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 13-01-06
Из: Санкт-Петербург
Пользователь №: 13 154

|
Здравствуйте.
Перехожу на программирование ARM -микроконтроллеров, компилятор Keil. До этого работал с аналогичным компилятором, но для 51 контроллеров.
Собственно, вопрос. Хочу объявить константу так, чтобы она размещалась в самом коде программы. В компилторе для 51 процессоров это делалось так:
char code MyText[7]= "Hellow";
В компиляторе для ARM это не прокатывает. Модификатор const тоже не помогает - константа все равно размещается в оперативке. А как разместить ее в коде аналогично вышеуказанному примеру?
Спасибо.
--------------------
Все врут (с) /M.D.House/
|
|
|
|
|
Jul 23 2009, 04:41
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(sonycman @ Jul 23 2009, 00:09)  Можно ещё добавить static: Код static const char text[] = "Привет"; Не надо мешать мух с котлетами. static не имеет никакого отношения к размешению кода во флеш, а только определяет область видимости переменной.
--------------------
Пасу котов...
|
|
|
|
|
Jul 23 2009, 08:10
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 13-01-06
Из: Санкт-Петербург
Пользователь №: 13 154

|
Вариант 1: Код #define AR_SIZE 500 char ar[AR_SIZE]; void main() { } Результат компиляции: Program Size: Code=1108 RO-data=16 RW-data=0 ZI-data=1256 Вариант 2: Код #define AR_SIZE 500 const char ar[AR_SIZE]; void main() { } Результат: Program Size: Code=1108 RO-data=16 RW-data=0 ZI-data=1256 Размер кода не изменился. Сдедовательно, константа разметилась в оперативке. Source Browser вообще в явном виде говорит, что переменная ar размещена в data. Может, надо выставить какие-то настройки в опциях компилятора, чтобы он константы располагал во флеше, а не в оперативке? Я не нашел что-то. Цитата Можно ещё добавить static: Цитата static не имеет никакого отношения к размешению кода во флеш, а только определяет область видимости переменной. Всем спасибо! Но все не правы. Статик не только определяет область видимости переменной. Это указывает компилятору разместить переменную в области статических данных. Эти переменные инициализируются один раз во время объявления, и их значения остаются действительными в течение времени жизни программы. Например, объявленная внутри функции переменная не потеряет своего последнего значения при следующем входе в данную функцию. Исходя из этой идеалогии, статические переменные не должны размещаться в коде.
--------------------
Все врут (с) /M.D.House/
|
|
|
|
|
Jul 23 2009, 08:41
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(Dreamer @ Jul 23 2009, 12:10)  Исходя из этой идеалогии, статические переменные не должны размещаться в коде. Вы сделали неправильные выводы. Ключевое слово const объявляет переменную константной, то есть не модифицируемой в run-time. Если вы объявили переменную как const и попытались ее модифицировать, компилятор выругается. попробуйте: Код const int slon = 1; void main(void) { slon = 2; } Компилятор выругается. При этом гарантий того, что const будет размещено именно во flash - нет. Нужно смотреть в документацию компилятора для уточнения деталей. Но, если вы не добавите const к объявлению - то компилятор будет размещать ее в RW области. Что же касается static - вы сдалали уточнение насчет объявления static внутри функии, такое же дополнение можно сделать по применению static внутри класса в С++, но static и const достаточно ортогональны, и могут применяться в любых сочетаниях. В том числе и: Код void main(void) { static const int slon = 1; }
--------------------
Пасу котов...
|
|
|
|
|
Jul 23 2009, 09:24
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 13-01-06
Из: Санкт-Петербург
Пользователь №: 13 154

|
Цитата Если вы объявили переменную как const и попытались ее модифицировать, компилятор выругается. Это и не подвергалось сомнению  У меня нет вопросов по самому языку С и С ++. Вопросы именно касаемо тонкостей их понимания компилятором Keil для ARM. Как вы сказали: Цитата При этом гарантий того, что const будет размещено именно во flash - нет. А мне нужна. Наверняка, это можно сделать явным образом так же, как и в Keil51. Цитата Нужно смотреть в документацию компилятора для уточнения деталей. Посмотрел. Немного потормозил. Снова посмотрел. Все еще не нашел  Покомпилировал пример с разными длинами массивов - 5, 50, и 5000. Параметр Code при комментировании/раскоментировании модификатора const меняется не всегда. Зато меняются параметры RO-data, RW-data и ZI-data. Где можно прочитать, что каждый из параметров означает? Цитата(aaarrr @ Jul 23 2009, 13:03)  Нет, просто ваша константа была выброшена за ненадобностью. Задействуйте ее где-нибудь и сравните результаты. Делаем. Вариант 1: Код #define AR_SIZE 500 const char ar[AR_SIZE]; void main() { if(ar[AR_SIZE-1]); } Цитата Program Size: Code=1108 RO-data=16 RW-data=0 ZI-data=1256 Вариант2: Код #define AR_SIZE 500 /*const*/ char ar[AR_SIZE]; void main() { if(ar[AR_SIZE-1]); } Цитата Program Size: Code=1108 RO-data=16 RW-data=0 ZI-data=1256
--------------------
Все врут (с) /M.D.House/
|
|
|
|
|
Jul 23 2009, 09:24
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(Dreamer @ Jul 23 2009, 13:18)  Зато меняются параметры RO-data, RW-data и ZI-data. Где можно прочитать, что каждый из параметров означает? Тоже в документации на компилятор-линкер, но и так понятно, что это ReadOnly data - сюда должны попадать переменные с ключевым словом const, а куда эта секция будет размещаться, задается в опциях линкера. Вам нужно ее разместить во flash. ReadWrite data - сюда попадают инициализированные переменные, объявленные как: int slon = 1; В startup эта область копируется из flash, в которое лежит копия область с начальными значениями. ZeroInit data - переменные, инициализированные нулем, то есть не имеющие начального значения, объявленные как: int slon;
--------------------
Пасу котов...
|
|
|
|
|
Jul 23 2009, 09:30
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 13-01-06
Из: Санкт-Петербург
Пользователь №: 13 154

|
Цитата ReadOnly data - сюда должны попадать переменные с ключевым словом const А в последнем примере не занеслось =( Цитата ZeroInit data - переменные, инициализированные нулем, то есть не имеющие начального значения, объявленные как: int slon; То есть глобальные и статические ? (Так как локальные инициализироваться вроде как не должны, или тут тоже что-то по-другому?)
--------------------
Все врут (с) /M.D.House/
|
|
|
|
|
Jul 23 2009, 09:31
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
У вас скорее всего работает оптимизатор, и выкидывает нафиг вашу переменную. Кроме того, для приведенного фрагмента кода слишком много, наверняка что-то еще компилируется. Сделайте ваши эксперименты в отдельном файле, порулите размером массива, чтобы понять, куда он у вас попадает. Добавьте иницализацию элементов массива, добавьте еще одно объявление массива с ключевым словом extern, чтобы компилятор думал, что эта переменная используется еще и внешними модулями.
--------------------
Пасу котов...
|
|
|
|
|
Jul 23 2009, 09:33
|

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

|
Цитата(Dreamer @ Jul 23 2009, 12:24)  Зато меняются параметры RO-data, RW-data и ZI-data. Где можно прочитать, что каждый из параметров означает? В документации. Опыт подсказывает, что это Read-Onle data, Read-Write data и Zero-Initialized data. Последние два - аналоги .data и .bss в GCC. Цитата(Dreamer @ Jul 23 2009, 12:24)  Код #define AR_SIZE 500 const char ar[AR_SIZE]; void main() { if(ar[AR_SIZE-1]); } Вы думаете от этого массив стал нужнее?  Результат if() не используется, оптимизатор (умница!) выкинул и if() и все, что внутри условия. Ибо то, что внутри условия тоже не имеет побочных эффектов. Попробуйте так: Код #define AR_SIZE 500 const char ar[AR_SIZE]; void main() { volatile int i = ar[AR_SIZE-1]; } Если не поможет, попробуйте volatile const char ar[AR_SIZE]; - это точно должно сработать.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 23 2009, 09:35
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
В IAR ваш код выглядит вот так: Код char ar[AR_SIZE];
Section sizes:
Function/Label Bytes -------------- ----- ar 500 main1 4
500 bytes in section .bss 4 bytes in section .text 4 bytes of CODE memory 500 bytes of DATA memory Код const char ar[AR_SIZE];
Section sizes: Function/Label Bytes -------------- ----- ar 500 main1 4 500 bytes in section .rodata 4 bytes in section .text 4 bytes of CODE memory 500 bytes of CONST memory
--------------------
Пасу котов...
|
|
|
|
|
Jul 23 2009, 09:52
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 13-01-06
Из: Санкт-Петербург
Пользователь №: 13 154

|
Цитата У вас скорее всего работает оптимизатор, и выкидывает нафиг вашу переменную. Да, вы правы. Усложнил код - параметр RO-data стал меняться на 500 байт. Код #define AR_SIZE 500 const char ar[AR_SIZE]={1}; char ar2[AR_SIZE]; void main() { int i; for(i=0;i<sizeof(ar2);i++) if(i&1) ar2[i]=ar[i];
} Цитата Кроме того, для приведенного фрагмента кода слишком много, наверняка что-то еще компилируется. Сделайте ваши эксперименты в отдельном файле, порулите размером массива, чтобы понять, куда он у вас попадает. Ага, при создании проекта средой добавлен достаточно большой файл startap.s. Если его не добавить, то "голый проект" с одним лишь моим файлом не компилируется. Цитата Если не поможет, попробуйте volatile const char ar[AR_SIZE]; - это точно должно сработать. Вот объявление массива как const volatile как раз оставляет RO-data= 0. Зато на 500 увеличивается RW-data.
Сообщение отредактировал Dreamer - Jul 23 2009, 09:54
--------------------
Все врут (с) /M.D.House/
|
|
|
|
|
Jul 23 2009, 15:18
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 13-01-06
Из: Санкт-Петербург
Пользователь №: 13 154

|
Цитата ReadOnly data - сюда должны попадать переменные с ключевым словом const, а куда эта секция будет размещаться, задается в опциях линкера. Вам нужно ее разместить во flash. Что-то не нашел, где и как это нужно сделать.
--------------------
Все врут (с) /M.D.House/
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|