📄 os_cpu_a.s
字号:
STR R6, [R4]
LDR SP, [R6] @ SP = OSTCBHighRdy->OSTCBStkPtr;
@ RESTORE NEW TASK'S CONTEXT
LDR R4, [SP], #4 @ pop new task's CPSR
MSR CPSR_cxsf, R4
LDR R0, [SP], #4 @ pop new task's context
LDR R1, [SP], #4
LDR R2, [SP], #4
LDR R3, [SP], #4
LDR R4, [SP], #4
LDR R5, [SP], #4
LDR R6, [SP], #4
LDR R7, [SP], #4
LDR R8, [SP], #4
LDR R9, [SP], #4
LDR R10, [SP], #4
LDR R11, [SP], #4
LDR R12, [SP], #4
LDR LR, [SP], #4
LDR PC, [SP], #4
.endfunc
@*********************************************************************************************************
@ PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
@
@ Note(s) : 1) OSIntCtxSw() is called in SYS 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
@*********************************************************************************************************
.text
.arm
.align 2
.func OSIntCtxSw
OSIntCtxSw:
BL OSTaskSwHook @ OSTaskSwHook();
LDR R4,OS_PrioCur_Addr @ OSPrioCur = OSPrioHighRdy
LDR R5,OS_PrioHighRdy_Addr
LDRB R6,[R5]
STRB R6,[R4]
LDR R4,OS_TCBCur_Addr @ OSTCBCur = OSTCBHighRdy;
LDR R6,OS_TCBHighRdy_Addr
LDR R6,[R6]
STR R6,[R4]
LDR SP,[R6] @ SP = OSTCBHighRdy->OSTCBStkPtr;
@ RESTORE NEW TASK'S CONTEXT
LDR R4, [SP], #4 @ pop new task's CPSR
MSR CPSR_cxsf, R4
LDR R0, [SP], #4 @ pop new task's context
LDR R1, [SP], #4
LDR R2, [SP], #4
LDR R3, [SP], #4
LDR R4, [SP], #4
LDR R5, [SP], #4
LDR R6, [SP], #4
LDR R7, [SP], #4
LDR R8, [SP], #4
LDR R9, [SP], #4
LDR R10, [SP], #4
LDR R11, [SP], #4
LDR R12, [SP], #4
LDR LR, [SP], #4
LDR PC, [SP], #4
.endfunc
@*********************************************************************************************************
@ IRQ Interrupt Service Routine
@*********************************************************************************************************
.text
.arm
.align 2
.func OS_CPU_IRQ_ISR
OS_CPU_IRQ_ISR:
STR R3, [SP, #-4]! @ PUSH WORKING REGISTERS ONTO IRQ STACK
STR R2, [SP, #-4]!
STR R1, [SP, #-4]!
MOV R1, SP @ Save IRQ stack pointer
ADD SP, SP,#12 @ Adjust IRQ stack pointer
SUB R2, LR,#4 @ Adjust PC for return address to task
MRS R3, SPSR @ Copy SPSR (i.e. interrupted task's CPSR) to R3
MSR CPSR_c, #Mode_SYS|I_Bit|F_Bit @ Change to SYS mode
@ SAVE TASK'S CONTEXT ONTO TASK'S STACK
STR R2, [SP, #-4]! @ Push task's Return PC
STR LR, [SP, #-4]! @ Push task's LR
STR R12, [SP, #-4]! @ Push task's R12-R4
STR R11, [SP, #-4]!
STR R10, [SP, #-4]!
STR R9, [SP, #-4]!
STR R8, [SP, #-4]!
STR R7, [SP, #-4]!
STR R6, [SP, #-4]!
STR R5, [SP, #-4]!
STR R4, [SP, #-4]!
LDR R4, [R1], #4 @ Move task's R1-R3 from IRQ stack to SYS stack
LDR R5, [R1], #4
LDR R6, [R1], #4
STR R6, [SP, #-4]!
STR R5, [SP, #-4]!
STR R4, [SP, #-4]!
STR R0, [SP, #-4]! @ Push task's R0 onto task's stack
STR R3, [SP, #-4]! @ Push task's CPSR (i.e. IRQ's SPSR)
@ HANDLE NESTING COUNTER
LDR R0, OS_IntNesting_Addr @ OSIntNesting++;
LDRB R1, [R0]
ADD R1, R1,#1
STRB R1, [R0]
CMP R1, #1 @ if (OSIntNesting == 1) {
BNE OS_CPU_IRQ_ISR_1
LDR R4, OS_TCBCur_Addr @ OSTCBCur->OSTCBStkPtr = SP
LDR R5, [R4]
STR SP, [R5] @ }
OS_CPU_IRQ_ISR_1:
MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit @ Change to IRQ mode (to use the IRQ stack to handle interrupt)
BL OS_CPU_IRQ_ISR_Handler @ OS_CPU_IRQ_ISR_Handler();
MSR CPSR_c, #Mode_SYS|I_Bit|F_Bit @ Change to SYS mode
BL OSIntExit @ OSIntExit();
@ RESTORE TASK'S CONTEXT and RETURN TO TASK
LDR R4, [SP], #4 @ pop new task's CPSR
MSR CPSR_cxsf, R4
LDR R0, [SP], #4 @ pop new task's context
LDR R1, [SP], #4
LDR R2, [SP], #4
LDR R3, [SP], #4
LDR R4, [SP], #4
LDR R5, [SP], #4
LDR R6, [SP], #4
LDR R7, [SP], #4
LDR R8, [SP], #4
LDR R9, [SP], #4
LDR R10, [SP], #4
LDR R11, [SP], #4
LDR R12, [SP], #4
LDR LR, [SP], #4
LDR PC, [SP], #4
.endfunc
@*********************************************************************************************************
@ FIQ Interrupt Service Routine
@*********************************************************************************************************
.text
.arm
.align 2
.func OS_CPU_FIQ_ISR
OS_CPU_FIQ_ISR:
STMFD SP!,{R1-R3} @ PUSH WORKING REGISTERS ONTO IRQ STACK
MOV R1,SP @ Save IRQ stack pointer
ADD SP,SP,#12 @ Adjust FIQ stack pointer
SUB R2,LR,#4 @ Adjust PC for return address to task
MRS R3,SPSR @ Copy SPSR (i.e. interrupted task's CPSR) to R3
MSR CPSR_c,#Mode_SYS|I_Bit|F_Bit @ Change to SYS mode
@ SAVE TASK'S CONTEXT ONTO TASK'S STACK
STMFD SP!,{R2} @ Push task's Return PC
STMFD SP!,{R4-R12,LR} @ Push task's LR,R12-R4
LDMFD R1!,{R4-R6} @ Move task's R1-R3 from IRQ stack to SYS stack
STMFD SP!,{R4-R6}
STMFD SP!,{R0} @ Push task's R0 onto task's stack
STMFD SP!,{R3} @ Push task's CPSR (i.e. IRQ's SPSR)
@ HANDLE NESTING COUNTER
LDR R0,OS_IntNesting_Addr @ OSIntNesting++;
LDRB R1,[R0]
ADD R1,R1,#1
STRB R1,[R0]
CMP R1,#1 @ if (OSIntNesting == 1) {
BNE OS_CPU_FIQ_ISR_1
LDR R4,OS_TCBCur_Addr @ OSTCBCur->OSTCBStkPtr = SP
LDR R5,[R4]
STR SP,[R5] @ }
OS_CPU_FIQ_ISR_1:
MSR CPSR_c,#Mode_FIQ|I_Bit|F_Bit @ Change to FIQ mode (to use the FIQ stack to handle interrupt)
BL OS_CPU_FIQ_ISR_Handler @ OS_CPU_FIQ_ISR_Handler();
MSR CPSR_c,#Mode_SYS|I_Bit|F_Bit @ Change to SYS mode
BL OSIntExit @ OSIntExit();
@ RESTORE TASK'S CONTEXT and RETURN TO TASK
LDMFD SP!,{R4} @ pop new task's CPSR
MSR CPSR_cxsf,r4
LDMFD SP!,{R0-R12,LR,PC} @ pop new task's R0-R12,LR & PC
.endfunc
@*********************************************************************************************************
@ POINTERS TO VARIABLES
@*********************************************************************************************************
OS_IntNesting_Addr: .word OSIntNesting
OS_PrioCur_Addr: .word OSPrioCur
OS_PrioHighRdy_Addr: .word OSPrioHighRdy
OS_Running_Addr: .word OSRunning
OS_TCBCur_Addr: .word OSTCBCur
OS_TCBHighRdy_Addr: .word OSTCBHighRdy
.end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -