Linux中断处理程序设计

    xiaoxiao2021-03-25  71

    Linux中断处理程序设计

    中断概念

             中断指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。

           为什么需要中断?

    1、 外设的处理速度一般慢于CPU

    2、  CPU不能一直等待外部事件

    所以设备必须有一种方法来通知CPU它的工作进度,这种方法就是中断。

    中断实现

             在Linux驱动程序设计中,为设备实现一个中断包含两个步骤:

    1、  向内核注册中断

    2、  实现中断处理函数

    中断注册

             request_irq用于实现中断的注册功能:

             intrequest_irq(unsigned int irq,

    void (*handler)(int, void*, struct

    pt_regs *),

    unsigned long flags,

    const char *devname,

    void *dev_id)

    返回0为成功,或者返回一个错误码

    unsigned int irq  中断号

    void (*handler)(int,void *,struct pt_regs *)  中断处理函数

    unsigned long flags  与中断管理相关的各种选项

    const char * devname  设备名

    void *dev_id   共享中断时使用

     

    中断标志

    IRQF_DISABLED (SA_INTERRUPT)如果设置该位,表示为快速中断;如果没有设置该位,那么就是个慢速中断

    IRQF_SHARED (SA_SHIRQ)         该位表明中断可以在设备间共享

    快速中断与慢速中断

    快速中断不会被其他中断打断;而慢速中断会被其他中断打断。

    中断处理程序就是普通的C代码。特别之处在于它是在中断上下文中运行的,它的行为受到某些限制:

    1、  不能向用户空间发送或者接收数据

    2、  不能使用可能引起阻塞的函数

    3、  不能使用可能引起调度的函数

    中断处理函数流程

    voidshort_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs)

    {

    /* 判断是否是本设备产生了中断(为什么要做这样的检测?)*/

    value =inb(short_base);

    if (!(value& 0x80)) return;

    /* 清除中断位(如果设备支持自动清除,则不需要这步) */

    outb(value &0x7F, short_base);

    /*  中断处理,通常是数据接收*/

    。。。。。。。。。

    /*唤醒等待数据的进程*/

    wake_up_interruptible(&short_queue);

    }

    释放中断

    voidfree_irq(unsigned int irq, void *dev_id)

     

    中断分层

             中断可分为上半部与下半部。

             上半部:当中断发生时,它进行对应的硬件读写,并登记该中断。

             下半部:在系统空闲的时候对上半部登记的中断进行后续处理。

             工作队列是一种将任务推后执行的形式,它把推后的任务交由一个内核线程去执行。这样下半部会在进程上下文执行,它允许重新调度甚至睡眠。每个被推后的任务叫做工作,由这些工作组成的队列称为工作队列。

             工作队列执行步骤:

             1、创建工作队列   create_workqueue

             2、创建工作    INIT_WORK

             3、提交工作    queue_work 或者schedule_work

     

    转载请注明原文地址: https://ju.6miu.com/read-33141.html

    最新回复(0)