ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
26 ноября
971372 Топик полностью
Nikolay_Po (18.01.2020 14:26 - 14:30, просмотров: 300) ответил evgeniy1294 на Если немного заморочиться, то можно легко найти проблему:
Имеет место наезд стека на массив. См. ниже. А вот пошаговая отладка. Вылетает на счётчике 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>
То есть, действительно имеет место наезд стека на массив.
image