在具体的ARM芯片中会有很多的中断类型,每一种类型的中断用以上结构来表示:
struct irqdesc irq_desc[NR_IRQS]; /* NR_IRQS根据不同的MCU会有所区别*/
在通过request_irq()函数注册中断服务程序的时候,将会把中断向量和中断服务程序对应起来。
我们来看一下request_irq的源码:
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long irq_flags, const char * devname, void *dev_id)
{
unsigned long retval;
struct irqaction *action;
if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
(irq_flags & SA_SHIRQ && !dev_id))
return -EINVAL;
action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action) /* 生成action结构*/
return -ENOMEM;
action->handler = handler;
action->flags = irq_flags;
action->mask = 0;
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
retval = setup_arm_irq(irq, action); /*把中断号irq和action 对应起来*/
if (retval)
kfree(action);
return retval;
}
其中第一个参数irq就是中断向量,第二个参数即是要注册的中断服务程序。很多同仁可能疑惑的是,我们要注册的中断向量号是怎么确定的呢?这要根据具体芯片的中断控制器,比如三星的S3C2410,需要 通过读取其中的中断状态寄存器,来获得是哪个设备发生了中断:
(保定慧通科技 garyguo http://www.witech.com.cn *版权所有,引用请注明出处!)
if defined(CONFIG_ARCH_S3C2410)
#include <asm/hardware.h>
.macro disable_fiq
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #INTBASE @ virtual address of IRQ registers
ldr \irqnr, [r4, #0x8] @ read INTMSK 中断掩码寄存器
ldr \irqstat, [r4, #0x10] @ read INTPND 中断寄存器
bics \irqstat, \irqstat, \irqnr
bics \irqstat, \irqstat, \irqnr
beq