Размещение таблиц в памяти

Как решить такую задачу
Есть следующий кусок кода

static char A[10];
static char B[12];
static char C[11]
static char D[5];
static char *R[]={A,B,C,D};

main ()
{
//Здесь заполняем данными, по ходу программы
R[0][0]=1;
R[1][3]=2;
}

Все замечательно работает и бегает, но смущает что массив указателей R расположен RAM.Как его разместит в ROM

Комментарии (32)

RSS свернуть / развернуть
Для вопросов есть форум.

А если по делу, то в стандарте C это делает модификатор const. В GCC работает.
+4
И как вы массиву const сделаете присвоение?
0

const uint8_t array[2][2][2]=
{
    { {1,2},{3,4} },
    { {5,6},{7,8} }
}

или

const uint8_t array[2][2][2]= { { {1,2},{3,4} }, { {5,6},{7,8} } }
0
Вы не внимательно прочитали пост. присвоение массиву идет в процессе выполнения программы, а не при инициализации
0
Тогда массив не может быть в ROM.
0
Массив указателей не меняется и линковщик знает все адреса зарание. Что мешает ему разместить массив указателей в ROM? __atribute__ с указанием секции тоже не дает результата
0
Или программа должна переписывать флеш микроконтроллера, но вам такое пока рано.
0

char A[6]="";
char B[5]="";
char C[9]="";
char D[7]="";
const char *R[4]={A,B,C,D};	 
int main(void)
{
R[0][0]=1;
R[1][3]=3;	
}

скомпилируйте, проверьте

Build target 'Target 1'
compiling main.c…
main.c(13): error: #137: expression must be a modifiable lvalue
R[0][0]=1;
main.c(14): error: #137: expression must be a modifiable lvalue
R[1][3]=3;
main.c: 0 warnings, 2 errors
".\Objects\crc.axf" — 2 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed: 00:00:01
0
Вы упоролись?

const char A[] = "123456";
const char B[] = "123456";
const char C[] = "123456";
const char D[] = "123456";
const char * const R[4] = {A,B,C,D};

А присвоение в main не возможно в принципе, если данные в ROM.
0
Можно так:


static char A[10];
static char B[12];
static char C[11]
static char D[5];
static char const *R[]={A,B,C,D};

Массив R будет конастантный.
0
в общем нашел решение, хотя Вы утверждаете, что такое не возможно

char A[6]="";
char B[5]="";
char C[9]="";
char D[7]="";
char *R[4] __attribute__((at(0x8000f00))) ={A,B,C,D};	 
int main(void)
{

R[0][0]=1;
R[1][3]=3;	
}

листинг показывает, что данные легли куда надо

    R                                        0x08000f00   Data          16  main.o(.ARM.__AT_0x08000F00)
    A                                        0x20000000   Data           6  main.o(.data)
    B                                        0x20000006   Data           5  main.o(.data)
    D                                        0x2000000b   Data           7  main.o(.data)
    C                                        0x20000014   Data           9  main.o(.bss)

Не удобство метода — надо считать самому куда что положит. Как линкеру обьяснить, чтоб сам распределял память?
0
Я чет так и не понял чего ты хочешь. Изначально вопрос стоял: массив констант в РОМ, хочу изменять в рантайме через указатели в РОМ. Как уже заметили, такое напрямую не сделать. Сейчас же ты создал массивы в ОЗУ, а указатели на них разместил в РОМ. Такое уже выполнимо вроде.
0
Хотя и не понятно зачем.
0
Массив указателей на массив строк хочу в ROM, а вот сами массивы строк — в памяти, линкер сам не может этого сделать, пришлось явно указывать адрес в памяти. теперь хочу заставить его делать это автоматом ( таких массивов много) и нет гарантии, что я его размещу в правильном месте.выделять секцию, тоже нехорошо, Будут пропуски, и проблемы с последующей правкой кода, придется каждый раз все пересчитывать
0
попробуйте так как предложил товарищ m0xf
0
не работает
compiling main.c…
main.c(14): error: #137: expression must be a modifiable lvalue
R[0][0]=1;
main.c(15): error: #137: expression must be a modifiable lvalue
R[1][3]=3;
main.c: 0 warnings, 2 errors
Наличие слова const в независимости от того где его написали — подразумевает запрет записи
0
при чем специфично для кейла, я так понял.
0
static char A[10];
static char B[12];
static char C[11];
static char D[5];
static char * const R[]={A,B,C,D};
пробовали? По-моему это именно то, что вы ищете
0
const char *R[4]={A,B,C,D};

Это тип – массив из четырех элементов, каждый из которых указатель на const char

Поэтому и ошибка, у вас не массив константа, а данные, которые хранятся по указателю в массиве.

char const *R[4]={A,B,C,D};


А это — массив из четырех константных указателей, на char (указатели константа, но сами данные вы можете менять)

Подозреваю, что именно это вы хотите получить. Я не знаю какие особенности у Кеил, но GCC массив R поместит в .rodata

00000000 g     O .bss   00000006 A
00000008 g     O .bss   00000005 B
00000010 g     O .bss   00000009 C
0000001c g     O .bss   00000007 D
00000000 g     O .rodata        00000010 R
00000000 g     F .text  00000040 main
0
не вижу этого в Вашем листинге. какой абсолютный адрес?

вот как Keil дает листинг
Region$$Table$$Base 0x08000254 Number 0 anon$$obj.o(Region$$Table)
Region$$Table$$Limit 0x08000274 Number 0 anon$$obj.o(Region$$Table)
R 0x08000f00 Data 16 main.o(.ARM.__AT_0x08000F00)
A 0x20000000 Data 6 main.o(.data)
B 0x20000006 Data 5 main.o(.data)
D 0x2000000b Data 7 main.o(.data)
C 0x20000014 Data 9 main.o(.bss)
— тут видно, что массив R лег во флеш, а A,B,C,D в Ram
0
не вижу этого в Вашем листинге. какой абсолютный адрес?

Вот с абсолютными адресами, (для AT91SAM7S256, то, что было под рукой :)

ROM

00100270 <R>:
  100270:	01ec 0020 01f4 0020 01fc 0020 0208 0020     .. ... ... ... .

RAM

002001ec <A>:
	...

002001f4 <B>:
	...

002001fc <C>:
	...

00200208 <D>:
	...

MEMORY
{
  CODE (rx)  : ORIGIN = 0x00100000, LENGTH = 256k
  DATA (rwx) : ORIGIN = 0x00200000, LENGTH = 64k
}
0
значит глюк кейла, он ни в какую не хочет
0
хотя нет,

static   char  * const R[]={A,B,C,D};

вот так все работает.
0
Странно, оно и без static должно работать …
0
Да работает.закрываем тему. Кучу памяти сэкономил
0
кучу? О_о
0
const char *R[4]={A,B,C,D};
char const *R[4]={A,B,C,D};
это ж одно и то же
+2
Упс, только сейчас заметил опечатку, имелось ввиду
char * const R[]={A,B,C,D};
А это — массив из четырех константных указателей, на char ...
0
ой, вы уже исправились
0
const char *R[4]={A,B,C,D};
и
char const *R[4]={A,B,C,D};
абсолютно идентичные объявления.
Правильно вот так:
static char * const R[]={A,B,C,D};
+1
И в ARMCC всё работает
-1
Наказать=) Беспощадно!!!
+2
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.