您的位置:首页 > 理论基础 > 数据结构算法

中断的 3个重要数据结构

2014-02-19 14:31 232 查看
(1)中断描述符 irq_desc——针对具体的IRQ线,一个控制器可能对应多条IRQ线

数据结构 irq_desc 用于描述 IRQ 线的属性与状态,又被称为中断描述符(区别于之前所述的门描述符)。每个 IRQ 都有它自己的 irq_desc 对象,所有的 irq_desc 对象组织在一起形成 irq_desc 数组,即中断描述符数组。irq_desc 结构在 include/linux/irq.h 文件中定义。

(2)中断控制器描述符 irq_chip——针对不同的控制器

数据结构 irq_chip 用于描述不同类型的中断控制器。Linux 可以支持多种中断控制器,所以内核分别创建了多个 irq_chip 结构对象,与之相对应,比如,I8259A 对应 i8259A_chip,APIC 对应 ioapic_chip、lapic_chip 等。irq_chip 在 include/linux/irq.h 文件中的定义。

(4)中断服务程序描述符 irqaction——针对具体的设备(对应具体的服务程序)

如前所述,多个设备可以共享同一个 IRQ 线,但是这些设备都有各自不同的中断处理方式。这就要求我们在进行中断处理时,能够区分共享同一个 IRQ 线的多个设备,基于这个目的,内核引入了数据结构irqaction 来描述针对特定设备所产生中断的操作。irqaction 在 include/linux/interrupt.h
文件中定义。

因为一个中断控制器控制多个IRQ线,因此,irq_chip里应该有IRQ相关的定义,可以看到如下代码:

struct irq_chip {
/* 中断控制器名称 */
099 const char*name;
/* 启用与关闭指定的 IRQ 线 */
100 unsigned int (*startup)(unsigned int irq);
101 void(*shutdown)(unsigned int irq);
102 void(*enable)(unsigned int irq);
103 void(*disable)(unsigned int irq);

/* 激活与禁止指定的 IRQ 线 */
104/* 应答指定的 IRQ 线 */
105 void (*ack)(unsigned int irq);
106 void (*mask)(unsigned int irq);
107 void (*mask_ack)(unsigned int irq);
/* 屏蔽指定的 IRQ 线,阻塞它向 CPU 发送 */
/* 解除屏蔽指定的 IRQ 线 */
108 void (*unmask)(unsigned int irq);
109 void (*eoi)(unsigned int irq);


同样,一个IRQ可以管理多个中断设备,因此在irqaction必然有和设备相关的数据结构,如下代码,有irqcation链表,用于存放多个irqaction。共享同一个 IRQ 线的多个 irqaction 对象组成一个队列,即所谓的中断请求队列。中断产生时,在该 IRQ线中断请求队列中挂载的所有中断服务程序将被依次调用执行。

080 typedef irqreturn_t (*irq_handler_t)(int, void *);
081
082 struct irqaction {
/* 特定设备对应的中断服务程序 */
083irq_handler_t handler;
/* 中断处理的标志(见表 6.3) */
084 unsigned long flags;
085 cpumask_t mask;
086 const char *name;
/* 设备名*/
/* 设备的私有字段,通常用于标识设备,或指向设备驱动程序的数据,
驱动程序申请 IRQ 时将其作为参数传递给中断处理程序 */
087 void *dev_id;
/* 指向 IRQ 线中断请求队列中的下一个 irqaction 对象 */
088 struct irqaction *next;
/* IRQ 线 */
089 int irq;
090 struct proc_dir_entry *dir;
091 };


主要的 irqaction 标志

IRQF_DISABLED 执行中断处理程序时,禁止对应的 IRQ 线

IRQF_SHARED 设备同意与其他设备共享 IRQ 线

IRQF_SAMPLE_RANDOM 可以被内核用作随机数产生器

为了使中断得到真正的处理,需要在设备驱动程序中使用 request_irq 函数注册一个 IRQ。request_irq函数会为设备创建 irqaction 结构对象,并将其添加到该 IRQ 的中断请求队列中,之后,设备产生中断时,就会通过该 IRQ 的中断请求队列找到已经添加的中断服务程序进行处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: