|
Инициализация стека в Cortex M3 |
|
|
|
Dec 6 2016, 04:37
|
Участник

Группа: Участник
Сообщений: 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?
|
|
|
|
|
 |
Ответов
(1 - 8)
|
Dec 6 2016, 07:38
|
Участник

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

|
Цитата(Kabdim @ Dec 6 2016, 11:14)  msp должен быть устновлен там куда указывает указатель в начале прошивке, всё остальное для бутлоадера совершенно не важно. Так и есть. Но я почему начал копать?! У меня при разных размерах стека загрузчика и приложения, а именно когда в загрузчике он больше, не стартует приложение. Как будь-то бы мусором из стека загрузчика инициализируются переменные в основном приложении. При размещении стека в конце ОЗУ он слишком далеко от данных приложения и этого эффекта уже нет. Конечно это не выход из положения и нужно разбираться что там происходит. Но такая удалённость данных от стека может предохранить их в случае пробоя последнего, может поэтому его народ старается размещать его в конце.
|
|
|
|
|
Dec 6 2016, 07:42
|

Знающий
   
Группа: Участник
Сообщений: 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
--------------------
Пролетарий умственного труда.
|
|
|
|
|
Dec 6 2016, 07:48
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Dec 6 2016, 07:53
|
Участник

Группа: Участник
Сообщений: 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 };
|
|
|
|
|
Dec 6 2016, 08:00
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Dec 6 2016, 08:11
|
Участник

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

|
Цитата(Obam @ Dec 6 2016, 11:42)  Ну тема про M3, и моё мнение более иное: стек в конце RAM - не есть хорошо, раздувшимся стеком точно похерятся данные при форс мажоре. Если стек в конце, а данные в начале, то при выходе из границ стек будет безболезненно юзать пространство свободного ОЗУ. А если стек вначале, то при том же форсмажоре он сразу перейдёт через нижнюю границу RAM. Цитата(Сергей Борщ @ Dec 6 2016, 12:00)  Вы вроде взрослый человек, а надеетесь на качество примеров в интернете. Во первых не в интернете а в EWВ\arm\config\devices\... А во-вторых не надеюсь, а подвергаю сомнению и советуюсь с теми кто эту тему проходил.
Сообщение отредактировал Yogen - Dec 6 2016, 08:12
|
|
|
|
|
Dec 8 2016, 11:06
|
Гуру
     
Группа: Свой
Сообщений: 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-режиме).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|