又是中断(二)-相关的数据结构

本文深入探讨了中断处理相关的数据结构,包括struct irq_desc、struct irqaction和struct hw_interrupt_type。介绍了它们的成员和作用,阐述了如何描述中断源、中断控制器以及处理中断时的行动。并详细解析了中断状态、共享中断以及中断服务程序的实现。

——————————————————————————————————————

先来看看与中断相关的几个主要数据结构:
1、结构体:struct irq_desc(include/linux/irq.h)

27 struct irq_desc;
 28 
typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, 
 29 
struct irq_desc *desc);
 153struct irq_desc 
{
 154 irq_flow_handler_t handle_irq
; /*指向一个函数,下面会用到*/
 155 
struct irq_chip *chip; /* 下面会介绍这个结构体*/
 156 
struct msi_desc *msi_desc;
 157 
void *handler_data;
 158 
void *chip_data;
 159 
struct irqaction *action; /* IRQ action lis下面会介绍 */
 160 
unsigned int status; /* IRQ status */
 161
 162 
unsigned int depth; /* nested irq disables */
 163 
unsigned int wake_depth; /* nested wake enables */
 164 
unsigned int irq_count; /* For detecting broken IRQs */
 165 
unsigned int irqs_unhandled;
 166 
unsigned long last_unhandled;/*Aging timer for unhandled count*/
 167 spinlock_t lock
;
 168
#ifdef CONFIG_SMP
 169 cpumask_t affinity
;
 170 
unsigned int cpu;
 171
#endif
 172
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
 173 cpumask_t pending_mask
;
 174
#endif
 175
#ifdef CONFIG_PROC_FS
 176 
struct proc_dir_entry *dir;
 177
#endif
 178 
const char *name;
 179
} ____cacheline_internodealigned_in_smp;
180 
extern struct irq_desc irq_desc[NR_IRQS];
typedef struct irq_desc irq_desc_t;

这个结构体用来描述中断源,数组irq_desc[NR_IRQS](NR_IRQS=225)中每一项都对应一个相应的中断源,他的每一项对应着中断向量表中的一项,即该数组的第一项对应着中断向量表中的第32项(中断向量号为0x20),往下依次对应。中断向量表一共有256项。
部分成员解释:
status:或者是0,或者是从一个特定的集合中抽取的一个标志位(不太清楚)。这些标志位代表了IRQ的状态--是否被禁止,有关IRQ的设备当前是否正被自动检测等。
chip:是一个指向hw_interrupt_type(或者irq_chip)的指针。下面对此有介绍。
action:是一个指向由irqaction结构体组成的一个单向链表的头的指针。若一个IRQ只被一个中断源使用,那么该链表的长度就是1,当有多个设备共享一个中断源时,该链表就会由多个irqaction结构体组成,下面对此有介绍。
depth:irq_desc_t的当前用户的个数,主要用来保证事件正在处理的过程中IRQ不会被禁止。

2、结构体:struct irqaction(include/linux/interrupt.h)

struct irqaction {
  61 irq_handler_t handler
;
  62 
unsigned long flags;
  63 cpumask_t mask
;
  64 
const char *name;
  65 
void *dev_id;
  66 
struct irqaction *next;//指向下一个本结构

  67 
int irq;
  68 
struct proc_dir_entry *dir;
  69
};

这个结构体包含了处理一种中断所需要的各种信息,它代表了内核接受到特定IRQ之后应该采取的操作。
主要成员:
handler—该指针所指向的函数就是在中断服务程序,当中断发生时内核便会调用这个指针指向的函数。
flags:该标志位可以是0,也可以是:SA_INTERRUPT(表示此中断处理程序是一个快速中断处理程序,在2.6中默认情况下没有这个标志)SA_SAMPLE_RANDOM(表示这个中断对内核池有贡献,我理解为就是在中断时产生一些随机数,这些随机数被用来作为加密密匙,因为中断是随机发生的,如果某种中断是有频率的被产生,那么它就不要设置此标志位,还有就是那种设备容易被攻击也不应该设置此标志位)SA_SHIRQ(此标志位表示允许多个中断服务程序共享一个中断号,如不设则一个程序对应一个中断线)。
mask:在x86上不会用到。
name:产生中断的硬件的名字.
dev_id:该标志位主要在共享中断号时使用,即你设置flags=SA_SHIRQ时,有多个中断服务程序共享一个中断号时,内核就需要知道在用完中断程序后该删除那个中断服务程序。不共享时此成员为null。
next:如果flags=SA_SHIRQ,那么这就是指向对列中下一个struct irqaction结构体的指针,否则为空。
irq:不用说这就是中断号了。

3 结构体:struct hw_interrupt_type(include/linux/irq.h)

#define hw_interrupt_type irq_chip
typedef struct irq_chip hw_irq_controller;
  99struct irq_chip 
{
 100 
const char *name;
 101 
unsigned int (*startup)(unsigned int irq);
 102 
void (*shutdown)(unsigned int irq);
 103 
void (*enable)(unsigned int irq);
 104 
void (*disable)(unsigned int irq);
 105
 106 
void (*ack)(unsigned int irq);
 107 
void (*mask)(unsigned int irq);
 108 
void (*mask_ack)(unsigned int irq);
 109 
void (*unmask)(unsigned int irq);
 110 
void (*eoi)(unsigned int irq);
 111
 112 
void (*end)(unsigned int irq);
 113 
void (*set_affinity)(unsigned int irq, cpumask_t dest);
 114 
int (*retrigger)(unsigned int irq);
 115 
int (*set_type)(unsigned int irq, unsigned int flow_type);
 116 
int (*set_wake)(unsigned int irq, unsigned int on);
 117
 118 
/* Currently used only by UML, might disappear one day.*/
 119
#ifdef CONFIG_IRQ_RELEASE_METHOD
 120 
void (*release)(unsigned int irq, void *dev_id);
 121
#endif
 122 
/*
 123 * For compatibility, ->typename is copied into ->name.
 124 * Will disappear.
 125 */

 126 
const char *typename;
 127
};

此结构体用来描述中断控制器,它是一个抽象的中断控制器,其成员是一系列指向函数的指针。
typename:给相应的控制器起一个便于理解的名字。
startup:允许从给定的控制器的IRQ所产生的事件。(基本上与enable相同)
shutdown:禁止从给定的控制器的IRQ所产生的事件。(基本上与disable相同)
以上三个结构体的关系可以用下面一张图来说明:


数组irq_desc_t用来描述中断的相关信息,它有225项,每一项代表一个中断源,其中字段irq(注意这个字段就是上图中的handler字段),此结构体用来描述中断控制器,action字段用来描述处理一种中断所需要的各种信息,它代表了内核接受到特定IRQ之后应该采取的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值