linux内核之中断

Linux内核学习从零单排之三:中断

1.不同的设备对应的中断不同,每个中断都有一个唯一的数字标识,这些中断值通常称为中断请求线(IRQ)。

2.在响应一个中断的时候,内核会执行一个函数,就叫做中断处理程序。中断处理程序就是被内核调用来响应中断的。既想要中断处理程序运行快,又想完成的工作量多,鉴于此,我们一般把中断处理分为两个部分:中断处理程序是上半部(top half),能够被允许稍后完成的工作会推迟到下半部(bottom half)。

3.注册中断处理程序:

 驱动程序可以通过request_irq()函数注册一个中断处理程序(声明文件在:<linux/interrupt.h>),并且激活给定的中断线以处理中断。

int request_irq(unsigned int irq,irq_handler_t handler,unsigned long flags,const char *name,void *dev)

irq表示要分配的中断号。handler是一个指针,只想处理这个中断的实际中断处理程序。第三个参数flags可以为0,也可能是下列一个或多个标识的位掩码(其定义在<linux/interrupt.h>中):1)IRQF_DISABLED,被设置后,意味着内核在处理中断处理程序本身期间,要禁止所有的其他中断。2)IRQF_SAMPLE_RANDOM,此标识表明这个设备产生的中断对内核熵池entropy pool 有贡献。如果指定了该标识,那么来自该设备的中断间隔时间就会作为墒填充到熵池。3)IRQF_TIMER,该标识是特别为系统定时器的中断处理而准备的。4)IRQF_SHARED,此标志表明可以再多个中断处理程序之间共享中断线。

第四个参数name是与中断相关的设备的ASCII文本表示,如键盘中断就是keyboard。

第五个参数dev用于共享中断线。

request_irq()成功执行会返回0,若返回非0,则表明有错误发生,这种情况下,指定的中断处理程序不会被注册。

注意:request_irq()函数可能会睡眠,因此不能再中断上下文或其他不允许阻塞的代码中调用该函数。原因是因为它会调用到kmalloc()函数(这个函数式可以睡眠的).

4.编写中断处理程序

中断处理程序的声明:

static irqreturn_t intr_handler(int irq,void *dev)

第一个参数irq是中断号。第二个参数dev是一个通用指针,它必须与在中断处理程序注册时的dev值一致。中断处理程序的可能返回两个特殊的值:IRQ_NONE和 IRQ_HANDLED。当中断处理程序被正确调用且确实是它所对应的设备产生了中断是返回IRQ_HANDLED。

对于共享的中断处理程序,其request_irq()的参数flags必须设置为IRQ_SHARDED。

5.中断上下文

当执行一个中断处理程序时,内核处于中断上下文。进程上下文是一种内核所处的操作模式,此时内核代表进程执行系统调用或运行内核线程,进程上下文可以睡眠,也可以调用调度程序。中断上下文与进程无关,中断上下文不能睡眠,所以它不能调用某些会睡眠的函数。

中断上下文具有较为严格的时间限制,因为它打断了其他代码,所以应尽量迅速简洁,尽量把工作从中断处理程序中分离出来,放在下半部执行。

你可能感兴趣的:(linux内核之中断)