ATMEL精妙的IRQ中断处理过程

本文详细解析了AT91SAM7S64微控制器中中断栈的分配原理及其内部机制,包括不同类型的中断栈大小计算、中断嵌套的支持方式等,并通过具体的代码示例展示了中断服务程序的执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A: 从栈地址开始,栈顶为AT91SAM7S64的16K片内RAM尽头0x00204000
IRQ_STACK_SIZE = 3*8*4
FIQ_STACK_SIZE = 0x004
ABT_STACK_SIZE = 0x004
UND_STACK_SIZE = 0x004
SVC_STACK_SIZE = 0x800
SYS_STACK_SIZE = 0x400

irq栈为什么用3*8*4=96B呢?因为irq最多8级嵌套,ARM字长4B,而3,是由于每次进栈均破坏了3个寄存器r0、spsr、lr,所以需要压栈保存的也就是3。计算十分精准,没有一个字浪费,这是AT第一牛X的地方。

当irq发生时,下列操作处理器自动完成:
1。r14(irq)=返回地址
2。spsr(irq)=cpsr(中断发生前的模式)
3。改cpsr,成模式为irq,禁止irq中断。
4。设pc,跳转到0x00000018去

下面看中断0x00000018指向的irq_handle代码:

;因为要继续调用函数,lr会被冲掉,所以压irq栈
sub lr,lr,#4
stmfd sp!,{lr}

;将r0和spsr压irq栈,因为下面用到r0,spsr
mrs r14,spsr
stmfd sp!,{r0,r14}

;写IVR,支持保护模式,普通模式无效
;释放NIRQ,清除保护模式下中断源
ldr r14,=AT91C_BASE_AIC
ldr r0,[r14,#AIC_IVR]
str r14,[r14, #AIC_IVR]

;允许中断嵌套,由irq模式切换入svc模式
msr cpsr_c, #ARM_MODE_SVC

;保存scratch和被使用到的寄存器、lr入svc堆栈
stmfd sp!, {r1-r3, r12, r14}

;跳转到AIC_IVR指向的中断服务程序地址
mov r14,pc
bx r0

;恢复scratch、被用到的寄存器、lr
ldmia sp!,{r1-r3, r12, r14}

;禁止irq中断嵌套,由svc切换到irq模式。
msr cpsr_c,#I_BIT | ARM_MODE_IRQ

;写AIC_EOICR
ldr r14,=AT91C_BASE_AIC
str r14,[r14, #AIC_EOICR]

;恢复spsr、r0
ldmia sp!,{r0, r14}
msr spsr_cxsf, r14

;中断返回
ldmia sp!, {pc}^

以上就是全部,让我惊叹的是如上做法支持了中断嵌套,想了想,自己以前搞的东西还真是全部回避回去了,也就是说,以前各个中断并没有优先级区分,进了中断就关门i->I。中断服务程序执行完了再打开,优点是简单明了,缺点是中断服务程序必须迅速处理完.

转载于:https://www.cnblogs.com/shangdawei/p/4538994.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值