📄 os_cpu_a.s
字号:
MOVS PC,R0 ; Restore PC and CPSR
; SAVE OLD TASKS CONTEXT ONTO OLD TASKS STACK
STMFD SP!,{R2} ; Push tasks PC
STMFD SP!,{R4-R12,LR} ; Push tasks LR,R12-R4
MOV R4,R1 ; Move R0-R3 from IRQ stack to SVC stack
MOV R5,R3
LDMFD R4!,{R0-R3} ; Load R0-R3 from IRQ stack
STMFD SP!,{R0-R3} ; Push R0-R3
STMFD SP!,{R5} ; Push tasks CPSR
MRS R4,SPSR
STMFD SP!,{R4} ; Push tasks SPSR
LDR R4,=OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP
LDR R5,[R4]
STR SP,[R5]
BL OSTaskSwHook ; call Task Switch Hook
LDR R4,=OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR R5,=OSPrioHighRdy
LDRB R6,[R5]
STRB R6,[R4]
LDR R4,=OSTCBCur ; OSTCBCur = OSTCBHighRdy
LDR R6,=OSTCBHighRdy
LDR R6,[R6]
LDR SP,[R6]
STR R6,[R4]
LDMFD SP!,{R4} ; pop new task's SPSR
MSR SPSR_cxsf,R4
LDMFD SP!,{R4} ; pop new task's PSR
MSR CPSR_cxsf,R4
;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
LDR r14, =AT91C_BASE_AIC
STR r14, [r14, #AIC_IVR]
;- 读取定时器状态寄存器
LDR r12,=AT91C_BASE_TC0
LDR r12,[r12, #TC_SR]
;- Mark the End of Interrupt on the AIC
LDR r12, =AT91C_BASE_AIC
STR r12, [r12, #AIC_EOICR]
LDMFD SP!,{R0-R12,LR,PC} ; pop new tasks R0-R12,LR & PC
TC_OSTickISR
STMFD SP!,{R0-R3,R12,LR}
BL OSIntEnter
BL OSTimeTick
BL OSIntExit
LDR R0, =OSIntCtxSwFlag
LDR R1, [R0]
CMP R1, #1
BEQ TC_OS_IntCtxSw
;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
LDR r14, =AT91C_BASE_AIC
STR r14, [r14, #AIC_IVR]
;- 读取定时器状态寄存器
LDR r12,=AT91C_BASE_TC0
LDR r12,[r12, #TC_SR]
;- Mark the End of Interrupt on the AIC
LDR r12, =AT91C_BASE_AIC
STR r12, [r12, #AIC_EOICR]
LDMFD SP!, {R0-R3, R12, LR}
SUBS PC, LR, #4
PIT_OS_IntCtxSw
LDR R0,=OSIntCtxSwFlag ; OSIntCtxSwFlag = FALSE
MOV R1,#0
STR R1,[R0]
LDMFD SP!,{R0-R3,R12,LR} ; Clean up IRQ stack
STMFD SP!,{R0-R3} ; We will use R0-R3 as temporary registers
MOV R1,SP
ADD SP,SP,#16
SUB R2,LR,#4
MRS R3,SPSR ; Disable interrupts for when we go back to SVC mode
ORR R0,R3,#NO_INT
BIC R0,R0,#0x00000020 ;- 这一句很关键,是整个系统稳定运行的重要因素
MSR SPSR_c,R0 ;- c 控制域屏蔽字节(PSR[7:0])
;- x 扩展域屏蔽字节(PSR[15:8])
;- s 状态域屏蔽字节(PSR[23:16])
;- f 标志域屏蔽字节(PSR[31:24])
LDR R0,=.+8 ; Switch back to SVC mode (Code below, current location + 2 instructions)
MOVS PC,R0 ; Restore PC and CPSR
; SAVE OLD TASKS CONTEXT ONTO OLD TASKS STACK
STMFD SP!,{R2} ; Push tasks PC
STMFD SP!,{R4-R12,LR} ; Push tasks LR,R12-R4
MOV R4,R1 ; Move R0-R3 from IRQ stack to SVC stack
MOV R5,R3
LDMFD R4!,{R0-R3} ; Load R0-R3 from IRQ stack
STMFD SP!,{R0-R3} ; Push R0-R3
STMFD SP!,{R5} ; Push tasks CPSR
MRS R4,SPSR
STMFD SP!,{R4} ; Push tasks SPSR
LDR R4,=OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP
LDR R5,[R4]
STR SP,[R5]
BL OSTaskSwHook ; call Task Switch Hook
LDR R4,=OSPrioCur ; OSPrioCur = OSPrioHighRdy
LDR R5,=OSPrioHighRdy
LDRB R6,[R5]
STRB R6,[R4]
LDR R4,=OSTCBCur ; OSTCBCur = OSTCBHighRdy
LDR R6,=OSTCBHighRdy
LDR R6,[R6]
LDR SP,[R6]
STR R6,[R4]
LDMFD SP!,{R4} ; pop new task's SPSR
MSR SPSR_cxsf,R4
LDMFD SP!,{R4} ; pop new task's PSR
MSR CPSR_cxsf,R4
;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
LDR r14, =AT91C_BASE_AIC
STR r14, [r14, #AIC_IVR]
;- 读取PIT寄存器PIVR以确认中断
LDR r12,=AT91C_BASE_PITC
LDR r12,[r12, #PITC_PIVR]
;- Mark the End of Interrupt on the AIC
LDR r12, =AT91C_BASE_AIC
STR r12, [r12, #AIC_EOICR]
LDMFD SP!,{R0-R12,LR,PC} ; pop new tasks R0-R12,LR & PC
PIT_OSTickISR
STMFD SP!,{R0-R3,R12,LR}
BL OSIntEnter
BL OSTimeTick
BL Uart_Debug_ISR
BL OSIntExit
LDR R0, =OSIntCtxSwFlag
LDR R1, [R0]
CMP R1, #1
BEQ PIT_OS_IntCtxSw
;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
LDR r14, =AT91C_BASE_AIC
STR r14, [r14, #AIC_IVR]
;- 读取PIT寄存器PIVR以确认中断
LDR r12,=AT91C_BASE_PITC
LDR r12,[r12, #PITC_PIVR]
;- Mark the End of Interrupt on the AIC
LDR r12, =AT91C_BASE_AIC
STR r12, [r12, #AIC_EOICR]
LDMFD SP!, {R0-R3, R12, LR}
SUBS PC, LR, #4
;- 临界处理函数
ARMCoreDisableIntExt
MRS R0,CPSR ;- 将CPSR寄存器的值传送到参数寄存器R0中
__DisableInt
ORR R1,R0,#I_BIT:OR:F_BIT
MSR CPSR_c,R1 ;- 进行判断的目的是确认中断禁止操作已经成功后再开始临界处理
MRS R1,CPSR
AND R1,R1,#I_BIT:OR:F_BIT
CMP R1,#I_BIT:OR:F_BIT
BNE __DisableInt
BX LR ;- 返回调用函数并返回原来的CPSR值
ARMCoreRestoreIntStatus
MSR CPSR_c, R0
BX LR
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -