📄 os_cpu_a.s
字号:
@ 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, =OSTaskSwHook @ OSTaskSwHook();
MOV LR, PC
BX R0
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 SP, [R2] @ SP = OSTCBHighRdy->OSTCBStkPtr;
@ RESTORE NEW TASK'S CONTEXT
LDMFD SP!, {R0} @ Pop new task's CPSR
MSR CPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC} @ Pop new task's context
@********************************************************************************************************
@ RESET EXCEPTION HANDLER
@********************************************************************************************************
OS_CPU_ARM_ExceptResetHndlr:
@ LR offset to return from this exception: 0
@ (there is no way to return from a RESET exception)
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, LR @ Save link register
MOV R0, #OS_CPU_ARM_EXCEPT_RESET @ Set exception ID to OS_CPU_ARM_EXCEPT_RESET
B OS_CPU_ARM_ExceptHndlr @ Branch to global exception handler
@********************************************************************************************************
@ UNDEFINED INSTRUCTION EXCEPTION HANDLER
@********************************************************************************************************
OS_CPU_ARM_ExceptUndefInstrHndlr:
@ LR offset to return from this exception: 0
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptSwiHndlr:
@ LR offset to return from this exception: 0
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptPrefetchAbortHndlr:
SUB LR, LR, #4 @ LR offset to return from this exception: -4
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptDataAbortHndlr:
SUB LR, LR, #8 @ LR offset to return from this exception: -8
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptAddrAbortHndlr:
SUB LR, LR, #8 @ LR offset to return from this exception: -8
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptIrqHndlr:
SUB LR, LR, #4 @ LR offset to return from this exception: -4
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptFiqHndlr:
SUB LR, LR, #4 @ LR offset to return from this exception: -4
STMFD SP!, {R0-R12, LR} @ Push working registers
MOV R3, 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
@********************************************************************************************************
OS_CPU_ARM_ExceptHndlr:
MRS R1, SPSR @ Save CPSR (i.e. exception's SPSR)
@ DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION
@ SPSR.Mode = FIQ, IRQ, SVC, ABT, UND : Other exception
@ SPSR.Mode = SYS : Task
@ SPSR.Mode = USR : *unsupported state*
AND R2, R1, #OS_CPU_ARM_MODE_MASK
CMP R2, #OS_CPU_ARM_MODE_SYS
BNE OS_CPU_ARM_ExceptHndlr_BreakExcept
@********************************************************************************************************
@ EXCEPTION HANDLER: TASK INTERRUPTED
@********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakTask:
MRS R2, CPSR @ Save exception's CPSR
MOV R4, SP @ Save exception's stack pointer
@ Change to SYS mode & disable interruptions
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
@ SAVE TASK'S CONTEXT ONTO TASK'S STACK
STMFD SP!, {R3} @ Push task's PC
STMFD SP!, {LR} @ Push task's LR
STMFD SP!, {R5-R12} @ Push task's R12-R5
LDMFD R4!, {R5-R9} @ Move task's R4-R0 from exception stack to task's stack
STMFD SP!, {R5-R9}
TST R3, #1 @ See if called from Thumb mode
ORRNE R1, R1, #OS_CPU_ARM_CONTROL_THUMB @ If yes, Set the T-bit
STMFD SP!, {R1} @ Push task's CPSR (i.e. exception SPSR)
@ if (OSRunning == 1)
LDR R1, =OSRunning
LDRB R1, [R1]
CMP R1, #1
BNE OS_CPU_ARM_ExceptHndlr_BreakTask_1
@ HANDLE NESTING COUNTER
LDR R3, =OSIntNesting @ OSIntNesting++;
LDRB R4, [R3]
ADD R4, R4, #1
STRB R4, [R3]
LDR R3, =OSTCBCur @ OSTCBCur->OSTCBStkPtr = SP;
LDR R4, [R3]
STR SP, [R4]
OS_CPU_ARM_ExceptHndlr_BreakTask_1:
MSR CPSR_cxsf, R2 @ RESTORE INTERRUPTED MODE
LDR R1, =OS_CPU_ExceptHndlr @ OS_CPU_ExceptHndlr();
MOV LR, PC
BX R1
@ Adjust exception stack pointer. This is needed because
@ exception stack is not used when restoring task context.
ADD SP, SP, #(14*4)
@ Change to SYS mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
@ Call OSIntExit(). This call MAY never return
@ if a ready task with higher priority than
@ the interrupted one is found.
LDR R0, =OSIntExit
MOV LR, PC
BX R0
@ RESTORE NEW TASK'S CONTEXT
LDMFD SP!, {R0} @ Pop new task's CPSR
MSR CPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC} @ Pop new task's context
@********************************************************************************************************
@ EXCEPTION HANDLER: EXCEPTION INTERRUPTED
@********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakExcept:
MRS R2, CPSR @ Save exception's CPSR
@ Change to SYS mode & disable interruptions
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
@ HANDLE NESTING COUNTER
LDR R3, =OSIntNesting @ OSIntNesting++;
LDRB R4, [R3]
ADD R4, R4, #1
STRB R4, [R3]
MSR CPSR_cxsf, R2 @ RESTORE INTERRUPTED MODE
LDR R3, =OS_CPU_ExceptHndlr @ OS_CPU_ExceptHndlr();
MOV LR, PC
BX R3
@ Change to SYS mode & disable interruptions
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)
@ HANDLE NESTING COUNTER
LDR R3, =OSIntNesting @ OSIntNesting--;
LDRB R4, [R3]
SUB R4, R4, #1
STRB R4, [R3]
MSR CPSR_cxsf, R2 @ RESTORE INTERRUPTED MODE
LDMFD SP!, {R0-R12, PC}^ @ Pull working registers and return from exception.
.ltorg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -