📄 irq.inc
字号:
ARM_MODE_USER EQU 0x10
ARM_MODE_FIQ EQU 0x11
ARM_MODE_IRQ EQU 0x12
ARM_MODE_SVC EQU 0x13
ARM_MODE_ABORT EQU 0x17
ARM_MODE_UNDEF EQU 0x1B
ARM_MODE_SYS EQU 0x1F
I_BIT EQU 0x80
F_BIT EQU 0x40
T_BIT EQU 0x20
;External references
EXTERN OSPrioCur
EXTERN OSPrioHighRdy
EXTERN OSIntNesting
EXTERN OSIntExit
EXTERN OSIntCtxSw
MACRO
$IRQ_Label HANDLER $IRQ_Exception_Function
EXPORT $IRQ_Label ; 输出的标号
IMPORT $IRQ_Exception_Function ; 引用的外部标号
$IRQ_Label
SUB LR, LR, #4 ;- Adjust and save LR_irq in IRQ stack
STMFD SP!, {R0-R3, R11, R12, LR} ;- Save scratch/used registers and LR in IRQ Stack
;- #Save R11 only for the register 'LR_svc'
MRS R14, SPSR ;- Save SPSR need to be saved for nested interrupt
STMFD SP!, {R14}
LDR R11, =OSIntNesting ; OSIntNesting++;
LDRB R12, [R11]
ADD R12, R12,#1
STRB R12, [R11]
MSR CPSR_c, #ARM_MODE_SVC ; - Enable Interrupt and Switch to SVC mode
MOV R11, LR ; R11<-LR_svc
BL $IRQ_Exception_Function ; 调用c语言的中断处理程序
MOV LR, R11 ;- Restore LR_svc
MSR CPSR_c, #(I_BIT | F_BIT | ARM_MODE_IRQ) ;- Disable Interrupt and Switch back in IRQ mode
BL OSIntExit ; OSIntExit() <not call OSIntCtxSw()>
LDR R0, =OSPrioCur ; if (OSPrioCur != OSPrioHighRdy)
LDR R1, =OSPrioHighRdy
LDRB R0, [R0]
LDRB R1, [R1]
CMP R0, R1
BNE OSIntCtxSw ; Do OSIntCtxSw()
LDMFD SP!, {R14} ;- Restore SPSR_irq from IRQ stack
MSR SPSR_cxsf, R14
LDMFD SP!, {R0-R3, R11, R12, PC}^ ;- Restore adjusted LR_irq from IRQ stack directly in the PC
MEND
END
;/********************************************************************************************************
;** End Of File
;********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -