Обращение к нереализованному адресу это совсем не выход за разрешенный диапазон, и, как мне кажется, может как-то помочь уж совсем в крайнем случае.
Отладка - это не то, что я имел ввиду. Прикладная программа может отловить аварийный выход стека за пределы и реализовать что-то вроде BSOD, что может помочь в нахождении проблем при эксплуатации, когда отладчик вообще ни к месту.
Но если полноценного контроля за "сегментами" нет, все эти рассусоливания ни к чему вообще.
В итоге, имхо, всех поголовно устроил бы тот вариант, о котором и говорил топикстартер: STACK=MAXRAM-STATIC-HEAP
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
[uquote="dosikus",url="/forum/viewtopic.php?p=3443016#p3443016"]Сумневающиеся, о отладке в RAM не забыли?[/uquote]У меня это вообще стандартно. Я почему и удивляюсь, чего такого сложного поправить скрипт линкера? Им даже размер стека лень поправить. Полный пердомонокль.
VladislavS писал(а):У меня это вообще стандартно. Я почему и удивляюсь, чего такого сложного поправить скрипт линкера? Им даже размер стека лень поправить. Полный пердомонокль.
Не придумывайте, то чего тут не говорилось. Все ходы записаны.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3443047#p3443047"]Не придумывайте, то чего тут не говорилось. Все ходы записаны.[/uquote]
Ну да, конечно, записыватель нашёлся.
[uquote="afz",url="/forum/viewtopic.php?p=3442611#p3442611"]Угу. Только EmBitz делает это сам, без моих движений, а Кейлу я должен буду править каждый проект, где мне нужно такое распределение памяти. И еще непонятно, как при этом бороться с кейловскими Stack_Size и Heap_Size - их же тоже придется регулярно править...[/uquote]
Размер стэка и кучи в каждом проекте править, Карл!
Инициализировал SP значением 0x20000000, то бишь ниже ОЗУ, в каком-то ничего не делающем особо проекте. Никаких настроек для обработки исключения больше не делал.
При запуске ввалился в Default_Handler().
Вот причина.Спойлер
SP=0x1fffffe0
Ну нормально, можно так за стеком следить.
МК STM32F103
Добавлено after 1 minute 43 seconds:
VladislavS писал(а):Размер стэка и кучи в каждом проекте править,
И где тут некие "они" сказали что "им" лень?
Добавлено after 4 minutes 9 seconds:
Где-то у меня еще 030 валяется, на нем чтоли еще попробовать, что будет.
А есть ешё чипы с CCM RAM и в них стек очень хорошо туда ложится. Как вы не поймёте, что не бывает одного универсального/правильного/лучшего решения для всех проектов.
В регистре BFAR значение 1ffffff8. Получается ошибка не конкретно срыва стека, а ошибка адреса. Т.е. этот регистр хранит адрес куда пытался залезть.
Но вроде как, можно отдельно настроить прерывание для М3 при проблемах со стеком, судя по маскам указанным мной ранее. Хотя я их ошибочно флагами назвал. Короче там много надо курить.
Хотя и этого достаточно чтобы за стеком бдить.
Добавлено after 1 minute 21 second:
[uquote="VladislavS",url="/forum/viewtopic.php?p=3443073#p3443073"]А есть ешё чипы с CCM RAM и в них стек очень хорошо туда ложится. Как вы не поймёте, что не бывает одного универсального/правильного/лучшего решения для всех проектов.[/uquote] Большой дядя, и этого никто не заявлял и не искал универсального решения для всего.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3443076#p3443076"]Большой дядя, и этого никто не заявлял и не искал универсального решения для всего.[/uquote]Мне уже надоело тыкать вас мордой. Либо читать не умеете, либо с памятью плохо.
[uquote="afz",url="/forum/viewtopic.php?p=3442515#p3442515"]Это каждому проекту крутить, а хотелось бы поставить где-нибудь галочку, чтобы он делал это сам и для всех.[/uquote]Для всех проектов одной галочкой, Карл!
Z_h_e писал(а):Инициализировал SP значением 0x20000000, то бишь ниже ОЗУ, в каком-то ничего не делающем особо проекте. Никаких настроек для обработки исключения больше не делал.
При запуске ввалился в Default_Handler().
МК STM32F103
Это STM32F103 попадает в Default_Handler()? В таблице не нашел такого прерывания. Может имелся в виду МК с ядром M0?
В STM32F103 при выходе стека за пределы ОЗУ происходит переход в HardFault_Handler().
Ага, именно 103. Я в кокосе, может просто по разному обозваны обработчики исключений.
А вот сейчас я пробую 030. Но только распаковал его, еще до этого не пробовал никогда. Сразу обратил внимание, что SP уже инициализируется ручками, а нулевой вектор Reserved.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Z_h_e писал(а):А вот сейчас я пробую 030. Но только распаковал его, еще до этого не пробовал никогда. Сразу обратил внимание, что SP уже инициализируется ручками, а нулевой вектор Reserved.
По нулевому вектору адрес стека как и в STM32F103.
Последний раз редактировалось Мурик Пт авг 24, 2018 21:52:24, всего редактировалось 2 раза.
Добавлено after 20 minutes 15 seconds:
Попробовал на 030. Стартап тут у меня уже ассмоский. По умолчанию SP на конец оперативки. Инициализировал SP=0x20000000. Ожидаемо ввалился в обработчик преывания по умолчанию. С регистрами причины не стал разбираться. Можно будет поразибраться именно по какому вектору идет прерывание. Но это уже вопрос техники.
Надо будет со скриптом линкера поразбираться и попробовать стек поставить вперед кобылы .
Нормальная в общем то идея бдить за срывом стека.
Добавлено after 3 minutes 45 seconds:
Мурик писал(а):По нулевому вектору адрес стека как и в STM32F103.
Стартап у меня его туда кладет, но он не используется.(исп. 25.08.2018 07:30)
Вот как там происходит инициализация.
Добавлено after 5 minutes 35 seconds:
Получается в 030 в линкере не выделяется секция под стек. Просто в конец sp и все. Но тут МК конечно самый простецкий из линейки stm32.
Последний раз редактировалось Z_h_e Сб авг 25, 2018 06:23:24, всего редактировалось 2 раза.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Reset_Handler:
/* Loop to copy data from read only memory to RAM. The ranges
* of copy from/to are specified by following symbols evaluated in
* linker script.
* __etext: End of code section, i.e., begin of data sections to copy from.
* __data_start__/__data_end__: RAM address range that data should be
* copied to. Both must be aligned to 4 bytes boundary. */
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .flash_to_ram_loop_end
movs r4, 0
.flash_to_ram_loop:
ldr r0, [r1,r4]
str r0, [r2,r4]
adds r4, 4
cmp r4, r3
blt .flash_to_ram_loop
.flash_to_ram_loop_end:
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
ldr r0, =_start
bx r0
.pool
.size Reset_Handler, . - Reset_Handler
/* Our weak _start alternative if we don't use the library _start
* The zero init section must be cleared, otherwise the librtary is
* doing that */
.align 1
.thumb_func
.weak _start
.type _start, %function
_start:
/* Zero fill the bss segment. */
ldr r1, = __bss_start__
ldr r2, = __bss_end__
movs r3, #0
b .fill_zero_bss
.loop_zero_bss:
str r3, [r1]
adds r1, 4
.fill_zero_bss:
cmp r1, r2
bcc .loop_zero_bss
/* Jump to our main */
bl main
b .
.size _start, . - _start
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (NOLOAD):
{
*(.stack)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
VladislavS писал(а):Для всех проектов одной галочкой, Карл!
Именно. До сих пор всё, что я знал о скриптах линкера, это то, что они существуют, что их генерит среда, которую я пользую, и больше ничего. И был счастлив в своем незнании. А теперь выясняется, что одна из сред генерит нечто неудобное и мне для комфортной работы надо куда-то лезть и что-то править. На хрена мне, спрашивается, это удовольствие? Классическое преодоление трудностей, специально для этой цели придуманных.
Ладно, случай с malloc() в некоторой степени надуманный - это характерно, скорее, для компьютеров, где и памяти может быть разное количество, и загруженность другими задачами разной. На МК изменение размера доступной памяти возможно только при переносе на другой МК, не грех и руками поправить. То есть, бог с ней, с кучей. Но ведь в стеке располагаются автоматические переменные и массивы. Приспичит мне в какой-то программуле объявить массив килобайт на несколько, и лезь в startup_stm32f10x_md править размер стека. Какого хрена я вынужден делать правку сразу в двух местах? Чем думали кейловские программисты, когда делали такое? Головой? Ну, так пусть сядут на нее!..
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3443097#p3443097"]Добавлено after 3 minutes 45 seconds:
Мурик писал(а):По нулевому вектору адрес стека как и в STM32F103.
Стартап у меня его туда кладет, но он не используется.[/uquote]Этого не может быть, потому что не может быть никогда. Это же кортекс, он по ресету аппаратно из нулевого вектора загружает указатель стека.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3443097#p3443097"]Вот как там происходит инициализация.
[/uquote]Это написано для случая, если либо загрузчик, либо отладчик загрузил прошивку в ОЗУ и не знает, что надо стек инициализировать значением из нулевого вектора. В принципе, можно убрать.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3443097#p3443097"]Правка вектора №0 эффекта не дает в 030.[/uquote]А чего бы она давала эффект, если стартап его переинициализирует на _eram.
Добавлено after 8 minutes 15 seconds:
[uquote="afz",url="/forum/viewtopic.php?p=3443168#p3443168"]Какого хрена я вынужден делать правку сразу в двух местах? Чем думали кейловские программисты, когда делали такое? Головой? Ну, так пусть сядут на нее!..[/uquote]Хорош истерить уже. Всё там в одном месте правится. У Keil не лучшее решение в этом плане, но оно рабочее.
VladislavS писал(а):Это же кортекс, он по ресету аппаратно из нулевого вектора загружает указатель стека.
Да, с этим я перемудрил. Сбило с толку принудительная инициализация SP и Reserved в таблице векторов. Хотя второе есть и на 103. Сейчас обозначу это в ранее сказанном.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Однажды в одной программе столкнулся с переполнением стека. Как изменить размер быстро не нашел, пошел обходным путем. Такой вариант беру на заметку. Правда на изменение размера кучи ругается.
VladislavS писал(а):Всё там в одном месте правится.
Неправда. В одном месте я исправил свою программу - добавил массив и что-то с ним делаю. А еще я должен не забыть в другом месте поправить размер стека.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)