Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

IAR stm32f103, инициализация стека в середине ОЗУ

Пн май 13, 2019 09:14:13

Начал копаться в файле линкера, и тут заметил что вершина стека где-то в середине ОЗУ устанавливается :shock:
Причем полистал память под отладкой и в Symbolic memory вижу что есть примеренные выше стека и ниже стека :shock:

Изображение

Файл ликера почти стандартный, да и стандартный пробовал та же фигня.
Код:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__   = 0x0803FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x2000BFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_heap__   = 0x1000;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

place at address mem:__ICFEDIT_region_ROM_end__-4095 { readonly section .Flashstart};

place at address mem:__ICFEDIT_region_ROM_end__-1023 { readonly section .default};

в map файле вижу секция CSTACK так и размешается по адресу 0x20002c38
Код:
"A1":  place at 0x08000000 { ro section .intvec };
"P1":  place in [from 0x08000000 to 0x0803ffff] { ro };
"P2":  place in [from 0x20000000 to 0x2000bfff] { rw, block CSTACK, block HEAP };
...................
"P2", part 2 of 3:                          0x1000
  CSTACK                       0x20001c38   0x1000  <Block>
    CSTACK            uninit   0x20001c38   0x1000  <Block tail>
                             - 0x20002c38   0x1000


Как сделать что бы было по нормальному и стек был в конце ОЗУ ?
Вложения
CSTack.png
(123.9 KiB) Скачиваний: 189
CSTack.png
(123.9 KiB) Скачиваний: 400

Re: IAR stm32f103, инициализация стека в середине ОЗУ

Пн май 13, 2019 15:20:43

В чём проблема то? Он и так почти в конце, дальше только куча. Разместить где хочешь можно указав в скрипте линкера конкретный адрес расположения. Или вообще в стартапе любой ручками записать в SP, не забыть только эту область у линкера забрать.

PS: Да и какая разница где он? Главное чтобы размера хватало. Ты же не собираешься его превышать, правда? Или таки да?

PPS: А вообще читать доки это рулез.
The place at directive places sections and blocks either at a specific address or, at the
beginning or the end of a region.

Re: IAR stm32f103, инициализация стека в середине ОЗУ

Вт май 14, 2019 03:48:56

"Он и так почти в конце, дальше только куча"
Увы увы, там дальше ещё под 100 перемененных идет. Это я там тестовый массив(mass) на >1000 байт объявил, а после него другие примеренные продолжаются.
place in RAM_region { readwrite, last block CSTACK, block HEAP };

Вот таким образом получилось разместить его в конце всех переменных.
Кстати как насчет того что бы его разместить в самом начале, и ловить HardFault при перевыполнении стека ?

Re: IAR stm32f103, инициализация стека в середине ОЗУ

Вт май 14, 2019 05:58:50

Кстати как насчет того что бы его разместить в самом начале, и ловить HardFault при перевыполнении стека ?
Эта теме всплывает на форумах с завидной регулярностью. Я с первого сообщения знал, что к этому придёт. Но никто, почему-то, не может объяснить зачем устраивать HardFault вместо правильного задания размера стека. И ещё, свой инструмент знать надо. Почитай раздел "Stack usage analysis" в документации - пользы будет больше.
Ответить