uC/OS移植

MRS R0, PSP ; PSP is process stack pointer…

一、任务切换

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。

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