Посмотрел через отладку по SWD, что там происходит. В зависимости от того как собрать ломается в разных местах. Например с теми настройками, что я обычно использую (-O2 -flto), падаем в коде FreeRTOS, а именно в prvPortStartFirstTask.
Код
static void prvPortStartFirstTask( void )
{
__asm volatile(
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n"
" ldr r0, [r0] \n"
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
" cpsie i \n" /* Globally enable interrupts. */
" cpsie f \n"
" dsb \n"
" isb \n"
" svc 0 \n" /* System call to start first task. */
" nop \n"
);
}
Код
Breakpoint 2, 0x08004158 in prvPortStartFirstTask.lto_priv.84 () at freertos/port.c:490
490 }
(gdb) disassemble
Dump of assembler code for function prvPortStartFirstTask.lto_priv.84:
0x08004154 <+0>: ldr r0, [pc, #476]; (0x8004334)
0x08004156 <+2>: ldr r0, [r0, #0]
=> 0x08004158 <+4>: ldr r0, [r0, #0]
0x0800415a <+6>: msr MSP, r0
0x0800415e <+10>: cpsie i
0x08004160 <+12>: cpsie f
0x08004162 <+14>: dsb sy
0x08004166 <+18>: isb sy
0x0800416a <+22>: svc 0
0x0800416c <+24>: nop
End of assembler dump.
(gdb) info registers
r0 0xbfa91300 -1079438592
r1 0xf00000 15728640
...
То есть прочитали из SCB->VTOR какую-то непонятную 0xbfa91300, хотя там должно быть 0x8000000. Я даже вручную это туда записываю в коде инициализации, который к этому моменту уже выполнен.
Начал разбираться, что там на самом деле пишется в тот VTOR, оказалось именно тот мусор вместо начала flash. Дальше заменил строку,
Код
//SCB->VTOR = (unsigned long) &ldSvectors;
SCB->VTOR = (unsigned long) 0x80000000;
запускаю и получаю,
Код
0x0800be28 <+156>: ldr r4, [pc, #108]; (0x800be98 <halStart+268>)
0x0800be2a <+158>: add r2, pc
0x0800be2c <+160>: mov.w r6, #2147483648; 0x80000000
0x0800be30 <+164>: str r0, [r2, #0]
0x0800be32 <+166>: ldr.w r0, [r3, #136]; 0x88
0x0800be36 <+170>: ldr r2, [pc, #100]; (0x800be9c <halStart+272>)
0x0800be38 <+172>: orr.w r0, r0, #15728640; 0xf00000
=> 0x0800be3c <+176>: str.w r0, [r3, #136]; 0x88
0x0800be40 <+180>: str r6, [r3, #8]
0x0800be42 <+182>: ldr r0, [r3, #12]
0x0800be44 <+184>: movw r6, #63743; 0xf8ff
0x0800be48 <+188>: ands r0, r6
0x0800be4a <+190>: orrs r2, r0
0x0800be4c <+192>: str r2, [r3, #12]
0x0800be4e <+194>: ldr r3, [r5, #0]
0x0800be50 <+196>: orr.w r3, r3, #240; 0xf0
0x0800be54 <+200>: str r3, [r5, #0]
0x0800be56 <+202>: ldr r3, [r1, #48]; 0x30
0x0800be58 <+204>: orr.w r3, r3, #7
0x0800be5c <+208>: str r3, [r1, #48]; 0x30
0x0800be5e <+210>: ldr r3, [r4, #0]
0x0800be60 <+212>: bic.w r3, r3, #64512; 0xfc00
0x0800be64 <+216>: orr.w r3, r3, #21504; 0x5400
0x0800be68 <+220>: str r3, [r4, #0]
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) si
155 SCB->VTOR = (unsigned long) 0x80000000;
1: *((int* ) 0xE000ED08) = 0
(gdb) si
NVIC_SetPriorityGrouping () at hal/cmsis/core_cm4.h:1467
1467 reg_value = SCB->AIRCR; /* read old register configuration */
1: *((int* ) 0xE000ED08) = -2147483648
(gdb)
(gdb) info registers
r0 0xf00000 15728640
r1 0x40023800 1073887232
r2 0x5fa0300 100270848
r3 0xe000ed00 -536810240
r4 0x40020400 1073873920
r5 0x40007000 1073770496
r6 0x80000000 -2147483648
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
sp 0x1000fff4 0x1000fff4
lr 0x800bf6f 0x800bf6f <ccmComp+8>
pc 0x800be42 0x800be42 <halStart+182>
xpsr 0x61000000 1627389952
fpscr 0x0 0
msp 0x1000fff4 0x1000fff4
psp 0x0 0x0
special 0x0 0
Как вот так может быть? Наверно уже устал, надо еще раз самому это перечитать. Да, все верно, только дальше продолжает падать, но теперь уже иначе, корректного указателя стека нет, стало сложнее. На этот раз где-то в pvPortMalloc, точнее определить сложно, надо глазами анализировать код и содержимое стека.
Может это GCC, я его недавно обновлял на 6.3.0.