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

 
 
> AT91SAM7 + GCC(Yagarto), Как сделать костантный массив во FLASH.
bug_fix
сообщение Aug 17 2008, 16:47
Сообщение #1





Группа: Новичок
Сообщений: 8
Регистрация: 25-01-05
Пользователь №: 2 166



Требуется хранить некий массив данных во FLASH. как записывать данные на это место вроде как понятно. Через контроллер памяти. А вот как сказать компилятору, что это костантный массив данных лежащий в памяти программ (FLASH) пока чего то не раскопал. Может кто носом ткнет или ссылочкой побалует ? Поиск по форуму не дал результата.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 5)
aaarrr
сообщение Aug 17 2008, 16:51
Сообщение #2


Гуру
******

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



Через указатель можно сделать, типа:
Код
int *array = (int *)(AT91C_IFLASH + ADDR);
Go to the top of the page
 
+Quote Post
bug_fix
сообщение Aug 17 2008, 17:57
Сообщение #3





Группа: Новичок
Сообщений: 8
Регистрация: 25-01-05
Пользователь №: 2 166



Цитата(aaarrr @ Aug 17 2008, 23:51) *
Через указатель можно сделать, типа:
Код
int *array = (int *)(AT91C_IFLASH + ADDR);


А вроде гдето отковырял , что можно

Код
const int arr[] = {0x023,0x056,...,0x098};


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

В предложеном вами случае получается, что нужно будет руками задавать адрес массива. и размещать его в памяти через скрипт линкера. Как линкеру сказать , что некая бинарная сущность должно лежать по адресу выровненому на границу 256 чтоб не задавать все руками ?
Go to the top of the page
 
+Quote Post
Norton
сообщение Aug 18 2008, 13:17
Сообщение #4





Группа: Новичок
Сообщений: 12
Регистрация: 7-04-08
Из: Пермь
Пользователь №: 36 538



я делал примерно так для сохраниния настроек
Код
unsigned long *opt1            = (unsigned long *)        SETTINGS_OFFSET+SA_OPT1;
unsigned long *opt2            = (unsigned long *)        SETTINGS_OFFSET+SA_OPT2;

где SETTINGS_OFFSET - адрес начала страницы, а SA_OPT - смещение внутри страницы нашей настройки, и также писать процедуру перезаписи всего сегмента

а чтобы компилятор туда не помещал ничего другого, прописать в скрипте линкера
Код
.=0x00100000+255K;
.settings :
{
    *(.settings .settings.*);
} >flash =0x00


можно использовать
Код
.=align(256);

которая выравнивает точку в памяти кратно указанному числу байт

также можете поэксперементировать с объявлению переменной с привязкой к сегменту
Код
__attribute__ ((section (".settings"))) unsigned long int Buf[64];

но у меня дружбы с ними не получилось, то регион кончался, то линкер ошибку давал (а рассказывать детально о своих ошибках не хотел)
Go to the top of the page
 
+Quote Post
bug_fix
сообщение Aug 18 2008, 16:41
Сообщение #5





Группа: Новичок
Сообщений: 8
Регистрация: 25-01-05
Пользователь №: 2 166



Спасибки буду ковырять.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 20 2008, 05:29
Сообщение #6


Гуру
******

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



Цитата(bug_fix @ Aug 17 2008, 19:47) *
А вот как сказать компилятору, что это костантный массив данных лежащий в памяти программ (FLASH) пока чего то не раскопал.
Все глобальные переменные, описанные с квалификатором const по умолчанию складываются в секцию rodata. Но поскольку вы собираетесь переписывать ваши данные и не хотите случайно затереть остальные константы, то вам надо поместить ваши данные в отдельную секцию и в скрипте линкера добать эту секцию с выравниванием на границе сектора. Примерно так:
Код
.c:
#define MYFLASH __attribute__((section(".myflash")))

MYFLASH uint8_t const array[256];

.ld:

  .text :
  {
    ..........
  } > ROM

  .data :
  {
     .........
  } > RAM AT > ROM

   ..........

  .myflash :
  {
    . = ALIGN(256);
    *(.myflash)
    . = ALIGN(256);

  } > ROM
Здесь начальные значения констант (.data) размещаются вслед за выходной секцией .text, поэтому описание выходной секции .myflash я поместил после .data, чтобы эта секция располагалась последней. Как вариант - можно описать отдельный регион памяти для этих констант и линковать .myflash в этот регион:
Код
/* memory layout */
MEMORY
{
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 - 512    /* 64K - MYFLASH*/
  MYFLASH (rx) : ORIGIN = 0x000010000 - 512, LENGTH = 512
  RAM (rw) : ORIGIN = 0x00200000, LENGTH = 0x00004000
}

   ..........

  .myflash :
  {
    *(.myflash)
  } >MYFLASH


--------------------
На любой вопрос даю любой ответ
"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

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 11:00
Рейтинг@Mail.ru


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