Имеет место наезд стека на массив. См. ниже. А вот пошаговая отладка. Вылетает на счётчике 1998..1999. Код, где вылетает, такой:
void SysTick_Handler(void)
{
HAL_IncTick();
unsigned Index = Count & 16383u;
if(Count>1997){
asm volatile ("nop");
}
TestArray[Index] = (int16_t) Count;
Count++;
}
Поставил прерывание по условию (Count>1997). И вот что вижу, см. картинку. Массив уже частично затёрт и следующая запись в ячейку 1998 затирает что-то важное, из-за чего, по возврату из SysTick_Handler() программа крашится тем или иным образом.
Попытка "разматывать" стек бессмысленна, так как содержимое стека уже повреждено.
На картинке красным обведены записанные в массив данные, которые затёрлись посторонней записью. Стрелками обозначена ячейка, куда выполняется запись, после которой возврат из обработчика прерываний приводит к сбою.
Как видно из распечатки массива, адрес, запись по которому приводит к отказу, такой: 0x20000FC4. В диапазон секции .bss.TestArray попадает. Вот, собственно, секция .bss:
.bss 0x000000002000000c 0x8024 load address 0x0000000008001554
0x000000002000000c _sbss = .
0x000000002000000c __bss_start__ = _sbss
*(.bss)
.bss 0x000000002000000c 0x1c /opt/st/stm32cubeide_1.2.0/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.linux64_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7-m/crtbegin.o
*(.bss*)
.bss.TestArray
0x0000000020000028 0x8000 Core/Src/main.o
0x0000000020000028 TestArray
.bss.Count 0x0000000020008028 0x4 Core/Src/main.o
0x0000000020008028 Count
*(COMMON)
COMMON 0x000000002000802c 0x4 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.o
0x000000002000802c uwTick
0x0000000020008030 . = ALIGN (0x4)
0x0000000020008030 _ebss = .
0x0000000020008030 __bss_end__ = _ebss
._user_heap_stack
0x0000000020008030 0x600 load address 0x0000000008001554
0x0000000020008030 . = ALIGN (0x8)
0x0000000020008030 PROVIDE (end = .)
[!provide] PROVIDE (_end = .)
0x0000000020008230 . = (. + _Min_Heap_Size)
*fill* 0x0000000020008030 0x200
0x0000000020008630 . = (. + _Min_Stack_Size)
*fill* 0x0000000020008230 0x400
0x0000000020008630 . = ALIGN (0x8)
В указателе стека sp перед сбоем:
Name : sp
Hex:0x20000fb8
Default:0x20000fb8 <TestArray+3984>
То есть, действительно имеет место наезд стека на массив.