[Linux驱动入门]中断处理

时间:2020-12-01 23:37:23

第三章 中断处理

3.1 中断和中断处理

中断处理程序是被内核调用来响应中断的,运行在中断上下文,中断处理程序是上半部,当接收到一个中断时,它就立即开始执行,但只做有严格时限的工作。

中断处理程序的注册是通过request_irq函数完成的,由于该函数内部有分配内存的操作,所以它不能在中断上下文或其他不允许阻塞的代码中调用。同一个中断处理程序绝不会被同时调用以处理嵌套的中断。中断处理程序不用关心中断栈和内核栈的设置,只需尽量节约内核栈空间。

锁提供保护机制,防止来自其他处理器的并发访问,而禁止中断提供的保护机制则是防止来自其他中断处理程序的并发访问。

查看使用的中断号可以用“cat/proc/interrupts”得到。中断系统的状态可以通过几个函数获得:irqs_disabled 函数查看本地中断传递是否被禁止;in_interrupt函数查看是否在中断上下文;in_irq 查看是否是当前正在执行中断处理程序。

 

3.2 中断的下半部分

中断处理流程的上半部分的局限:

(1)中断以异步方式执行,它有可能打断其他重要代码,为了避免打断时间过长,中断处理程序应该执行快些。

(2)如果当前有一个中断处理程序正在运行,需要做一个禁止其他中断的操作,禁止中断后硬件和操作系统无法通信了,所以也有中断处理快点。

(3)中断处理往往需要对硬件操作,所以也需要快一点。

(4)中断处理程序不在进程上下文,不能睡眠,这也限制了它们所做的事情。

     下半部的任务就是执行与中断处理密切相关中断处理程序本身不执行工作。对时间敏感、与硬件相关、要保证不被其他中断打断的事件放在中断处理程序中执行,其他任务考虑放在下半部执行。

3.3 中断下半部分的实现

下半部实现的机制包括软中断,tasklet和工作队列。

(1)软中断是一组静态定义的下半部接口,有32个,可以在所有处理器上同时执行,软中断必须在编译期间进行静态注册。软中断在以下情况执行:

     1.一个硬件中断代码处返回。

     2.在ksoftirqd内核线程中。

     3.在显式检查和执行处待理的软件中断的代码中。

2)tasklet有两类软中断代表:HI_SOFTIRQ和TASKLET_SOFTIRQ,前者优先级更高。

DECLARE_TASKLET(test_tasklet,test_tasklet_func,0)    //定义

void test_tasklet_func(void)                       //处理函数

{

    printk(tasklet is executing!\n);               

}

tasklet_schedule(&test_tasklet);        //调度

(3)工作队列可以把工作退后,交给一个内核线程去执行,这个下半部分总是会在进程上下文中执行的,工作队列运行重新调度甚至是睡眠,它是唯一能在进程上下文中运行的下半部实现机制,也只有它可以睡眠。