"handler function" request_threaded_irq的 I2c 读取和写入操作如何影响整个驱动程序。?



我有一个驱动程序代码,其处理程序函数和线程函数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. "处理程序 fn"中的 2 个 i2c 操作需要相当长的时间吗?

  2. 我是否需要在"处理程序 fn"原子中进行位操作?

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

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

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

提前谢谢。

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

该协议允许外设从机IC执行时钟拉伸,从而允许它们"保持"主机,直到它们准备就绪。但是,这不是常见的情况,因此大多数情况下,每个I2C传输通常都在预定的时间间隔内完成。但是,这不是保证,因此在ISR中执行多个I2C传输不是一个好主意。

链接包含有关线程 irqs 的基础知识及其正确用法的良好解释。


上述场景的最佳设计?

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

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

ISR 代码 :
1. 在 ISR 中,呼叫disable_irq()以防止进一步中断。
2. 安排一个下半部分处理程序函数(工作队列是一个不错的选择)。
3. 从 ISR 返回IRQ_HANDLED

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



实现相同设计的另一种方法是使用不带 ISR 的线程 irq。这实现了与上述设计相同的目标,并且无需在代码中单独定义/初始化/清理下半部分处理程序。

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

最新更新