void xPortPendSVHandler( void )
{
__asm volatile
(
mrs r0, psp
/* PSP值保存至R0 */
isb
/* 清除流水线之前的指令已经执行完成*/
ldr r3, pxCurrentTCBConst
/* 获取当前TCB栈的位置 */
ldr r2, [r3]
/* 保存栈的值 */
stmdb r0!, {r4-r11}
/* 将R0减去4保存R11依次类推保存 */
str r0, [r2]
/* 将R0的值赋给栈顶地址的值 */
stmdb sp!, {r3, r14}
/* 将R3- R14的值临时压入栈中 */
mov r0, %0
msr basepri, r0
/* 进入临界资源 */
bl vTaskSwitchContext
/* 切换优先级最高任务控制块 */
mov r0, #0
msr basepri, r0
/* 退出临界资源 */
ldmia sp!, {r3, r14}
/* R3-R14出栈恢复 */
ldr r1, [r3]
/* R3指向当前任务 */
ldr r0, [r1]
/* R0保存当前任务栈顶位置 */
ldmia r0!, {r4-r11}
/* 将上次压入栈中的值恢复到R3-R11 */
msr psp, r0
/* R0栈顶位置保存到PSP */
isb
bx r14
/* 异常返回硬件恢复 */
.align 4
"pxCurrentTCBConst: .word pxCurrentTCB
::“i” ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
);
}
-
当发生PendSV中断时,Cortex-M4内核会自动保存PSP、PC、LR、R12、R3-R0八个寄存器到栈中,R4-R11这几个需要手动保存。
-
PendSV中断中调用bx r14 时,硬件将自动恢复PSP、PC、LR、R12、R3-R0八个寄存器的值。