kzs*_*kzs 3 interrupt irq linux-device-driver linux-kernel
我有一个带处理函数的驱动程序代码和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;
}
Run Code Online (Sandbox Code Playgroud)
关于上述实施,我几乎没有问题.
"处理程序fn"中的2 i2c操作是否需要相当长的时间.
我是否需要在"handler fn"atomic中进行位操作?
我应该将执行操作直到"启用设备中断"从"线程fn"移动到"处理程序fn"(这将花费我多4次i2c操作和一位操作完全)? - 根据上面的代码实现,我有可能错过中断的原因.
如果我这样做(根据问题3).它如何影响其他设备中断.(因为我基本怀疑硬IRQ上下文中的"处理程序fn"是否在禁用中断的情况下运行)
请为我提供一个针对上述场景的良好和最佳解决方案.
提前致谢.
I2C读/写传输不是确定性的.
该协议允许外围从设备IC执行时钟延长,从而允许它们"保持"主设备,直到它们准备就绪.然而,这不是常见的情况,因此每次I2C传输通常在大多数时间以预定间隔完成.但是,这不是保证,因此在ISR中执行多个I2C传输并不是一个好主意.
此链接包含有关线程irq的基本原理及其正确用法的很好的解释.
使用线程中断处理程序方法不会有很多好处,因为尝试启用/禁用设备上的中断会增加延迟.
在您当前的场景中(来自单个设备的单个中断),可以坚持常规request_irq()注册中断服务例程(ISR).
ISR代码:
1.在ISR中,调用disable_irq()以防止进一步中断.
2.安排下半部处理函数(workqueue是一个不错的选择).
3. IRQ_HANDLED从ISR 返回.
下半部处理程序代码:
4.执行I2C传输.
5.致电enable_irq()并退出.
注意:
实现相同设计的另一种方法是使用没有ISR的线程irq.这实现了与上述设计相同的功能,并且无需在代码中单独定义/初始化/清理下半部分处理程序.
在这种方法中,可以将所有I2C读/写代码放在IRQ线程函数中并将其传递给它request_threaded_irq(),handler = NULL即空ISR.
| 归档时间: |
|
| 查看次数: |
2729 次 |
| 最近记录: |