中断处理流程

xiaoxiao2025-09-02  14

以s3c2440为例讲述,中断处理流程:

1.开中断。产生外部中断。流程如下按键----->中断控制器------->cpu(总开关)

* 按键:

需要设置GPIO为中断模式,上升沿还是下降沿触发。

* 中断控制器:

* cpu:

2.中断处理

* 跳转到中断向量表。如果从nandflash启动,代码已经重定位到sdram,此时候是绝对跳转,会跳转的真正的0地址(sram)。

中断向量表如下:

*    硬件操作      a. lr_irq保存有被中断模式中的下一条即将执行的指令的地址      b. SPSR_irq保存有被中断模式的CPSR      c. CPSR中的M4-M0被设置为10010, 进入到irq模式      d. 跳到0x18的地方执行程序 

*软件操作

a. 设置sp_irq栈,这个是irq模式的sp,sp_user不用了,两个是独立的sp,所以需要重新设置。

b.保存现场     /* 在irq异常处理函数中有可能会修改r0-r12, 所以先保存 */     /* lr-4是异常处理完后的返回地址, 也要保存 */ 方便最后pc =lr,可以从异常模式跳转到用户模式

c.处理irq异常 

跳转到中断处理函数

d.恢复现场。

代码如下:

中断向量表:

.text .global _start _start: b reset /* vector 0 : reset */ ldr pc, und_addr /* vector 4 : und */ ldr pc, swi_addr /* vector 8 : swi */ b halt /* vector 0x0c : prefetch aboot */ b halt /* vector 0x10 : data abort */ b halt /* vector 0x14 : reserved */ ldr pc, irq_addr /* vector 0x18 : irq */ b halt /* vector 0x1c : fiq */ und_addr: .word do_und swi_addr: .word do_swi irq_addr: .word do_irq

中断处理及跳转:

.align 4 do_irq: /* 执行到这里之前: * 1. lr_irq保存有被中断模式中的下一条即将执行的指令的地址 * 2. SPSR_irq保存有被中断模式的CPSR * 3. CPSR中的M4-M0被设置为10010, 进入到irq模式 * 4. 跳到0x18的地方执行程序 */ /* sp_irq未设置, 先设置它 */ ldr sp, =0x33d00000 /* 保存现场 */ /* 在irq异常处理函数中有可能会修改r0-r12, 所以先保存 */ /* lr-4是异常处理完后的返回地址, 也要保存 */ sub lr, lr, #4 stmdb sp!, {r0-r12, lr} /* 处理irq异常 */ bl handle_irq_c /* 恢复现场 */ ldmia sp!, {r0-r12, pc}^ /* ^会把spsr_irq的值恢复到cpsr里 */

中断处理函数:

void handle_irq_c(void) { /* 分辨中断源 */ int bit = INTOFFSET; /* 调用对应的处理函数 */ irq_array[bit](bit); //函数指针数组, /* 清中断 : 从源头开始清 */ SRCPND = (1<<bit); INTPND = (1<<bit); }

 

 

 

转载请注明原文地址: https://www.6miu.com/read-5035649.html

最新回复(0)