Skip to content

uC/OS移植

· 2 min

一、任务切换#

PendSV_Handler
CPSID I ; Cortex-M7 errata notice. See Note #5
MOV32 R2, OS_KA_BASEPRI_Boundary ; Set BASEPRI priority level required for exception preemption
LDR R1, [R2]
MSR BASEPRI, R1
DSB
ISB
CPSIE I
MRS R0, PSP ; PSP is process stack pointer
STMFD R0!, {R4-R11, R14} ; Save remaining regs r4-11, R14 on process stack
LDR R5, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R1, [R5]
STR R0, [R1] ; R0 is SP of process being switched out
; At this point, entire context of process has been saved
MOV R4, LR ; Save LR exc_return value
BL OSTaskSwHook ; Call OSTaskSwHook() for FPU Push & Pop
LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R1, =OSTCBHighRdy ; OSTCBCur = OSTCBHighRdy;
LDR R2, [R1]
STR R2, [R5]
ORR LR, R4, #0x04 ; Ensure exception return uses process stack
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
LDMFD R0!, {R4-R11, R14} ; Restore r4-11, R14 from new process stack
MSR PSP, R0 ; Load PSP with new process SP
MOV32 R2, #0 ; Restore BASEPRI priority level to 0
CPSID I
MSR BASEPRI, R2
DSB
ISB
CPSIE I
BX LR ; Exception return will restore remaining context
ALIGN ; Removes warning[A1581W]: added <no_padbytes> of padding at <address>
END
  1. 触发PendSV的中断,进入中断服务程序。

  2. 屏蔽低优先级的中断,或者直接关闭中断。关中断防止额外的中断嵌套。

  3. 使用MRS指令读取PSP指针的值。因为CPU进入了中断模式,SP指针已经变成了MSP,所以不能直接压栈,只能通过MRS指令读取PSP的值,再将R4到R11和R14寄存器的值直接压栈进入PSP。

    为什么不保存其他寄存器的值?