具体细节看那个切换函数。OSPendSV
IF OS_CRITICAL_INT_PRIO > 0 ; disable interupt 禁能中断
MRS R3, BASEPRI
LDR R1, =OS_CRITICAL_INT_PRIO
MSR BASEPRI, R1
ELSE
MRS R3, PRIMASK
CPSID I
ENDIF
MRS R0, PSP ; PSP is process stack pointer
; PSP是任务的堆栈指针
CBZ R0, OSPendSV_nosave ; skip register save the first
; time第一次跳过保存
SUB R0, R0, #0x20 ; save remaining regs r4-11 on
; process stack 保存r4-r11
STM R0, {R4-R11}
LDR R4, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R4, [R4]
STR R0, [R4] ; R0 is SP of process being
; switched outR0是被切换开的任务
; 的堆栈指针
OSPendSV_nosave
PUSH {R14} ; need to save LR exc_return
; value保存LR返回值
LDR R0, =OSTaskSwHook ; OSTaskSwHook();
BLX R0
POP {R14}
LDR R4, =OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR R5, =OSPrioHighRdy
LDRB R6, [R5]
STRB R6, [R4]
LDR R4, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
STR R6, [R4]
LDR R0, [R6] ; SP = OSTCBHighRdy->OSTCBStkPtr;
LDM R0, {R4-R11} ; restore r4-11 from new process
; stack 从新任务的堆栈恢复r4-r11
ADD R0, R0, #0x20
MSR PSP, R0 ; load PSP with new process SP
; 从新任务的堆栈恢复PSP
ORR LR, LR, #0x04 ; ensure exception return uses
; PSP确保返回后使用PSP
IF OS_CRITICAL_INT_PRIO > 0 ; restore interrupts 恢复中断
MSR BASEPRI, R3
ELSE
MSR PRIMASK, R3
ENDIF
BX LR ; exception return will restore
; remaining context
; 返回时会恢复剩下的上下文
NOP
|