📄 os_cpu_a.asm
字号:
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, ?OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
;
; Note(s) : 1) OSIntCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED.
;
; 2) The pseudo-code for OSCtxSw() is:
; a) OSTaskSwHook();
; b) OSPrioCur = OSPrioHighRdy;
; c) OSTCBCur = OSTCBHighRdy;
; d) SP = OSTCBHighRdy->OSTCBStkPtr;
; e) Restore the new task's context from the new task's stack,
; f) Return to new task's code.
;
; 3) Upon entry:
; OSTCBCur points to the OS_TCB of the task to suspend,
; OSTCBHighRdy points to the OS_TCB of the task to resume.
;********************************************************************************************************
OSIntCtxSw
LDR R0, ?OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, ?OS_PrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, ?OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;********************************************************************************************************
; UNDEFINED INSTRUCTION EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptUndefInstrHndlr
; LR offset to return from this exception: 0.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_UNDEF_INSTR ; Set exception ID to OS_CPU_ARM_EXCEPT_UNDEF_INSTR.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; SOFTWARE INTERRUPT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptSwiHndlr
; LR offset to return from this exception: 0.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_SWI ; Set exception ID to OS_CPU_ARM_EXCEPT_SWI.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; PREFETCH ABORT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptPrefetchAbortHndlr
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_PREFETCH_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_PREFETCH_ABORT.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; DATA ABORT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptDataAbortHndlr
SUB LR, LR, #8 ; LR offset to return from this exception: -8.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_DATA_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_DATA_ABORT.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; ADDRESS ABORT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptAddrAbortHndlr
SUB LR, LR, #8 ; LR offset to return from this exception: -8.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_ADDR_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_ADDR_ABORT.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; INTERRUPT REQUEST EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptIrqHndlr
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_IRQ ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; FAST INTERRUPT REQUEST EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptFiqHndlr
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
STMFD SP!, {R0-R3} ; Push working registers.
MOV R2, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_FIQ ; Set exception ID to OS_CPU_ARM_EXCEPT_FIQ.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; GLOBAL EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1 Exception's SPSR
; R2 Return PC
; R3 Exception's SP
;
; Note(s) : 1) An exception can occur in three different circumstances; in each of these, the
; SVC stack pointer will point to a different entity :
;
; a) CONDITION: An exception occurs before the OS has been fully initialized.
; SVC STACK: Should point to a stack initialized by the application's startup code.
; STK USAGE: Interrupted context -- SVC stack.
; Exception -- SVC stack.
; Nested exceptions -- SVC stack.
;
; b) CONDITION: An exception interrupts a task.
; SVC STACK: Should point to task stack.
; STK USAGE: Interrupted context -- Task stack.
; Exception -- Exception stack 'OS_CPU_ExceptStk[]'.
; Nested exceptions -- Exception stack 'OS_CPU_ExceptStk[]'.
;
; c) CONDITION: An exception interrupts another exception.
; SVC STACK: Should point to location in exception stack, 'OS_CPU_ExceptStk[]'.
; STK USAGE: Interrupted context -- Exception stack 'OS_CPU_ExceptStk[]'.
; Exception -- Exception stack 'OS_CPU_ExceptStk[]'.
; Nested exceptions -- Exception stack 'OS_CPU_ExceptStk[]'.
;********************************************************************************************************
OS_CPU_ARM_ExceptHndlr
MRS R1, SPSR ; Save CPSR (i.e. exception's SPSR).
MOV R3, SP ; Save exception's stack pointer.
; Adjust exception stack pointer. This is needed because
; exception stack is not used when restoring task context.
ADD SP, SP, #(4 * 4)
; Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
; SAVE CONTEXT ONTO SVC STACK:
STMFD SP!, {R2} ; Push task's PC,
STMFD SP!, {LR} ; Push task's LR,
STMFD SP!, {R4-R12} ; Push task's R12-R4,
LDMFD R3!, {R5-R8} ; Move task's R3-R0 from exception stack to task's stack.
STMFD SP!, {R5-R8}
STMFD SP!, {R1} ; Push task's CPSR (i.e. exception SPSR).
; if (OSRunning == 1)
LDR R3, ?OS_Running
LDRB R4, [R3]
CMP R4, #1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -