📄 os_cpu_a.s
字号:
@********************************************************************************************************
@ 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
BNE OS_CPU_ARM_ExceptHndlr_BreakNothing
@ HANDLE NESTING COUNTER:
LDR R3, =OS_IntNesting @ OSIntNesting++;
LDRB R4, [R3]
ADD R4, R4, #1
STRB R4, [R3]
CMP R4, #1 @ if (OSIntNesting == 1)
BNE OS_CPU_ARM_ExceptHndlr_BreakExcept
@********************************************************************************************************
@ EXCEPTION HANDLER: TASK INTERRUPTED
@
@ Register Usage: R0 Exception Type
@ R1
@ R2
@ R3
@********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakTask:
LDR R3, =OS_TCBCur @ OSTCBCur->OSTCBStkPtr = SP;
LDR R4, [R3]
STR SP, [R4]
LDR R3, =OS_CPU_ExceptStkBase @ Switch to exception stack.
LDR SP, [R3]
@ EXECUTE EXCEPTION HANDLER:
LDR R1, =OS_CPU_ExceptHndlr @ OS_CPU_ExceptHndlr(except_type = R0)
MOV LR, PC
BX R1
@ Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
@ Call OSIntExit(). This call MAY never return if a ready
@ task with higher priority than the interrupted one is
@ found.
LDR R0, =OS_IntExit
MOV LR, PC
BX R0
LDR R3, =OS_TCBCur @ SP = OSTCBCur->OSTCBStkPtr;
LDR R4, [R3]
LDR SP, [R4]
@ 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.
@********************************************************************************************************
@ EXCEPTION HANDLER: EXCEPTION INTERRUPTED
@
@ Register Usage: R0 Exception Type
@ R1
@ R2
@ R3
@********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakExcept:
LDR R3, =OS_CPU_ExceptStkPtr @ OS_CPU_ExceptStkPtr = SP;
STR SP, [R3]
@ EXECUTE EXCEPTION HANDLER:
LDR R3, =OS_CPU_ExceptHndlr @ OS_CPU_ExceptHndlr(except_type = R0)
MOV LR, PC
BX R3
@ Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
@ HANDLE NESTING COUNTER:
LDR R3, =OS_IntNesting @ OSIntNesting--;
LDRB R4, [R3]
SUB R4, R4, #1
STRB R4, [R3]
@ RESTORE OLD CONTEXT:
LDMFD SP!, {R0} @ Pop old CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ @ Pull working registers and return from exception.
@********************************************************************************************************
@ EXCEPTION HANDLER: 'NOTHING' INTERRUPTED
@
@ Register Usage: R0 Exception Type
@ R1
@ R2
@ R3
@********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakNothing:
@ EXECUTE EXCEPTION HANDLER:
LDR R3, =OS_CPU_ExceptHndlr @ OS_CPU_ExceptHndlr(except_type = R0)
MOV LR, PC
BX R3
@ Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
@ RESTORE OLD CONTEXT:
LDMFD SP!, {R0} @ Pop old CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ @ Pull working registers and return from exception.
@********************************************************************************************************
@ ENABLE & DISABLE INTERRUPTS
@
@ Note(s) : 1) OS_CPU_SR_INT_En() can be called by OS_CPU_ExceptHndlr() AFTER the external
@ interrupt source has been cleared. This function will enable IRQs and FIQs so that
@ nesting can occur.
@
@ 2) OS_CPU_ARM_INT_Dis() can be called to disable IRQs and FIQs so that nesting will not occur.
@********************************************************************************************************
OS_CPU_SR_INT_En:
MRS R0, CPSR
BIC R0, R0, #OS_CPU_ARM_CONTROL_INT_DIS @ Clear IRQ and FIQ bits in CPSR to enable all interrupts.
MSR CPSR_c, R0
BX LR
OS_CPU_SR_INT_Dis:
MRS R0, CPSR
ORR R0, R0, #OS_CPU_ARM_CONTROL_INT_DIS @ Set IRQ and FIQ bits in CPSR to disable all interrupts.
MSR CPSR_c, R0
BX LR
@********************************************************************************************************
@ ENABLE & DISABLE IRQs
@
@ Note(s) : 1) OS_CPU_SR_IRQ_En() can be called by OS_CPU_ExceptHndlr() AFTER the external
@ interrupt source has been cleared. This function will enable IRQs so that IRQ nesting
@ can occur.
@
@ 2) OS_CPU_ARM_IRQ_Dis() can be called to disable IRQs so that IRQ nesting will not occur.
@********************************************************************************************************
OS_CPU_SR_IRQ_En:
MRS R0, CPSR
BIC R0, R0, #OS_CPU_ARM_CONTROL_IRQ_DIS @ Clear IRQ bit in CPSR to enable IRQs.
MSR CPSR_c, R0
BX LR
OS_CPU_SR_IRQ_Dis:
MRS R0, CPSR
ORR R0, R0, #OS_CPU_ARM_CONTROL_IRQ_DIS @ Set IRQ bit in CPSR to disable IRQs.
MSR CPSR_c, R0
BX LR
@********************************************************************************************************
@ ENABLE & DISABLE FIQs
@
@ Note(s) : 1) OS_CPU_SR_FIQ_En() can be called by OS_CPU_ExceptHndlr() AFTER the external
@ interrupt source has been cleared. This function will enable FIQs so that FIQ nesting
@ can occur.
@
@ 2) OS_CPU_ARM_FIQ_Dis() can be called to disable FIQs so that FIQ nesting will not occur.
@********************************************************************************************************
OS_CPU_SR_FIQ_En:
MRS R0, CPSR
BIC R0, R0, #OS_CPU_ARM_CONTROL_FIQ_DIS @ Clear FIQ bit in CPSR to enable FIQs.
MSR CPSR_c, R0
BX LR
OS_CPU_SR_FIQ_Dis:
MRS R0, CPSR
ORR R0, R0, #OS_CPU_ARM_CONTROL_FIQ_DIS @ Set FIQ bit in CPSR to disable FIQs.
MSR CPSR_c, R0
BX LR
.ltorg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -