- 中断请求(IRQ)线:不同设备对应的中断不同,而每个中断都通过一个唯一的数字标志。重点在于特定的中断总是与特定的设备相关联,并且内核要知道这些信息。
- 异常:常常也称为同步中断。如处理器执行到由于编程失误导致的错误指令(如被0除),或者执行期间出现特殊情况(如缺页),处理器就会产生一个异常。
- 中断处理程序(ISR):上半部——接收到一个中断,它就立即开始执行,但只做有严格时限的工作,例如对接收的中断进行应答或者复位硬件,这些工作都是在所有中断被禁止的情况下完成的。
- 注册中断处理程序
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
irq:表示要分配的中断号,对大多数设备,这个值可以通过探测获取,或者通过编程动态确定;
handler:指针指向处理这个中断的实际中断处理程序。
typedef irqreturn_t (*irq_handler_t)(int, void *);
flag:可能是下列一个或者多个标志的位掩码
IRQF_DISABLED 该标志被设置后,意味着内核在处理中断处理程序本身期间,要禁止所有其他的中断。
IRQF_SAMPLE_RAMDOM 此标志标明这个设备产生的中断对内核熵池有贡献。
IRQF_TIMER 该标志是特别为系统定时器的中断处理而准备的。
IRQF_SHARED 此标志标明可以在多个中断处理程序之间共享中断线
name:与中断相关的设备的ASCII文本表示。/proc/irq和/proc/interrupts文件使用,以便与用户通信。
dev:用于共享中断线。内核每次调用中断处理程序时,都会把这个指针传递给它。实践中往往会通过它传递驱动程序的设备结构。
注意:request_irq()函数可能会睡眠,因此不能在中断上下文或其他不允许阻塞的代码中调用。
- 释放中断处理程序
void free_irq(unsigned in irq, void *dev)
- 编写中断处理程序
static irqreturn_t intr_handler(int irq, void *dev)
注意:第二个参数dev是一个通用指针,它与request_irq()的参数dev必须一致。dev可能指向中断处理程序使用的一个数据结构。
重入:linux的中断处理程序是无须重入的。当一个给定的中断处理程序正在执行时,相应的中断线在所有处理器上都会被屏蔽。
共享的中断处理程序:
<a>flag必须设置IRQF_SHARED
<b>dev参数必须唯一,通常会用设备结构;
<c>中断处理程序必须能够判断它的设备是否真的产生了中断:需要硬件的支持和处理程序中的处理逻辑。内核接收到一个中断后,它将依次调用在该中断线上注册的每一个处理程序。
- 中断上下文
当执行一个中断处理程序时,内核处于中断上下文。
进程上下文:内核所处的一种操作模式,此时内核代表进程执行,例如执行系统调用或者运行内核线程。
中断处理程序打断了其他代码(甚至可能是打断了其他中断线上的另一中断处理程序)
内核栈、中断栈:页