Перейти к содержанию
    

Keil 5.35 ARMC 6.16 размещение данных в rom

Приветствую коллеги.

Элементарная вроде задача - размещать некоторых структур/данных в rom.

Для Keil не могу найти решения. В IAR для этого есть атрибут __flash.

В Keil вроде как для этой цели можно было бы приспособить  атрибуты

__attribute__((section(".rodata")))

Однако при попытке собрать проект где идут друг за другом объявления типа

const int A __attribute__((section(".rodata"))) = 1;

const int B __attribute__((section(".rodata"))) = 2;

Выдает ошибку

../File.c(163): error: 'B' causes a section type conflict with 'A'

Введение своей секции в.sct файл картины не меняет:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
   *.o(romdata)
  }
  
  ;Sec_Const 0x08001FFC 0x000004 {
  ;  Const.o(SecConst)
  ;}
  
  RW_IRAM1 0x20000000 0x00014000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

Как объяснить компилятору что располагать в секции данный можно последовательно?

С директивой #pragma вообще ничего подходящего не нашел...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, dlsh said:

Элементарная вроде задача - размещать некоторых структур/данных в rom.

А чем не годится простой "const" ?

Или вам нужно это размещать не просто во flash, а именно в ОПРЕДЕЛЕННОМ фиксированном месте? Но для этого не требуется создавать отдельную секцию.

Да и ваш sct неправильный - там пересекаются секции, это видно по адресам.

У keil вроде как вполне внятная документация. Первый же запрос в гугле дает вполне исчерпывающий ответ: https://www.keil.com/support/man/docs/armclang_intro/armclang_intro_pge1362066003118.htm

Вот тут еще немного других нюансов: https://www.keil.com/support/man/docs/armlink/armlink_pge1362066000009.htm

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, dlsh said:

В IAR для этого есть атрибут __flash.

Но она не используется при работе с ядром ARM. Эта фича нужна была для тех же AVR, где флешка висела в отдельном адресном пространстве, чтобы линкер точно знал, что константу нужно уложить по адресу 0x00000077 Flash, а не по адресу 0x00000077 ОЗУ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

const - размещает объекты в секции Data. const - не указывает где размещать, а определяет свойство неизменяемости.

У keil дано решение для одного объекта, как только появляется второй с указанием размещения в той же секции то возникает конфликт размещения с ошибкой.

В sct Sec_Const закоментирован.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, dlsh said:

const - размещает объекты в секции Data. const - не указывает где размещать, а определяет свойство неизменяемости.

Все эти рассуждения, конечно, хороши, но больше похожи на софистику)

Чем обычный const Вас не устраивает, как уже спросили выше? Не знаю, чем сильно Кейл отличается от IAR, но в IAR достаточно указать перед созданием объекта const и он будет находится в памяти flash. При условии, что это возможно, конечно. Например, если объект может быть создан только в run-time, то уже переместится в ОЗУ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, haker_fox said:

но в IAR достаточно указать перед созданием объекта const и он будет находится в памяти flash.

У keil аналогично. Причем в любом его компиляторе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для общего ознакомления весьма интересна данная статья от нашего коллеги.

Just now, Forger said:

У keil аналогично. Причем в любом его компиляторе.

Отлично! Кейл использовал очень давно. И подумалось, вдруг действительно есть какие-то нюансы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, dlsh said:

У keil дано решение для одного объекта, как только появляется второй с указанием размещения в той же секции то возникает конфликт размещения с ошибкой.

Какая ошибка? Вариантов много: перекрытие областей размещения, недостаточный размер секции, сама секция пересекается с другой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Верно, для простых случаев компилятор размещает данные в flash. Для случаев чуть сложнее все уходит в RAM.

Например для IAR

int A_var[10];

#pragma location=0x80000b0
const __root int *pA_var[100] = { &A_var[0], &A_var[2] };
const __root int *pB_var[100] = { &A_var[1], &A_var[3] };

int main()
{
  int B = *pA_var[0];
  while(1){
    B += *pB_var[B % 100];
  }
  
  return 0;
}

Имеем размещение

..........
main                     0x800'02a1   0x24  Code  Gb  main.o [1]
pA_var                   0x800'00b0  0x190  Data  Gb  main.o [1]
pB_var                  0x2000'0000  0x190  Data  Gb  main.o [1]
.............

т.е. т.к. для pA_var явно указана flash то он там и лежит, а для pB_var этого явно не указано и компилятор размещает этот объект в Data.

C атрибутом __flash согласен не совсем корректно, но он очень хорошо демонстрирует то что требуется. Т.е. нужно аналогия __flash для ARM в Keil чтобы можно помечать объекты которые нужно разместить в 

test.zip

23 минуты назад, Forger сказал:

Какая ошибка? Вариантов много: перекрытие областей размещения, недостаточный размер секции, сама секция пересекается с другой

Так указал же выхлоп компилятора

../File.c(163): error: 'B' causes a section type conflict with 'A'

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, dlsh said:

Так указал же выхлоп компилятора

Повторил ваш пример:

const int A __attribute__((section(".rodata"))) = 1;
const int B __attribute__((section(".rodata"))) = 2;

Никаких ошибок нет. Компилятор тот же: 6.16.

В данном примере __attribute__((section(".rodata"))) вообще не нужно. Достаточно const.

 

Короче, объясните конкретнее задачу, так проще помочь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Повторил Ваш пример в IAR

image.png.2a1ecc8c9368a5cadead61d60b4a8c7b.png

Выхлоп map

image.thumb.png.c28cae83d8e16d0018466f826c151047.png

Вы же объявили неконстантые указатели на константные данные. При этом сами указатели могут менятся. У них квалификатор const не стоит.

Если сделать так

image.png.8361fb2dd898e05711e9559dfa3dd650.png

То всё кладётся во флешку.

image.thumb.png.504fcdef842ae481aaa4a01b5d0be884.png

static можно убрать. Это я экспериментировал.

Компилятор: IAR 9.10, оптимизация выключена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

32 минуты назад, Forger сказал:

.....

Короче, объясните конкретнее задачу, так проще помочь.

Прикрепил упрощенный проект того что у меня сейчас в работе.

#define __rom const __attribute__((section(".rxdata")))

typedef struct _B_var_t{
	int *value;
}B_var_t;

int A_var[10];

__rom int *pA_var[100]  = { &A_var[0], &A_var[2] };
__rom B_var_t pB_var[100]  = { {&A_var[1]}, {&A_var[3]} };

int main()
{
  int B = *pA_var[0];
  while(1){
    B += *pB_var[B % 100].value;
  }
  
  return 0;
}

Получаю ошибку

Скрытый текст

Build started: Project: test
*** Using Compiler 'V6.16', folder: 'C:\ProgramFiles\Keil_v5\ARM\ARMCLANG\Bin'
Build target 'Test'
main.c(10): error: 'pB_var' causes a section type conflict with 'pA_var'
__rom B_var_t pB_var[100]  = { {&A_var[1]}, {&A_var[3]} };
              ^
main.c(9): note: declared here
__rom int *pA_var[100]  = { &A_var[0], &A_var[2] };
           ^
1 error generated.
compiling main.c...
".\Objects\test.axf" - 1 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed:  00:00:00

Что интересно... если убрать структуру и сделать по аналогии тому примеру что в IAR то все работает, и оба указателя уходят во flash.... Но если добавит структуру то получаю ошибку.

24 минуты назад, haker_fox сказал:

Повторил Ваш пример в IAR

.....

То всё кладётся во флешку.

....

Ясно. 

test.KEIL.zip

Эхх перемудрил...

Все верно товарищи,  достаточно просто указать const и компилятор убирает данные в flash... Ни какого атрибута не нужно. )))

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, dlsh said:

Прикрепил упрощенный проект

Ничего не понял. Объясните словами: что и где нужно размещать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, dlsh сказал:

Верно, для простых случаев компилятор размещает данные в flash. Для случаев чуть сложнее все уходит в RAM.

Например для IAR


#pragma location=0x80000b0
const __root int *pA_var[100] = { &A_var[0], &A_var[2] };
const __root int *pB_var[100] = { &A_var[1], &A_var[3] };

Имеем размещение


..........
main                     0x800'02a1   0x24  Code  Gb  main.o [1]
pA_var                   0x800'00b0  0x190  Data  Gb  main.o [1]
pB_var                  0x2000'0000  0x190  Data  Gb  main.o [1]
.............

т.е. т.к. для pA_var явно указана flash то он там и лежит, а для pB_var этого явно не указано и компилятор размещает этот объект в Data.

Не понятно - на кой Вы пытаетесь засунуть переменные во флешь? :wacko2:

Компилятор делает правильно, зачем Вы пытаетесь поставить программу раком - непонятно....

 

Во флешь размещают константы. Переменные размещают в ОЗУ (кроме редких особых случаев).

Открываем учебник по си:

char const * zpx[] = {"1", "2"}; - массив-переменная; разместится в ОЗУ

char * const zpy[] = {"1", "2", "3"}; - массив-константа; разместится во флешь

Никаких __rom, __flash, #pragma location=0x80000b0 и пр. лабуды в общем случае компилятору указывать не надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, jcxz сказал:

....

Никаких __rom, __flash, #pragma location=0x80000b0 и пр. лабуды в общем случае компилятору указывать не надо.

Понял, все верно.

1 час назад, Forger сказал:

Ничего не понял. Объясните словами: что и где нужно размещать?

Нужно было чтобы оба объекта pB_var и pB_var компоновщик разместил во flash. И да, все верно - добавление квалификатор const решает задачу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...