PensSV Exception: Is it necessary to push and pop r0 during context switching?

Recently, I’ve been spending time reading the code for SVC and PendSV exceptions, but there’s a detail I haven’t understood. As shown in the figure below, in the PendSV exception, r0 and r3 are pushed onto the stack before calling vTaskSwitchContext. It’s understandable to push r3 since it equals pxCurrentTCB, but is it necessary to push r0 onto the stack here?

You need to push more than one register to maintain an 8-byte aligned stack for the vTaskSwitchContext() function call - which in this case is only really necessary if that function calls a user supplied callback or macro (such as a trace macro). Even so, for future proofing, it’s best to ensure compliance with the EABI specification because future compiler versions may depend on it.

1 Like

I BELIEVE your fallacy here is that since we are in an ISR context already when we get here, all registers BUT r0 have already been saved, so we are free to use eg r3 as temporary storage. Now a task switch has to be completly transparent to the task switched out from, meaning all registers including r0 (which is excluded from the abi) must eventually be restored. The code is this handler will eventually ensure that all register contents will be saved in the TCB even though the abi does not enforce it.

When entering an exception in ARM, the caller-saved registers (r0~r3, r12, lr, pc, and xPSR) are saved on the stack, including r0. I removed the stack push and pop for r0 in the code, and FreeRTOS can still perform task scheduling normally. I believe what “rtel” said is correct.