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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> ARM, Keil, C/C++ - программирование, Как разместить константу во флеше?
Dreamer
сообщение Jul 22 2009, 14:51
Сообщение #1


Участник
*

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



Здравствуйте.

Перехожу на программирование ARM -микроконтроллеров, компилятор Keil.
До этого работал с аналогичным компилятором, но для 51 контроллеров.

Собственно, вопрос. Хочу объявить константу так, чтобы она размещалась в самом коде программы.
В компилторе для 51 процессоров это делалось так:

char code MyText[7]= "Hellow";

В компиляторе для ARM это не прокатывает.
Модификатор const тоже не помогает - константа все равно размещается в оперативке.
А как разместить ее в коде аналогично вышеуказанному примеру?

Спасибо.


--------------------
Все врут (с) /M.D.House/
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 22 2009, 15:06
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Код
const char text[6] = "Hello";


Замечательно размещается во флеш.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Jul 22 2009, 20:09
Сообщение #3


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Можно ещё добавить static:
Код
static const char text[] = "Привет";
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Jul 23 2009, 04:41
Сообщение #4


Знающий
****

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



Цитата(sonycman @ Jul 23 2009, 00:09) *
Можно ещё добавить static:
Код
static const char text[] = "Привет";

Не надо мешать мух с котлетами.
static не имеет никакого отношения к размешению кода во флеш, а только определяет область видимости переменной.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Dreamer
сообщение Jul 23 2009, 08:10
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 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/
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Jul 23 2009, 08:41
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 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;
}


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 23 2009, 09:03
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Dreamer @ Jul 23 2009, 12:10) *
Размер кода не изменился. Сдедовательно, константа разметилась в оперативке.

Нет, просто ваша константа была выброшена за ненадобностью. Задействуйте ее где-нибудь и сравните результаты.
Go to the top of the page
 
+Quote Post
Dreamer
сообщение Jul 23 2009, 09:24
Сообщение #8


Участник
*

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



Цитата
Если вы объявили переменную как const и попытались ее модифицировать, компилятор выругается.

Это и не подвергалось сомнению wink.gif
У меня нет вопросов по самому языку С и С ++.
Вопросы именно касаемо тонкостей их понимания компилятором Keil для ARM.

Как вы сказали:
Цитата
При этом гарантий того, что const будет размещено именно во flash - нет.


А мне нужна. Наверняка, это можно сделать явным образом так же, как и в Keil51.
Цитата
Нужно смотреть в документацию компилятора для уточнения деталей.

Посмотрел. Немного потормозил. Снова посмотрел. Все еще не нашел wink.gif

Покомпилировал пример с разными длинами массивов - 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/
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Jul 23 2009, 09:24
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 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;


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Dreamer
сообщение Jul 23 2009, 09:30
Сообщение #10


Участник
*

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



Цитата
ReadOnly data - сюда должны попадать переменные с ключевым словом const

А в последнем примере не занеслось =(

Цитата
ZeroInit data - переменные, инициализированные нулем, то есть не имеющие начального значения, объявленные как:
int slon;


То есть глобальные и статические ?
(Так как локальные инициализироваться вроде как не должны, или тут тоже что-то по-другому?)


--------------------
Все врут (с) /M.D.House/
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Jul 23 2009, 09:31
Сообщение #11


Знающий
****

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



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


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 23 2009, 09:33
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 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]);
}
Вы думаете от этого массив стал нужнее? smile.gif Результат 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)
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Jul 23 2009, 09:35
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 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


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Dreamer
сообщение Jul 23 2009, 09:52
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 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/
Go to the top of the page
 
+Quote Post
Dreamer
сообщение Jul 23 2009, 15:18
Сообщение #15


Участник
*

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



Цитата
ReadOnly data - сюда должны попадать переменные с ключевым словом const, а куда эта секция будет размещаться, задается в опциях линкера. Вам нужно ее разместить во flash.


Что-то не нашел, где и как это нужно сделать.


--------------------
Все врут (с) /M.D.House/
Go to the top of the page
 
+Quote Post

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

 


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


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