【问题标题】:Interrupt handling in Device Driver设备驱动程序中的中断处理
【发布时间】:2014-11-20 04:56:17
【问题描述】:

我编写了一个简单的字符驱动程序,并在一个 gpio 引脚上请求 IRQ,并为它编写了一个处理程序。

err = request_irq(irq, irq_handler,IRQF_SHARED | IRQF_TRIGGER_RISING, INTERRUPT_DEVICE_NAME, raspi_gpio_devp);

static irqreturn_t irq_handler(int irq, void *arg);

现在从理论上我知道在中断中断控制器时告诉处理器调用 do_IRQ() 它将检查 IDT 并为此行调用我的中断处理程序。

内核如何知道中断处理程序是针对这个特定设备文件的

我也知道中断处理程序不在任何进程上下文中运行。但是,假设我正在访问在处理程序范围之外声明的任何变量,静态全局标志 = 0,在处理程序中我将标志 = 1 表示发生了中断。该变量在进程上下文中。所以我很困惑这个处理程序如何不在任何进程上下文中修改进程上下文中的变量。

谢谢

【问题讨论】:

    标签: linux-kernel kernel linux-device-driver interrupt interrupt-handling


    【解决方案1】:

    内核不知道这个特定中断是针对特定设备的。

    它唯一知道的是它必须调用irq_handler,并以raspi_gpio_devp 作为参数。 (像这样:irq_handler(irq, raspi_gpio_devp))。

    如果您的 irq 线路是共享的,您应该检查您的设备是否生成了 IRQ。代码:

    int irq_handler(int irq, void* dev_id) {
        struct raspi_gpio_dev *raspi_gpio_devp = (struct raspi_gpio_dev *) dev_id;
        if (!my_gpio_irq_occured(raspi_gpio_devp))
            return IRQ_NONE;
        /* do stuff here */
        return IRQ_HANDLED;
    }
    

    中断处理程序在中断上下文中运行。 但是你可以访问在中断范围之外声明的静态变量

    通常,中断处理程序的作用是:

    • 检查中断状态
    • 从硬件中检索信息并将其存储在某处(例如缓冲区/fifo)
    • wake_up() 等待该信息的内核进程

    如果您想对中断处理的“做”和“不做”真正有信心,最好了解一下内核的进程是什么。

    处理这个问题的好书是Linux Kernel Developpement by Robert Love.

    【讨论】:

      【解决方案2】:

      内核不知道中断属于哪个设备。单个中断可以在多个设备之间共享。以前这很常见。由于中断控制器中改进的中断支持和消息信号中断的引入,它变得越来越少。您的驱动程序必须确定中断是否来自您的设备(即您的设备是否需要“服务”)。

      您可以通过提供的“void *arg”为您的中断处理程序提供上下文。这绝不应该是特定于进程的上下文,因为进程可能会退出而留下悬空的指针(即引用已被释放和/或可能为其他目的重新分配的内存)。

      全局变量不是“在进程上下文中”。它存在于所有上下文中——如果您愿意,也可以没有上下文。当您听到“不在进程上下文中”时,这意味着几件事:(1)您不能阻塞/睡眠(因为您要让哪个进程进入睡眠状态?),(2)您不能对用户空间虚拟进行任何引用地址(因为这些引用指向什么?),(3)您不能引用“当前任务”(因为没有或未知)。

      通常,驱动程序的中断处理程序将数据推送或拉入“驱动程序全局”数据区域,驱动程序的进程上下文端可以从该数据区域/向该数据区域传输数据。

      【讨论】:

      • 我如何编写代码来确定中断是针对我的设备的...将 irq 参数与已知的 IRQ 值进行比较?因此,我所说的这个全局变量例如:指示已发生中断的 int 标志应位于每个设备结构的一侧,该结构应作为 void *arg 传递给处理程序???
      • 通常您会询问您的设备。如果您的设备无法告诉您它是否产生了中断,那么您需要确保中断线共享(不使用 IRQF_SHARED)。
      • “void *arg”可用于您想使用的任何用途。通常,它指向某种特定于设备的数据结构(因为通常可能有多个设备实例)。您也可以将全局数据保存在全局/静态变量中。
      【解决方案3】:

      这是为了回答你的问题:-

      内核如何知道中断处理程序是针对这个特定的>设备文件的?

      1. 每个片上系统文档都会提到连接到不同中断线的不同设备的中断号。

      2. 为了实例化设备驱动程序,必须在设备树条目中提及相同的中断号。

      3. Device驱动常用的probe函数解析Device tree数据结构,读取IRQ号,使用register_irq函数注册handler。

      4. 如果一个 IRQ 号/行有多个设备,则可以在 IRQ 处理程序内部使用 IRQ 状态寄存器(如果映射在同一 VM 空间下,则用于不同设备)进行区分。

      请在我的blog阅读更多内容

      【讨论】:

        猜你喜欢
        • 2012-12-13
        • 2021-12-27
        • 2018-05-19
        • 2011-07-19
        • 2021-09-25
        • 1970-01-01
        • 2011-09-01
        • 2023-03-02
        • 2013-10-29
        相关资源
        最近更新 更多