在调用request_irq函数申请一个IRQ时,会传入相应的中断类型标志。对于这些标志新旧版本的内核实现是不完全相同的。
IRQF_DISABLED
3.16.7-ct7版本内核中此标志是没有地方用到的。此标志表示中断在处理的时候是关中断的,不能被另外的中断所打断。(http://lwn.net/Articles/380931/)这篇文章里有讲到此标志在新内核中被废弃的原因。
之前老的内核中,按照中断处理快慢,分为快速中断和慢速的中断。对于慢速的中断,在处理的时候是不能关中断的,能够被其他的中断所中断,这样能够防止处理耗时过长。快速中断在处理的时候是关中断的,不能被其他中断所中断,因为认为它处理的够快。
在老的内核版本(我参考的内核版本是2.6.12.6)中SA_INTERRUPT标志起到和IRQF_DISABLED一样的作用。
fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); do { ret = action->handler(irq, action->dev_id, regs); //执行注册的handler if (ret == IRQ_HANDLED) status |= action->flags; retval |= ret; action = action->next; } while (action); |
handle_IRQ_event在do_IRQ中调用,在执行注册的handler之前,会判断注册时有没有设置SA_INTERRUPT标志。如果没有设置此标志,就调用local_irq_enable函数开中断。
之前由于硬件的问题、慢速的处理器以及开发人员能力的差异,导致慢速的中断处理在现实情况中大量存在。现在随着硬件的快速发展,已经能够越来越快的处理中断了。并且中断的延迟处理机制,如下半部、中断线程化都使得能够将大量的工作从中断处理程序中移出来。
IRQF_SHARED
此标志用来表示一个IRQ是否允许在多个设备间共享。在之前使用8259中断控制器是,一个8259只有8个pin,2个级联也只能支持15个外部设备中断,外设很多的情况下可能会需要多个设备共享一个IRQ。
现在普遍使用的是APIC(高级可编程的中断控制器),由IO APIC和Local APIC组成。每个IO APIC支持24个IRQ Line,多个IO APIC可以级联。现在不推荐使用此标志来注册中断。