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}