上下文的切换,首先是调用OSCtxSw,该函数并没有真正的进行切换,只是出发的PendSV中断。上下文的切换在OS_CPU_PendSVHandler中完成。
OSCtxSw LDR R0, =NVIC_INT_CTRL 获取中断控制寄存器地址 LDR R1, =NVIC_PENDSVSET 获取PendSV中断向量 STR R1, [R0] 触发PendSV中断 BX LR 函数返回
OS_CPU_PendSVHandler CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time TST LR, #0x10 IT EQ VSTMDBEQ R0!, {S16-S31} MOV R3, LR STMDB R0!,{R3-R11} LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP; LDR R1, [R1] STR R0, [R1] ; R0 is SP of process being switched out ; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave PUSH {R14} ; Save LR exc_return value LDR R0, =OSTaskSwHook ; 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] ; R0 is new process SP ; SP = OSTCBHighRdyPtr->StkPtr; LDMIA R0!,{R3-R11} MOV LR, R3 TST LR, #0x10 IT EQ VLDMIAEQ R0!, {S16-S31} MSR PSP, R0 ; Load PSP with new process SP CPSIE I BX LR ; Exception return will restore remaining context END