ARM体系结构与编程学习(十三)
2011-05-01 18:55
393 查看
9.5 FIQ与IRQ异常中断处理程序
arm提供的FIQ与IRQ用于外部设备向CPU请求中断。
9.5.1 不可重入的IRQ/FIQ异常中断处理程序
;使用关键词_irq
__irq void IRQHandler (void)
{
volatile unsigned int *base = (unsigned int *) 0x80000000;
if (*base == 1) // which interrupt was it?
{
C_int_handler(); // process the interrupt
}
*(base+1) = 0; // clear the interrupt
}
;对应的汇编程序
IRQHandler PROC
STMFD sp!,{r0-r4,r12,lr}
MOV r4,#0x80000000
LDR r0,[r4,#0]
SUB sp,sp,#4
CMP r0,#1
BLEQ C_int_handler
MOV r0,#0
STR r0,[r4,#4]
ADD sp,sp,#4
LDMFD sp!,{r0-r4,r12,lr}
SUBS pc,lr,#4
ENDP
;不使用关键词_irq
void IRQHandler (void)
{
volatile unsigned int *base = (unsigned int *) 0x80000000;
if (*base == 1) // which interrupt was it?
{
C_int_handler(); // process the interrupt
}
*(base+1) = 0; // clear the interrupt
}
;对应的汇编程序
IRQHandler PROC
STMFD sp!,{r4,lr}
MOV r4,#0x80000000
LDR r0,[r4,#0]
CMP r0,#1
BLEQ C_int_handler
MOV r0,#0
STR r0,[r4,#4]
LDMFD sp!,{r4,pc}
END
可重入的IRQ/FIQ异常中断处理程序
1、将返回地址保存到IRQ的数据栈中
2、保存工作寄存器和SPSR_irq
3、清除中断标志位
4、将处理器切换到系统模式,重新使能IRQ/FIQ中断
5、保存用户模式的LR寄存器和被调用程序不保存的寄存器
6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ
7、切换到IRQ模式,禁止中断
8、恢复工作组寄存器和寄存器LR_irq
9、从IRQ异常中断处理程序中返回
PRESERVE8
AREA INTERRUPT, CODE, READONLY
IMPORT C_irq_handler
IRQ
SUB lr, lr, #4 ; construct the return address
STMFD sp!, {lr} ; and push the adjusted lr_IRQ
MRS r14, SPSR ; copy spsr_IRQ to r14
STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ
; Add instructions to clear the interrupt here
; then re-enable interrupts.
MSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
; enabled. USR mode registers
; are now current.
STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee
; saved registers
BL C_irq_handler ; branch to C IRQ handler.
LDMFD sp!, {r0-r3, lr} ; restore registers
MSR CPSR_c, #0x92 ; switch to IRQ mode and disable
; IRQs. FIQ is still enabled.
LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ
MSR SPSR_cf, r14
LDMFD sp!, {pc}^ ; return from IRQ.
END
9.5.2 IRQ异常中断处理程序例程
;保存返回地址
SUB LR,LR #4
STMFD SP!,{LR}
;保存SPSR及工作组寄存器R12
MRS R14,SPSR
STMFD SP!,{R12,R14}
;读取中断控制器的基地址
MOV R12 , #IntBase
;读取优先级最高的中断源的优先级
LDR R12 ,[R12,#IntLevel]
;使能中断
MRS R14,CPSR
BIC R14,R14,#0X80
MSR CPSR_c ,R14
;跳转到优先级最高的中断对应的中断处理程序
LDR PC, [PC,R12,LSR #2]
;加入一条NOP指令,实现跳转表的地址计算方法
NOP
;中断处理程序地址表
;优先级为0的中断对应的中断处理程序地址
DCD Priority0Handler
;优先级为1的中断对应的中断处理程序地址
DCD Priority1Handler
;优先级为2的中断对应的中断处理程序地址
DCD Priority2Handler
;优先级为0的中断对应的中断处理程序
Priority0Handler
;保存工作寄存器
STMFD SP!,[R0-R11]
;这里为中断处理程序的程序体
;...
;恢复工作寄存器
LDMFD SP! ,{R0-R11}
;禁止中断
MRS R12,CPSR
ORR R12,R12
MSR CPSR_c, R12
;恢复SPSR和寄存器R12
LDMFD SP!, {R12,R14}
MSR SPSR_csxf, R14
;从优先级为0的中断程序返回
LDMFD SP!, {PC}^
;优先级为1的中断对应的中断处理程序地址
Priority1Handler
;...
arm提供的FIQ与IRQ用于外部设备向CPU请求中断。
9.5.1 不可重入的IRQ/FIQ异常中断处理程序
;使用关键词_irq
__irq void IRQHandler (void)
{
volatile unsigned int *base = (unsigned int *) 0x80000000;
if (*base == 1) // which interrupt was it?
{
C_int_handler(); // process the interrupt
}
*(base+1) = 0; // clear the interrupt
}
;对应的汇编程序
IRQHandler PROC
STMFD sp!,{r0-r4,r12,lr}
MOV r4,#0x80000000
LDR r0,[r4,#0]
SUB sp,sp,#4
CMP r0,#1
BLEQ C_int_handler
MOV r0,#0
STR r0,[r4,#4]
ADD sp,sp,#4
LDMFD sp!,{r0-r4,r12,lr}
SUBS pc,lr,#4
ENDP
;不使用关键词_irq
void IRQHandler (void)
{
volatile unsigned int *base = (unsigned int *) 0x80000000;
if (*base == 1) // which interrupt was it?
{
C_int_handler(); // process the interrupt
}
*(base+1) = 0; // clear the interrupt
}
;对应的汇编程序
IRQHandler PROC
STMFD sp!,{r4,lr}
MOV r4,#0x80000000
LDR r0,[r4,#0]
CMP r0,#1
BLEQ C_int_handler
MOV r0,#0
STR r0,[r4,#4]
LDMFD sp!,{r4,pc}
END
可重入的IRQ/FIQ异常中断处理程序
1、将返回地址保存到IRQ的数据栈中
2、保存工作寄存器和SPSR_irq
3、清除中断标志位
4、将处理器切换到系统模式,重新使能IRQ/FIQ中断
5、保存用户模式的LR寄存器和被调用程序不保存的寄存器
6、调用C语言的IRQ/FIQ异常中断处理程序返回,恢复用户模式的寄存器,并禁止IRQ/FIQ
7、切换到IRQ模式,禁止中断
8、恢复工作组寄存器和寄存器LR_irq
9、从IRQ异常中断处理程序中返回
PRESERVE8
AREA INTERRUPT, CODE, READONLY
IMPORT C_irq_handler
IRQ
SUB lr, lr, #4 ; construct the return address
STMFD sp!, {lr} ; and push the adjusted lr_IRQ
MRS r14, SPSR ; copy spsr_IRQ to r14
STMFD sp!, {r12, r14} ; save work regs and spsr_IRQ
; Add instructions to clear the interrupt here
; then re-enable interrupts.
MSR CPSR_c, #0x1F ; switch to SYS mode, FIQ and IRQ
; enabled. USR mode registers
; are now current.
STMFD sp!, {r0-r3, lr} ; save lr_USR and non-callee
; saved registers
BL C_irq_handler ; branch to C IRQ handler.
LDMFD sp!, {r0-r3, lr} ; restore registers
MSR CPSR_c, #0x92 ; switch to IRQ mode and disable
; IRQs. FIQ is still enabled.
LDMFD sp!, {r12, r14} ; restore work regs and spsr_IRQ
MSR SPSR_cf, r14
LDMFD sp!, {pc}^ ; return from IRQ.
END
9.5.2 IRQ异常中断处理程序例程
;保存返回地址
SUB LR,LR #4
STMFD SP!,{LR}
;保存SPSR及工作组寄存器R12
MRS R14,SPSR
STMFD SP!,{R12,R14}
;读取中断控制器的基地址
MOV R12 , #IntBase
;读取优先级最高的中断源的优先级
LDR R12 ,[R12,#IntLevel]
;使能中断
MRS R14,CPSR
BIC R14,R14,#0X80
MSR CPSR_c ,R14
;跳转到优先级最高的中断对应的中断处理程序
LDR PC, [PC,R12,LSR #2]
;加入一条NOP指令,实现跳转表的地址计算方法
NOP
;中断处理程序地址表
;优先级为0的中断对应的中断处理程序地址
DCD Priority0Handler
;优先级为1的中断对应的中断处理程序地址
DCD Priority1Handler
;优先级为2的中断对应的中断处理程序地址
DCD Priority2Handler
;优先级为0的中断对应的中断处理程序
Priority0Handler
;保存工作寄存器
STMFD SP!,[R0-R11]
;这里为中断处理程序的程序体
;...
;恢复工作寄存器
LDMFD SP! ,{R0-R11}
;禁止中断
MRS R12,CPSR
ORR R12,R12
MSR CPSR_c, R12
;恢复SPSR和寄存器R12
LDMFD SP!, {R12,R14}
MSR SPSR_csxf, R14
;从优先级为0的中断程序返回
LDMFD SP!, {PC}^
;优先级为1的中断对应的中断处理程序地址
Priority1Handler
;...
相关文章推荐
- ARM体系结构与编程学习(九)
- ARM体系结构与编程学习(十一)
- ARM体系结构与编程学习(二)
- ARM体系结构与编程学习(十二)
- ARM体系结构与编程学习(十)
- ARM体系结构与编程学习(五)
- ARM体系结构与编程学习(四)
- ARM体系结构与编程学习(九)
- ARM体系结构与编程学习(一)
- ARM体系结构与编程学习(五)
- ARM体系结构与编程学习(六)
- ARM体系结构与编程学习(十一)
- ARM体系结构与编程学习(八)
- ARM&LINUX学习笔记(4)---ARM 体系结构
- ARM底层学习笔记-中断体系结构
- ARM学习之中断体系结构
- ARM的体系结构与编程系列博客——ARM处理器系列介绍
- ARM学习笔记--中断体系结构
- ARM的体系结构与编程系列博客——ARM的历史与应用范围
- ARM体系结构学习中的难点(不断更新中)