【发布时间】:2021-06-01 16:57:44
【问题描述】:
使用旧的 sysfs GPIO 接口来响应边沿触发的 GPIO 中断的通常方法是这样的:
repeat forever
poll() on POLLPRI event on GPIO fd
lseek() back to 0 on GPIO fd
read() current state from GPIO fd
如果我将实际处理中断的代码放在read() 之后,是否可以保证在再次调用poll() 之前发生的任何新中断都会导致下一个poll() 立即返回?换句话说,哪一步重新激活了中断?从poll() 的返回,对lseek() 的调用,对read() 的调用,还是对poll() 的下一次调用?如果是最后一个,我看不出有任何方法可以保证中断不会丢失。
另外,有必要做read()吗?我不关心状态,只关心边缘事件。如果我不需要read(),lseek() 有什么用处吗?这在现实生活中很难测试,因为它需要在现有硬件上快速连续地生成中断。似乎没有任何文档对此进行解释。
【问题讨论】:
-
首先不要使用sysfs接口。第二,你说的是什么内核版本?我们可以检查代码,看看那里发生了什么。
-
这显示了当新的中断(事件)到来时会发生什么elixir.bootlin.com/linux/latest/source/fs/kernfs/file.c#L913。 AFAIU 当您读取值时,您将读取实际状态(可能与触发投票的不同)。这意味着读取事件有点意义。
-
我坚持使用 4.0.0,这就是我使用 sysfs 的原因。我根本不知道如何绕过内核,所以我无法从这些代码中找出任何东西,尤其是在重新触发中断时。尽管代码中有一条注释暗示确实有必要进行 lseek 和 read。我在某处读到了 /dev/gpiochip 的优点,上面写着“捕获事件(来自 GPIO 线路的中断)的轮询过程是可靠的”,这让我担心 /sys/class/gpio 可能存在一些内在问题使偶尔错过的中断不可避免。
-
v4.0?! (没有v4.0.0)很奇怪。不过好吧,这不是我们在这里讨论的主要问题。
标签: linux interrupt gpio sysfs