如何在Linux中避免共享IRQ竞争

blu*_*ift 6 linux embedded interrupt

我正在考虑嵌入式Linux项目中即将出现的情况(还没有硬件),其中两个外部芯片需要共享一条物理IRQ线.该线路能够用于边沿触发的硬件,但不能用于电平触发的中断.

看看Linux中的共享irq支持,我理解这对两个独立驱动程序的工作方式是每个驱动程序都会调用它们的中断处理程序,检查它们的硬件并在适当的时候处理.

但是我想象下面的竞争条件,并且想知道我是否遗漏了某些东西或者可以做些什么来解决这个问题.假设有两个外部中断源,设备A和B:

  1. 发生设备B中断,IRQ变为活动状态
  2. IRQ edge导致Linux核心中断处理程序运行
  3. 设备A的ISR运行,发现没有待处理的中断
  4. 设备发生中断,IRQ保持活动状态(线或)
  5. 设备B的ISR运行,发现中断挂起,处理并清除它
  6. 核心中断处理程序退出
  7. IRQ保持活动状态,不再生成边缘,IRQ被锁定

似乎要解决这个问题,核心中断处理程序必须在运行所有处理程序后检查IRQ级别,如果仍然处于活动状态,则再次运行它们.Linux会这样做吗?我不认为中断内核知道如何检查IRQ线的电平.

这场比赛是否真的会发生,如果是这样,我该怎么处理?

Mic*_*hne 3

基本上,使用您所描述的硬件,对中断进行有线或操作永远无法单独正常工作。

如果您想要进行线或操作,您确实需要使用电平敏感的 IRQ 输入。如果这不可行,那么也许您可以添加某种中断控制器。该设备将采用 N 个电平敏感输入,并具有一个输出和某种“清除”。当中断控制器得到清除时,它将降低其输出,然后如果任何输入仍有效,则重新有效输出。

在软件方面,您可以查看是否运行到另一个处理器输入的 IRQ 线。这将允许您至少检查状态,但 Linux 核心 ISR 处理不会知道任何有关此的信息,因此您必须修补某些内容以使其检查状态并再次循环遍历 ISR。另外,这意味着在中断加载繁重的情况下,您永远无法退出此 ISR。鉴于您正在对 IRQ 进行线或操作,我假设这些设备不会经常中断。

另一件事是认真研究处理器。您可以在中断设置中使用某种技巧,以便让它再次识别中断。

我自己不会尝试任何太棘手的事情,我要么将源分离到单独的 IRQ 输入,更改为电平敏感输入,要么添加中断控制器芯片。