【问题标题】:Linux sysfs gpio: what re-arms interrupt?Linux sysfs gpio:什么重新武装中断?
【发布时间】: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


【解决方案1】:

我最近一直在使用 sysfs,这个 sn-p 帮助了我:

int main() {
    struct pollfd myPollfd;
    myPollfd.fd = open("/sys/class/gpio/GPIO_IN_WHEEL1/value", O_RDONLY); //store filedescriptor in struct, open(path, read-write-permission)
    myPollfd.events = POLLPRI;
    while (1) {
        poll(&myPollfd, 1, -1); //poll(struct pollfd, max fd, timeout), timeout=-1 --> never
        if(myPollfd.revents & POLLPRI) {
            len = read(myPollfd.fd, buf, BUF_SIZE);  //mandatory to make system register interrupt as served
            printf("interrupt!\n",);
        }
        lseek(myPollfd.fd, 0, 0); //return cursor to beginning of file or next read() will return EOF
    }
    close(myPollfd.fd);
    return 0;
}

根据 sysfs 手册,是读取操作使中断注册为已服务,因此为了响应下一个中断,必须在端点上调用 read(),即使端点本身的内容是没有意义的。
不幸的是,我目前找不到上述文档,但如果我正确理解了您的问题,您需要知道的是,在第一次和第一次调用 read() 之间发生的所有中断都将是丢了。

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 2012-06-01
    相关资源
    最近更新 更多