废话不多,直接上干活
1、任务切换会通过调用OSCtxSw这个函数
OSCtxSw LDR R0, =NVIC_INT_CTRL LDR R1, =NVIC_PENDSVSET STR R1, [R0] BX LR ;这段代码是跳转倒pendSV的中断函数中运行。
2、中断函数内容如下
OS_CPU_PendSVHandler
CPSID I ;关闭所有中断
MRS R0, PSP ; PSP是任务堆栈,如果第一次运行,这个值是0
CBZ R0, OS_CPU_PendSVHandler_nosave
;如果任务堆栈是0,直接跳转OS_CPU_PendSVHandler_nosave
SUBS R0, R0, #0x20 ; 保存R4-R11内容,这个部分主要是临时变量
STM R0, {R4-R11}
LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP;
LDR R1, [R1]
STR R0, [R1] ; 保存当前任务的SP
;
OS_CPU_PendSVHandler_nosave
PUSH {R14} ; 这个部分是调用切换任务的钩子函数
LDR R0, =OSTaskSwHook
BLX R0
POP {R14}
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr;
LDR R1, =OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; 恢复到新任务的SP
LDM R0, {R4-R11} ; 恢复R4-R11
ADDS R0, R0, #0x20
MSR PSP, R0 ; PSP为新任务的地址
ORR LR, LR, #0x04
CPSIE I
BX LR ;跳转到新任务