中断的 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相关的定义,可以看到如下代码:
同样,一个IRQ可以管理多个中断设备,因此在irqaction必然有和设备相关的数据结构,如下代码,有irqcation链表,用于存放多个irqaction。共享同一个 IRQ 线的多个 irqaction 对象组成一个队列,即所谓的中断请求队列。中断产生时,在该 IRQ线中断请求队列中挂载的所有中断服务程序将被依次调用执行。
主要的 irqaction 标志
IRQF_DISABLED 执行中断处理程序时,禁止对应的 IRQ 线
IRQF_SHARED 设备同意与其他设备共享 IRQ 线
IRQF_SAMPLE_RANDOM 可以被内核用作随机数产生器
为了使中断得到真正的处理,需要在设备驱动程序中使用 request_irq 函数注册一个 IRQ。request_irq函数会为设备创建 irqaction 结构对象,并将其添加到该 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 的中断请求队列找到已经添加的中断服务程序进行处理。
相关文章推荐
- 数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
- 数据结构——队列的链式实现(C语言)
- 数据结构之字典树
- 数据结构---设计一个栈,push, pop, min 时间复杂度都是 O(1)
- 数据结构---设计一个栈,push, pop, min 时间复杂度都是 O(1)
- 数据结构实验之栈三:后缀式求值
- 并查集(Union-Find Set)
- 最小生成树(MST) Kruskal 算法
- 希尔排序 - 数据结构和算法91
- 数据结构——链栈的实现(C语言)
- 数据结构uva101
- python基础数据结构——列表(list), 元祖(tuple), 字典(dict), 字符串(string), 集合(set) 介绍及相互转换
- 数据结构上机测试4.1:二叉树的遍历与应用1
- 数据结构实验之求二叉树后序遍历和层次遍历
- 数据结构实验之二叉树的建立与遍历
- 寒假训练--树与二叉树--数据结构实验之求二叉树后序遍历和层次遍历
- 寒假训练--树与二叉树--数据结构实验之二叉树的建立与遍历
- IplImag数据结构之dataOrder和widthStep
- 最小生成树(kruskal算法)
- App设置相关数据结构化