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

 
 
> Инициализация стека в Cortex M3
Yogen
сообщение Dec 6 2016, 04:37
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 16-11-09
Из: Омск
Пользователь №: 53 657



Здравствуйте.

Написал приложение с собственным загрузчиком на ADuCM360. Работает, но до последнего момента был неясен вопрос инициализации вершины стека при переходе с загрузчика на основное приложение. Понятно, что при старте загрузчика по ресету стек инициализируется автоматически по указателю на нулевом адресе. Но при переходе на основное приложение этого не происходит и его нужно инициализировать вручную, например так:

Код
__set_MSP(*(__IO uint32_t*) FLASH_APPLICATION_ADDR); // Новая вершина стека.

Насколько успел разобраться, указатель стека по адресу начала основного приложения инициализируется компилятором в соответствии с директивами файла конфигурации *icf линкера. В файлах *icf из примеров написано:

Код
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

но при таком размещении стек гуляет по памяти в зависимости от размера пользовательских данных в RAM и размера самого стека.
Однако здесь же на форуме читал что народ ставит вершину стека в конец RAM, поэтому переписал так:

Код
place at address mem: (__ICFEDIT_region_RAM_end__ - __ICFEDIT_size_cstack__)  { block CSTACK};
place in RAM_region   { readwrite, block HEAP };


Всё ли правильно сделал и какие могут быть подводные камни?
Где посмотреть пример файла конфигурации с привязкой вершины стека к концу RAM скажем для STM32?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 8)
Kabdim
сообщение Dec 6 2016, 07:14
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



msp должен быть устновлен там куда указывает указатель в начале прошивке, всё остальное для бутлоадера совершенно не важно. Компилятор/программист может сделать стэка где ему угодно, хоть в конце, хоть в начале.
Лично мне исходя из реализй m0 не нравится стек вначале т.к. в m0 нет vtor и таблица прерывний размещается в начале ram - соседство со стеком будет явно безрадостным в случае форсмажоров.
Go to the top of the page
 
+Quote Post
Yogen
сообщение Dec 6 2016, 07:38
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 16-11-09
Из: Омск
Пользователь №: 53 657



Цитата(Kabdim @ Dec 6 2016, 11:14) *
msp должен быть устновлен там куда указывает указатель в начале прошивке, всё остальное для бутлоадера совершенно не важно.

Так и есть. Но я почему начал копать?! У меня при разных размерах стека загрузчика и приложения, а именно когда в загрузчике он больше, не стартует приложение. Как будь-то бы мусором из стека загрузчика инициализируются переменные в основном приложении.
При размещении стека в конце ОЗУ он слишком далеко от данных приложения и этого эффекта уже нет. Конечно это не выход из положения и нужно разбираться что там происходит. Но такая удалённость данных от стека может предохранить их в случае пробоя последнего, может поэтому его народ старается размещать его в конце.
Go to the top of the page
 
+Quote Post
Obam
сообщение Dec 6 2016, 07:42
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Ну тема про M3, и моё мнение более иное: стек в конце RAM - не есть хорошо, раздувшимся стеком точно похерятся данные при форс мажоре.

В .icf компоновщику приказано:
Код
define region RAM_region     = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region ROM_region     = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];

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

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          { block CSTACK, block Process_stack, block HEAP };// более того, если блоки определены, то компоновщик их будет рамещать как приказано
place at end of RAM_region {readwrite};


И стеки в начале RAM, а переменные в конце. Пример:
CODE

*******************************************************************************
*** PLACEMENT SUMMARY
***

"A1": place at 0x00400000 { ro section .intvec };
"P1": place in [from 0x00400000 to 0x0040ffff] { ro };
"P2": place in [from 0x20000000 to 0x20003fff] {
block CSTACK, block Process_stack, block HEAP };
"A2": place at end of [0x20000000-0x20003fff] { rw };
"A3": place at end of [0x00400000-0x0040ffff] { ro section BITMAPS };

Section Kind Address Size Object
------- ---- ------- ---- ------
"A1": 0xcc
.intvec const 0x00400000 0xcc cstartup_M.o [1]
- 0x004000cc 0xcc

"P1": 0x1eac
.text ro code 0x004000cc 0x1ca8 main.o [1]
.text ro code 0x00401d74 0x6 ABImemclr4.o [4]
.text ro code 0x00401d7a 0x2e copy_init3.o [4]
.text ro code 0x00401da8 0x56 ABImemcpy.o [4]
.text ro code 0x00401dfe 0x22 zero_init3.o [4]
.text ro code 0x00401e20 0x32 ABImemset48.o [4]
.text ro code 0x00401e54 0x44 cstartup_M.o [1]
.text ro code 0x00401e98 0x16 cmain.o [4]
.text ro code 0x00401eae 0x4 low_level_init.o [3]
.text ro code 0x00401eb4 0x2c data_init3.o [4]
.text ro code 0x00401ee0 0x4 exit.o [3]
.text ro code 0x00401ee4 0xa cexit.o [4]
.text ro code 0x00401ef0 0xc XXexit.o [4]
.iar.init_table const 0x00401efc 0x24 - Linker created -
.rodata const 0x00401f20 0x20 main.o [1]
.rodata const 0x00401f40 0x18 main.o [1]
.rodata const 0x00401f58 0x10 main.o [1]
.rodata const 0x00401f68 0x8 main.o [1]
Initializer bytes ro data 0x00401f70 0x8 <for rw-1>
.rodata const 0x00401f78 0x0 bwt_init3c.o [4]
- 0x00401f78 0x1eac

"A3": 0x968
BITMAPS const 0x0040f698 0x10 main.o [1]
BITMAPS const 0x0040f6a8 0x8 main.o [1]
BITMAPS const 0x0040f6b0 0xc main.o [1]
BITMAPS const 0x0040f6bc 0x8 main.o [1]
BITMAPS const 0x0040f6c4 0x10 main.o [1]
BITMAPS const 0x0040f6d4 0x8 main.o [1]
BITMAPS const 0x0040f6dc 0x10 main.o [1]
BITMAPS const 0x0040f6ec 0x8 main.o [1]
BITMAPS const 0x0040f6f4 0x10 main.o [1]
BITMAPS const 0x0040f704 0x8 main.o [1]
BITMAPS const 0x0040f70c 0x10 main.o [1]
BITMAPS const 0x0040f71c 0x8 main.o [1]
BITMAPS const 0x0040f724 0x10 main.o [1]
BITMAPS const 0x0040f734 0x8 main.o [1]
BITMAPS const 0x0040f73c 0x10 main.o [1]
BITMAPS const 0x0040f74c 0x8 main.o [1]
BITMAPS const 0x0040f754 0x10 main.o [1]
BITMAPS const 0x0040f764 0x8 main.o [1]
BITMAPS const 0x0040f76c 0x10 main.o [1]
BITMAPS const 0x0040f77c 0x8 main.o [1]
BITMAPS const 0x0040f784 0x8 main.o [1]
BITMAPS const 0x0040f78c 0x8 main.o [1]
BITMAPS const 0x0040f794 0xc main.o [1]
BITMAPS const 0x0040f7a0 0x8 main.o [1]
BITMAPS const 0x0040f7a8 0x10 main.o [1]
BITMAPS const 0x0040f7b8 0x8 main.o [1]
BITMAPS const 0x0040f7c0 0x34 main.o [1]
BITMAPS const 0x0040f7f4 0x14 main.o [1]
BITMAPS const 0x0040f808 0x8 main.o [1]
BITMAPS const 0x0040f810 0xc main.o [1]
BITMAPS const 0x0040f81c 0x8 main.o [1]
BITMAPS const 0x0040f824 0x14 main.o [1]
BITMAPS const 0x0040f838 0x8 main.o [1]
BITMAPS const 0x0040f840 0x14 main.o [1]
BITMAPS const 0x0040f854 0x8 main.o [1]
BITMAPS const 0x0040f85c 0x14 main.o [1]
BITMAPS const 0x0040f870 0x8 main.o [1]
BITMAPS const 0x0040f878 0x14 main.o [1]
BITMAPS const 0x0040f88c 0x8 main.o [1]
BITMAPS const 0x0040f894 0x14 main.o [1]
BITMAPS const 0x0040f8a8 0x8 main.o [1]
BITMAPS const 0x0040f8b0 0x14 main.o [1]
BITMAPS const 0x0040f8c4 0x8 main.o [1]
BITMAPS const 0x0040f8cc 0x14 main.o [1]
BITMAPS const 0x0040f8e0 0x8 main.o [1]
BITMAPS const 0x0040f8e8 0x14 main.o [1]
BITMAPS const 0x0040f8fc 0x8 main.o [1]
BITMAPS const 0x0040f904 0x8 main.o [1]
BITMAPS const 0x0040f90c 0x8 main.o [1]
BITMAPS const 0x0040f914 0x14 main.o [1]
BITMAPS const 0x0040f928 0x8 main.o [1]
BITMAPS const 0x0040f930 0x14 main.o [1]
BITMAPS const 0x0040f944 0x8 main.o [1]
BITMAPS const 0x0040f94c 0x34 main.o [1]
BITMAPS const 0x0040f980 0x8 main.o [1]
BITMAPS const 0x0040f988 0x2c main.o [1]
BITMAPS const 0x0040f9b4 0x8 main.o [1]
BITMAPS const 0x0040f9bc 0xfc main.o [1]
BITMAPS const 0x0040fab8 0x8 main.o [1]
BITMAPS const 0x0040fac0 0x10 main.o [1]
BITMAPS const 0x0040fad0 0x8 main.o [1]
BITMAPS const 0x0040fad8 0xc main.o [1]
BITMAPS const 0x0040fae4 0x8 main.o [1]
BITMAPS const 0x0040faec 0x10 main.o [1]
BITMAPS const 0x0040fafc 0x8 main.o [1]
BITMAPS const 0x0040fb04 0xc main.o [1]
BITMAPS const 0x0040fb10 0x8 main.o [1]
BITMAPS const 0x0040fb18 0x24 main.o [1]
BITMAPS const 0x0040fb3c 0x8 main.o [1]
BITMAPS const 0x0040fb44 0x24 main.o [1]
BITMAPS const 0x0040fb68 0x8 main.o [1]
BITMAPS const 0x0040fb70 0x24 main.o [1]
BITMAPS const 0x0040fb94 0x8 main.o [1]
BITMAPS const 0x0040fb9c 0x24 main.o [1]
BITMAPS const 0x0040fbc0 0x8 main.o [1]
BITMAPS const 0x0040fbc8 0x18 main.o [1]
BITMAPS const 0x0040fbe0 0x8 main.o [1]
BITMAPS const 0x0040fbe8 0x24 main.o [1]
BITMAPS const 0x0040fc0c 0x8 main.o [1]
BITMAPS const 0x0040fc14 0x24 main.o [1]
BITMAPS const 0x0040fc38 0x8 main.o [1]
BITMAPS const 0x0040fc40 0x24 main.o [1]
BITMAPS const 0x0040fc64 0x8 main.o [1]
BITMAPS const 0x0040fc6c 0x24 main.o [1]
BITMAPS const 0x0040fc90 0x8 main.o [1]
BITMAPS const 0x0040fc98 0x24 main.o [1]
BITMAPS const 0x0040fcbc 0x8 main.o [1]
BITMAPS const 0x0040fcc4 0x24 main.o [1]
BITMAPS const 0x0040fce8 0x8 main.o [1]
BITMAPS const 0x0040fcf0 0x14 main.o [1]
BITMAPS const 0x0040fd04 0x8 main.o [1]
BITMAPS const 0x0040fd0c 0x3c main.o [1]
BITMAPS const 0x0040fd48 0x8 main.o [1]
BITMAPS const 0x0040fd50 0x3c main.o [1]
BITMAPS const 0x0040fd8c 0x8 main.o [1]
BITMAPS const 0x0040fd94 0x3c main.o [1]
BITMAPS const 0x0040fdd0 0x8 main.o [1]
BITMAPS const 0x0040fdd8 0x3c main.o [1]
BITMAPS const 0x0040fe14 0x8 main.o [1]
BITMAPS const 0x0040fe1c 0x4 main.o [1]
BITMAPS const 0x0040fe20 0x8 main.o [1]
BITMAPS const 0x0040fe28 0x4 main.o [1]
BITMAPS const 0x0040fe2c 0x8 main.o [1]
BITMAPS const 0x0040fe34 0x4 main.o [1]
BITMAPS const 0x0040fe38 0x8 main.o [1]
BITMAPS const 0x0040fe40 0x4 main.o [1]
BITMAPS const 0x0040fe44 0x8 main.o [1]
BITMAPS const 0x0040fe4c 0x4 main.o [1]
BITMAPS const 0x0040fe50 0x8 main.o [1]
BITMAPS const 0x0040fe58 0x4 main.o [1]
BITMAPS const 0x0040fe5c 0x8 main.o [1]
BITMAPS const 0x0040fe64 0x4 main.o [1]
BITMAPS const 0x0040fe68 0x8 main.o [1]
BITMAPS const 0x0040fe70 0x4 main.o [1]
BITMAPS const 0x0040fe74 0x8 main.o [1]
BITMAPS const 0x0040fe7c 0x14 main.o [1]
BITMAPS const 0x0040fe90 0x8 main.o [1]
BITMAPS const 0x0040fe98 0xc main.o [1]
BITMAPS const 0x0040fea4 0x8 main.o [1]
BITMAPS const 0x0040feac 0x14 main.o [1]
BITMAPS const 0x0040fec0 0x8 main.o [1]
BITMAPS const 0x0040fec8 0x14 main.o [1]
BITMAPS const 0x0040fedc 0x8 main.o [1]
BITMAPS const 0x0040fee4 0x14 main.o [1]
BITMAPS const 0x0040fef8 0x8 main.o [1]
BITMAPS const 0x0040ff00 0x14 main.o [1]
BITMAPS const 0x0040ff14 0x8 main.o [1]
BITMAPS const 0x0040ff1c 0x14 main.o [1]
BITMAPS const 0x0040ff30 0x8 main.o [1]
BITMAPS const 0x0040ff38 0x14 main.o [1]
BITMAPS const 0x0040ff4c 0x8 main.o [1]
BITMAPS const 0x0040ff54 0x14 main.o [1]
BITMAPS const 0x0040ff68 0x8 main.o [1]
BITMAPS const 0x0040ff70 0x14 main.o [1]
BITMAPS const 0x0040ff84 0x8 main.o [1]
BITMAPS const 0x0040ff8c 0x8 main.o [1]
BITMAPS const 0x0040ff94 0x8 main.o [1]
BITMAPS const 0x0040ff9c 0xc main.o [1]
BITMAPS const 0x0040ffa8 0x8 main.o [1]
BITMAPS const 0x0040ffb0 0x8 main.o [1]
BITMAPS const 0x0040ffb8 0x34 main.o [1]
BITMAPS const 0x0040ffec 0x14 main.o [1]
- 0x00410000 0x968

"P2": 0x1400
CSTACK 0x20000000 0x1000 <Block>
CSTACK uninit 0x20000000 0x1000 <Block tail>
Process_stack 0x20001000 0x400 <Block>
Process_stack uninit 0x20001000 0x400 <Block tail>
- 0x20001400 0x1400

"A2": 0x116
rw-1 0x20003ee8 0x8 <Init block>
.data inited 0x20003ee8 0x8 main.o [1]
.bss zero 0x20003ef0 0x4 main.o [1]
.bss zero 0x20003ef4 0x10 main.o [1]
.bss zero 0x20003f04 0x4 main.o [1]
.bss zero 0x20003f08 0x20 main.o [1]
.bss zero 0x20003f28 0x4 main.o [1]
.bss zero 0x20003f2c 0x20 main.o [1]
.bss zero 0x20003f4c 0x4 main.o [1]
.bss zero 0x20003f50 0x4 main.o [1]
.bss zero 0x20003f54 0x14 main.o [1]
.bss zero 0x20003f68 0x4 main.o [1]
.bss zero 0x20003f6c 0x4 main.o [1]
.bss zero 0x20003f70 0x24 main.o [1]
.bss zero 0x20003f94 0x24 main.o [1]
.bss zero 0x20003fb8 0x24 main.o [1]
.bss zero 0x20003fdc 0x14 main.o [1]
.bss zero 0x20003ff0 0x2 main.o [1]
.bss zero 0x20003ff2 0x2 main.o [1]
.bss zero 0x20003ff4 0x2 main.o [1]
.bss zero 0x20003ff6 0x2 main.o [1]
.bss zero 0x20003ff8 0x2 main.o [1]
.bss zero 0x20003ffa 0x2 main.o [1]
.bss zero 0x20003ffc 0x1 main.o [1]
.bss zero 0x20003ffd 0x1 main.o [1]
- 0x20003ffe 0x116


Сообщение отредактировал Obam - Dec 6 2016, 07:44


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 6 2016, 07:48
Сообщение #5


Гуру
******

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



QUOTE (Yogen @ Dec 6 2016, 10:38) *
может поэтому его народ старается размещать его в конце.
Он (народ) размещает стек в конце потому, что таким образом под него отдается вся незанятая память, которая, в противном случае, никем никогда не будет использована. Любая встреча стека с чем угодно (хоть глобальными переменными, хоть с кучей) - всегда катастрофа. Размащая стек в конце ОЗУ народ отдает под него максимально возможное количество памяти, больше уже не выделить никак. И это позволяет отложить больбу с проблемой "стек встретился с данными" до того момента, когда под вашу программу станет уже физически не хватать памяти. Вот и все.


--------------------
На любой вопрос даю любой ответ
"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
Yogen
сообщение Dec 6 2016, 07:53
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 16-11-09
Из: Омск
Пользователь №: 53 657



Цитата(Сергей Борщ @ Dec 6 2016, 11:48) *
Он (народ) размещает стек в конце потому, что таким образом под него отдается вся незанятая память, которая больше никем никогда не будет использована. Любая встреча стека с чем угодно (хоть глобальными переменными, хоть с кучей) - всегда катастрофа. Размащая стек в ОЗУ народ отдает под него максимально возможное количество памяти, больше уже не выделить никак. И это позволяет отложить больбу с проблемой "стек встретился с данными" до того момента, когда подж вашу программу станет уже физически не хватать памяти. Вот и все.

Я так и думал. Смутило, что в примерах для SТM32 и ADuCM360/361 он не привязан ни к началу ни к концу, а плавает вместе с данными. Там всё просто в файле icf
Код
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 6 2016, 08:00
Сообщение #7


Гуру
******

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



QUOTE (Yogen @ Dec 6 2016, 10:53) *
Смутило, что в примерах
Вы вроде взрослый человек, а надеетесь на качество примеров в интернете. Их тоже пишут люди и, судя по качеству кода, чаще всего - довольно низкоквалифицированные люди на зарплате. Заявленную функцию пример выполняет? Да. Денюжка получена, дальше хоть трава не расти. Относитесь к ним только как к примерам - берите из них идею, суть, но не копируйте бездумно реализацию.


--------------------
На любой вопрос даю любой ответ
"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
Yogen
сообщение Dec 6 2016, 08:11
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 16-11-09
Из: Омск
Пользователь №: 53 657



Цитата(Obam @ Dec 6 2016, 11:42) *
Ну тема про M3, и моё мнение более иное: стек в конце RAM - не есть хорошо, раздувшимся стеком точно похерятся данные при форс мажоре.


Если стек в конце, а данные в начале, то при выходе из границ стек будет безболезненно юзать пространство свободного ОЗУ. А если стек вначале, то при том же форсмажоре он сразу перейдёт через нижнюю границу RAM.

Цитата(Сергей Борщ @ Dec 6 2016, 12:00) *
Вы вроде взрослый человек, а надеетесь на качество примеров в интернете.

Во первых не в интернете а в EWВ\arm\config\devices\...
А во-вторых не надеюсь, а подвергаю сомнению и советуюсь с теми кто эту тему проходил. cool.gif

Сообщение отредактировал Yogen - Dec 6 2016, 08:12
Go to the top of the page
 
+Quote Post
jcxz
сообщение Dec 8 2016, 11:06
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Сергей Борщ @ Dec 6 2016, 10:48) *
Он (народ) размещает стек в конце потому, что таким образом под него отдается вся незанятая память, которая, в противном случае, никем никогда не будет использована. Любая встреча стека с чем угодно (хоть глобальными переменными, хоть с кучей) - всегда катастрофа. Размащая стек в конце ОЗУ народ отдает под него максимально возможное количество памяти, больше уже не выделить никак. И это позволяет отложить больбу с проблемой "стек встретился с данными" до того момента, когда под вашу программу станет уже физически не хватать памяти. Вот и все.

Лучше наоборот - расположить стек так, чтобы при его разрушении сразу прекращалось выполнение программы и вылетало на критическую ошибку. Чтобы эту ошибку сразу увидеть и исправить по "горячим следам" сразу как она сделана. А не через несколько месяцев, когда начнёт где-зто что-то глючит уже и не пойми что. И тогда на поиски ошибки уйдёт на порядки больше времени.
Копить ошибки и замазывать их костылями - ущербный подход, в результате всё ПО будет кривое и глючное.

Цитата(Yogen @ Dec 6 2016, 11:11) *
Если стек в конце, а данные в начале, то при выходе из границ стек будет безболезненно юзать пространство свободного ОЗУ. А если стек вначале, то при том же форсмажоре он сразу перейдёт через нижнюю границу RAM.

Стек должен быть не "в конце" и не "в начале", а там куда указано расположение "block HEAP" в *.icf. Вот на конец этого блока и надо ставить SP. Ставить можно например командой LDR SP, xxx в асм-стартап-файле. И нужно проинитить оба стека - MSP и PSP (если конечно не весь код выполняется в Handler-режиме).
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:28
Рейтинг@Mail.ru


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