设备驱动程序中的中断处理&轮询

时间:2017-12-23 07:32:37

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

我正在深入研究一些大致如下的代码:

  • 内核驱动程序处理中断。
  • 有一条中断线,所以当一个中断发生时,句柄读取一个32位寄存器,告诉这个中断是什么原因。
  • 对于设置的每个位,它调用ack_irq()来清除中断,并将中断原因写入驱动程序中的缓冲区以进一步读取()。
  • 接下来,它调用wake_up_interruptible()来唤醒在select()上休眠的用户空间进程。
  • 相应的poll()函数执行poll_wait()。
  • 一旦select返回,用户空间就会从驱动程序中读取()。

虽然我理解只有1位的基本操作,但在下列情况下会发生什么:

  • 发生中断,并设置1位。
  • 处理程序调用wake_up_interruptible()。 poll()返回。
  • 用户空间醒来,开始阅读()。
  • 现在,发生另一个中断 - > kernel处理中断并调用wake_up_interruptible(),但现在没有人不等待这个事件。

这是否意味着错过第二个中断?如果是这样,克服这个问题的方法是什么?

1 个答案:

答案 0 :(得分:0)

中断处理程序的任务是尽可能快地处理中断。

为了与系统的其余部分进行通信,ISR使用(循环)缓冲区来放置cause。它在处于中断禁用状态时执行此操作。

中断服务完成后,系统继续运行。如果用户进程现在想要检查循环缓冲区中的新事件,则需要对缓冲区进行独占访问。此外,它必须禁用中断(优先级高于ISR)。它禁用中断,获取缓冲区的下一个元素,更新缓冲区指针或索引并重新启用中断。

新的中断是否会进入,然后在用户进程重新启用中断之前不会处理(IRQ线保持高电平,芯片寄存器尚未被读取)。不用说,这个缓冲区访问也必须尽可能快(尽可能少的指令)。重新启用中断后,将处理新的待处理中断。

在从缓冲区获取下一个项目之后,它将其交给功能用户进程。如果缓冲区中没有项目,它会睡觉。当一个项目到达时,它将被唤醒,禁用中断,获取项目,重新启用中断并返回到用户进程。

通过这种方式,不会错过任何中断。