Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Разместить массив во Flash STM32
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
bingo
Здравствуйте
Есть большой набор не изменяемых массивов байт (целевые команды). Размещать из в RAM- не рационально.
Подскажите пожалуйста как объявить в IAR ARM С инициализированный массив , так чтобы он был расположен во FLASH, а не в RAM. Естественно, массив только для чтения.

Ранее для IAR AVR я делал так:
__flash char* num1 = "58749455350";

Для IAR ARM v6.21 это не проходит.
Но и такие объявления не получаются:
uint8_t Cmd [] = {3,2,1} @ "FLASH";

SergeyL
Так должно получиться
static const uint8_t Cmd [] = {3,2,1};
bingo
Цитата(SergeyL @ May 17 2012, 05:46) *
Так должно получиться
static const uint8_t Cmd [] = {3,2,1};


Неее!
Модификатор static не для этого!
static переменная все равно будет расположена в RAM, но только инициализироваться до main() и др.

Пробовал модификаторы @ и pragma, но пока не получается :-(

Неужели никто не знает как разместить массив в ROM (FLASH)?
PheeL
Цитата(bingo @ May 17 2012, 15:30) *
Неее!
Модификатор static не для этого!

Ключевое слово здесь не static, а const.
haker_fox
QUOTE (PheeL @ May 17 2012, 19:55) *
Ключевое слово здесь не static, а const.

const, если мне не изменяет память, также может быть в ОЗУ размещен. Пример - x86. При этом компилятор запрещает изменение этой константы на этапе компиляции, и разместит ее в секции .data.

Я думаю, что необходимо обратиться к доке на компилятор, и внимательно посмотреть, что там и к чему...
PheeL
Цитата(haker_fox @ May 17 2012, 19:05) *
const, если мне не изменяет память, также может быть в ОЗУ размещен. Пример - x86. При этом компилятор запрещает изменение этой константы на этапе компиляции, и разместит ее в секции .data.

Может. Даже на многих DSP процессорах(например, TMS320C5509A) это так sm.gif Потому что там нет FLASH памяти, с которой напрямую может работать ядро(маппируется в его адресное пространство + аппаратный кэш выборки команд для того, чтобы память успевала за тактовой ядра). Поэтому что остаётся делать линкеру с таким условием? Размещать в ОЗУ. А в тех контроллерах где есть такая возможность(есть встроенная FLASH), данное ключевое слово попросит линкер разместить переменную именно в ней. Вопрос был про STM32(да даже если про LPC21xx-24xx). Там есть FLASH на борту. Так что всё верно.
demiurg_spb
Цитата(PheeL @ May 17 2012, 14:55) *
Ключевое слово здесь не static, а const.

+1
Этого должно хватать для того чтобы данные разместились во флеше, при условии что они глобальные (вне функции обявлены).
bingo
Цитата(demiurg_spb @ May 17 2012, 20:51) *
+1
Этого должно хватать для того чтобы данные разместились во флеше, при условии что они глобальные (вне функции обявлены).


К сожелению и это не правильно. crying.gif
Вот цитата из документации ("EWARM Development Guide" с.288):

"If you declare a volatile object const, it will be write-protected but it will still be stored in RAM memory as the C standard specifies.
To store the object in read-only memory instead, but still make it possible to access it as a const volatile object, define the variable like this:
const volatile int x @ "FLASH";
"

Да, так работает.
Но мне нужен инициализированный массив (типа Cmd [] = {3,2,1} ).
А это уже не компилируется

Кстати, и без volatile - тоже массив будет в RAM!
А точнее, в RAM и еще код для его создания в ROM (т.к.начальный код для создания структуры массива в RAM все равно работает из FLASH). Т.е. не рационально и избыточно.

Возможность разместить неизменяемые большие массивы в ROM-FLASH (которого существенно больше чем RAM) очень полезна.
_Артём_
Цитата(bingo @ May 18 2012, 04:01) *
Вот цитата из документации ("EWARM Development Guide" с.288):

"If you declare a volatile object const, it will be write-protected but it will still be stored in RAM memory as the C standard specifies.
To store the object in read-only memory instead, but still make it possible to access it as a const volatile object, define the variable like this:
const volatile int x @ "FLASH";
"

Да, так работает.
Но мне нужен инициализированный массив (типа Cmd [] = {3,2,1} ).
А это уже не компилируется

Может где-то не там смотрите... Причина может быть в настройках проекта или ещё в чём-нибудь .
Создал массив по адресу(__root - запрет сооптимизировать):
Код
__root const unsigned char Test[3]@0x1005={
    1,2,3
};


Нажмите для просмотра прикрепленного файла

Массив по адресу 0x1005 - что есть FLASH.
bingo
Цитата(_Артём_ @ May 18 2012, 04:41) *
Может где-то не там смотрите... Причина может быть в настройках проекта или ещё в чём-нибудь .
Создал массив по адресу(__root - запрет сооптимизировать):
Код
__root const unsigned char Test[3]@0x1005={
    1,2,3
};


Нажмите для просмотра прикрепленного файла

Массив по адресу 0x1005 - что есть FLASH.


Верно, но это (@ 0x1005) вариант использования когда нужно разместить по конкретному location
А есть еще потребность, чтобы было просто во FLASH (неважно где). Для этого используется нотация
.... @ "FLASH";
Она как раз и не работает с инициализированным при объявлении массивом

В проекте я отключил оптимизацию (none).

==========================================================================
Всем спасибо!
Вот пример правильной записи :-)

