3

我有一个带有 request_threaded_irq 的处理函数和线程函数的驱动程序代码,类似于:

irq-handler fn()
{
      /*disable device interrupt*/
      i2c read from register;
      set disable bit to client-device-interrupt 
      i2c write back;
      return IRQ_WAKe_THREAD;
}



irq-thread fn()
{
      i2c read from register;
      ....
      ....
      /*enable device interrupt*/
      i2c read from register;
      set enable bit to client-device-interrupt 
      i2c write back;
      /*Rest of the operation*/
      ..........
      ..........
      return IRQ_HANDLED;
}

我对上述实施几乎没有疑问。

  1. “handler fn”中的 2 i2c 操作会花费大量时间吗?

  2. 我是否需要在“handler fn”原子中进行位操作?

  3. 我是否应该将执行到“启用设备中断”的操作从“线程 fn”移动到“处理程序 fn”(这将花费我 4 次 i2c 操作和一位操作)?- 有可能我可能会根据上述代码实现错过中断。

  4. 如果我这样做(根据问题 3)。它如何影响其他设备中断。(因为我基本怀疑硬 IRQ 上下文中的“处理程序 fn”是否在禁用中断的情况下运行

请为我提供上述情况的最佳解决方案。

提前致谢。

4

1 回答 1

5

I2C 读/写传输不是确定性的。

该协议允许外围从 IC 执行时钟延长,从而允许它们“保持”主器件,直到它们准备好。然而,这不是一个常见的场景,因此每个 I2C 传输通常在大部分时间都在预定的时间间隔内完成。但是,这不是保证,因此在 ISR 中执行多个 I2C 传输不是一个好主意。

链接包含有关线程 irq 的基本原理及其正确用法的很好的解释。


上述场景的优化设计?

使用线程中断处理程序方法不会有很多好处,因为尝试启用/禁用设备上的中断会增加延迟。

在您当前的情况下(来自单个设备的单个中断),可以坚持使用常规request_irq()来注册中断服务例程(ISR)。

ISR代码:
1. 在 ISR 中,调用disable_irq()以防止进一步的中断。
2.调度一个bottom half handler函数(workqueue是一个不错的选择)。
3.IRQ_HANDLED从 ISR 返回。

下半部分处理程序代码:
4. 执行 I2C 传输。
5. 调用enable_irq()并退出。


注意
实现相同设计的另一种方法是使用没有 ISR 的线程 irq。这实现了与上述设计相同的效果,并且无需在代码中单独定义/初始化/清理底部处理程序。

这种方法中,可以将所有 I2C 读/写代码放在IRQ 线程函数中,并将其与空 ISRrequest_threaded_irq()一起传递。handler = NULL

于 2013-09-22T10:41:13.483 回答