设备驱动程序中的中断处理

时间:2014-11-20 04:56:17

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

我编写了一个简单的字符驱动程序,并在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,在处理程序中我使flag = 1表示发生了中断。该变量处于流程上下文中。所以我很困惑这个处理程序不在任何进程上下文中修改进程上下文中的变量。

谢谢

3 个答案:

答案 0 :(得分:6)

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

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

全局变量不是“在进程上下文中”。它适用于所有情况 - 如果您愿意,也可以不上下文。当你听到“不在进程上下文中”时,这意味着一些事情:(1)你无法阻止/睡眠(因为你将进入睡眠状态的过程?),(2)你不能对虚拟用户空间进行任何引用地址(因为那些引用会指向什么?),(3)你不能引用“当前任务”(因为没有一个或它是未知的)。

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

答案 1 :(得分:5)

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

它唯一知道的是它必须以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 :(得分:0)

这是回答你的问题: -

  

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

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

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

  3. 设备驱动程序的常用探测功能解析设备树数据结构并读取IRQ编号并使用register_irq函数注册处理程序。

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

  5. 请在我的blog

    中阅读更多内容