|
-
- RSEG .text:CODE:NOROOT(2)
- THUMB
- PendSV_Handler
- CPSID I ; Prevent interruption during context switch
- MRS R0, PSP ; PSP is process stack pointer
- CMP R0, #0
- BEQ __nosave_regs ; equivalent code to CBZ from M3 arch to M0 arch
- ; Except that it does not change the condition code flags
- SUBS R0, R0, #0x20 ; Save remaining regs r4-r11 on process stack
- LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP;
- LDR R1, [R1]
- STR R0, [R1] ; R0 is SP of process being switched out
-
- STM R0!, {R4-R7} ; Store R4-R7(Low Registers) on process stack
- MOV R4, R8 ; Move R8-R11 values to R4-R7 registers.
- MOV R5, R9
- MOV R6, R10
- MOV R7, R11
- STM R0!, {R4-R7} ; Store R8-R11(High Registers) on process stack
- ; At this point, entire context of process has been saved
- __nosave_regs
- LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy;
- LDR R1, =OSPrioHighRdy
- LDRB R2, [R1]
- STRB R2, [R0]
- LDR R0, =OSTCBCur ; OSTCBCur = OSTCBHighRdy;
- LDR R1, =OSTCBHighRdy
- LDR R2, [R1]
- STR R2, [R0]
-
- LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
- ADDS R0, #0x10 ; Adjust SP to High Registers(R8-R11) location
- LDM R0!, {R4-R7} ; Load R8-R11 values from new process stack into R4-R7
- MOV R8, R4 ; Restore R8-R11 by moving their values from R4-R7
- MOV R9, R5
- MOV R10, R6
- MOV R11, R7
-
- MSR PSP, R0 ; Load PSP with new process SP
-
- SUBS R0, R0, #0x20 ; Adjust SP to Low registers(R4-R7) location
- LDM R0!, {R4-R7} ; Restore remaining R4-R7 from new process stack
- MOV R0, R14
- MOVS R1, #0x04 ; Immediate move to register
- ORRS R0, R1 ; Ensure exception return uses process stack
- MOV R14, R0
- CPSIE I
- BX LR ; Exception return will restore remaining context
复制代码 |
|