1. Linux2.6中断数据结构:
extern struct irq_desc irq_desc[NR_IRQS]; //中断描述符表
struct irqaction {
irq_handler_t handler;//中断注册函数
unsigned long flags;
cpumask_t mask;
const char *name;
void *dev_id;
struct irqaction *next;//实现中断共享同一IRQ
int irq;
struct proc_dir_entry *dir;
};
在中断初始化阶段,调用 hw_interrupt_type 类型的变量初始化 irq_desc_t 结构中的 handle 成员。在早期的系统中使用级联的8259A,所以将用 i8259A_irq_type 来进行初始化,而对于SMP系统来说,要么以 ioapic_edge_type,或以 ioapic_level_type 来初始化 handle 变量。
对于每一个外设,要么以静态(声明为 static 类型的全局变量)或动态(调用 request_irq 函数)的方式向 Linux 内核注册中断处理程序。不管以何种方式注册,都会声明或分配一块 irqaction 结构(其中 handler 指向中断服务程序),然后调用 setup_irq() 函数,将 irq_desc_t 和 irqaction 联系起来。
中断注册函数:
request_irq - allocate an interrupt line
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
* Flags: IRQF_SHARED Interrupt is shared
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
(具体中断共享机制参考《Linux如何处理共享中断》)
2. RTAI3.5中断数据结构
struct rtai_realtime_irq_s rtai_realtime_irq[];
struct rtai_realtime_irq_s {
int (*handler)(unsigned irq, void *cookie);
void *cookie;
int retmode;
int cpumask;
int (*irq_ack)(unsigned int);
};
中断注册请求函数:
int rt_request_irq(unsigned irq, rt_irq_handler_t handler, void *cookie, int retmode)
{
……
if (rtai_realtime_irq[irq].handler != NULL)
return -EBUSY;
……
}
每个IRQ只能注册一个handler,因而不支持中断共享。分析原因:RTAI为了保证中断的实时性,因而避免了终端共享机制中对IRQ中断链上每个注册中断函数的遍历处理。