uint8_t HCI_Reset[] @ "FLASH" = {3,2,1};
Dog Pawlowa
Цитата(bingo @ May 18 2012, 04:56) *
...
А есть еще потребность, чтобы было просто во FLASH (неважно где). Для этого используется нотация
.... @ "FLASH";
Она как раз и не работает с инициализированным при объявлении массивом

Это у Вас не работает! wink.gif
У меня почему-то работает.
Нажмите для просмотра прикрепленного файла
_Артём_
Цитата(bingo @ May 18 2012, 04:56) *
Верно, но это (@ 0x1005) вариант использования когда нужно разместить по конкретному location
А есть еще потребность, чтобы было просто во FLASH (неважно где)


Верно. Есть такая потребность:
Код
__root const unsigned char Test[3]={
    1,2,3
    
};


Нажмите для просмотра прикрепленного файла


Цитата(bingo @ May 18 2012, 04:56) *
В проекте я отключил оптимизацию (none).

А ведь пригодится...
Оптимизация none/high.

bingo
Цитата(Dog Pawlowa @ May 18 2012, 05:24) *
Это у Вас не работает! wink.gif
У меня почему-то работает.
Нажмите для просмотра прикрепленного файла


Я же перед Вашим постом написал, что все уже OK
Просто, вместо правильного синтаксиса:
uint8_t HCI_Reset[] @ "FLASH" = {3,2,1};

Я бодался с неочевидной ошибкой (из документации совешенно не видно, пример я привел выше):
uint8_t HCI_Reset[] = {3,2,1} @ "FLASH" ;

rolleyes.gif

Цитата(_Артём_ @ May 18 2012, 05:28) *
Верно. Есть такая потребность:
Код
__root const unsigned char Test[3]={
    1,2,3
    
};


Нажмите для просмотра прикрепленного файла



А ведь пригодится...
Оптимизация none/high.


Конечно же позже я ее включю rolleyes.gif
Дайте только все отладить.
Dog Pawlowa
Цитата(bingo @ May 18 2012, 07:57) *
Я же перед Вашим постом написал, что все уже OK
Просто, вместо правильного синтаксиса:
uint8_t HCI_Reset[] @ "FLASH" = {3,2,1};

Вы не поняли.
У меня никакого "FLASH" нет, это видно на картинке, и все работает правильно.
Что наводит на мысли, где же Вы свою переменную объявляете.
PheeL
Цитата(Dog Pawlowa @ May 18 2012, 10:43) *
Что наводит на мысли, где же Вы свою переменную объявляете.

Прошу прощения за буквоедство, но раз он переменную пытается чем-то уже инициализировать, то это определение )
Кстати, про @ "FLASH" я не знал. Это случайно не какая-нибудь новомодная "фишка" от IAR'а? Они там постоянно что-то меняют ( Что ещё раз подтверждает тезис о том, что нужно всегда читать документацию (
bingo
Цитата(Dog Pawlowa @ May 18 2012, 10:43) *
Вы не поняли.
У меня никакого "FLASH" нет, это видно на картинке, и все работает правильно.
Что наводит на мысли, где же Вы свою переменную объявляете.


Хмм.... Вы правы!
Как ни странно, но массив оказался снова в RAM!!!
Хотя это, на мой взгляд, противоречит документации .

Так какое решение Вы видите?
Использовать принудительное указание места размещения, типа "... @ 0x80...005=.." ?
Это не очень удобно.
Использование const , как у Вас? Но про это явно написано в документации (я ее цитировал ранее).


В понедельник буду снова пытать программу/плату.
Dog Pawlowa
Цитата(bingo @ May 18 2012, 13:40) *
Так какое решение Вы видите?

Я вижу единственный выход из тупика - покажите, где определена переменная.
Вас уже три раза подталкивали обратить на это внимание.

При чём тут фрагмент документации про volatile, мне непонятно.
derstik
Цитата(bingo @ May 17 2012, 08:16) *
Здравствуйте
Есть большой набор не изменяемых массивов байт (целевые команды). Размещать из в RAM- не рационально.
Подскажите пожалуйста как объявить в IAR ARM С инициализированный массив , так чтобы он был расположен во FLASH, а не в RAM. Естественно, массив только для чтения.

Ранее для IAR AVR я делал так:
__flash char* num1 = "58749455350";

Для IAR ARM v6.21 это не проходит.
Но и такие объявления не получаются:
uint8_t Cmd [] = {3,2,1} @ "FLASH";


В IAR есть #pragma location. Почитайте про нее. С её помощью я размещал во флэш серийный номер устройства
ViKo
Я поддерживаю сообщение №2. Нужно описывать в виде static const, и все будет хорошо.
muravei
Цитата(ViKo @ May 24 2012, 09:20) *
Нужно описывать в виде static const, и все будет хорошо.

Сделал так в Кейл, получилось ,надеюсь во флеш. Теперь проблема , как туда лазать по указателю?
Кажется, какие-то идеологические противоречия.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.