Hey there !
Still on my port for my dual-core Cortex-M7 ! My core 0 is working without any troubles, and it handles all the tasks of my demo app (just “Hello my name is…” tasks.) But the core 1 goes into HardFault. I observed several things, but I don’t know how to conclude.
First, the Fault Report indicates the register PENDSVACT is set to 1, and the address it indicates is xPortPendSVHandler
, so I can affirm I did a mistake while reworking this handler. Unfortunately, I didn’t saw it before : The core 0 did not encoutered any issue, now in SMP configuration, or sooner when I tried to use my modifications in single core (to check if I have the same behavior.)
Here is my modified version :
void xPortPendSVHandler( void )
{
/* This is a naked function. */
__asm volatile
(
" mrs r0, psp \n"
" isb \n"
" \n"
#if configNUMBER_OF_CORES == 1
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
" ldr r2, [r3] \n"
#else /* configNUMBER_OF_CORES == 1 */
/* [A */" push {r4} \n" /* save r4 */
/* [B */" push {r0-r3, r12, lr} \n" /* Save only these registers as the other are "callee-saved" */
" bl LLD_V7M_SCB_GetCoreID \n" /* Get the current core ID */
" mov r4, r0 \n" /* the core ID is in r4, so we can restore r0 */
/* B] */" pop{r0-r3, r12, lr} \n" /* Restore the previously saved registers */
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
" ldr r2, [r3, r4, lsl #2] \n"
/* A] */" pop {r4} \n"
#endif /* configNUMBER_OF_CORES == 1 */
" \n"
" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */
" it eq \n"
/* [C */" vstmdbeq r0!, {s16-s31} \n"
" \n"
/* [D */" stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
" \n"
/* ... */
(sorry, don’t know how to add the lines numbers.)
the comments /* [A */
were tools for me to ensure all my push and pop in the correct order. But let’s check the 4th line from the end : stmdb{r0-r3, r12, lr}
I kept it from the existing FreeRTOS port for M7, so I don’t think it’s wrong to use it. from what I understand, this instruction pushes my registers onto the stack, and decrements the value of r0. I observed the registers before executing this instruction :
- r0, r4-r11 = 0x00000000
- R14 = LR = 0xFFFFFFF9
r4-r11 and R14 have strange values, but why not. When the Fault occurs, it’s the first time a task is started, so let’s assume it’s because they are not used yet. but why r0 is 0x00000000 ? according to the first instruction mrs r0, psp
, r0 must hold the value of the process stack pointer. 0x00000000 is the base address of the stack for core 0, while the base address for the stack of core 1 is 0x34000000 (verified in the VTOR.) But if I put a breakpoint at mrs...
I see it actually returns 0x00000000.
This what I don’t understand and where I need help.
Thanks for reading !!
– Edit –
Corrected a typo : pop{r0-r3, r12, lr}
→ stmdb{r0-r3, r12, lr}