【问题标题】:How to handle GPIO interrupt-like handling in Linux userspace如何在 Linux 用户空间中处理类似 GPIO 中断的处理
【发布时间】:2019-05-16 10:38:21
【问题描述】:

不确定我是否应该在此处发布此内容,但我得问一下。

上下文:

  • 嵌入式平台上的 Linux (CPU @~500MHz)
  • 一个团队致力于单一用户空间软件
  • 一个团队致力于 Linux + 驱动程序 + uboot 等。

软件必须处理 GPIO,一些是输出(需要时写入),一些是输入(需要时读取,对另一些最好类似中断)。

该软件是一个多线程应用程序,在 SCHED_FIFO 调度策略中具有约 10-15 个线程。

假设我有一个名为 WGPIO 的模块,它是一个处理 GPIO 的包装器。 (顺便说一句,这是由 Linux 团队开发的。WGPIO 仍在用户空间中,但如果需要,他们可以开发驱动程序)

这是我们所说的设计的一些伪代码。

gpio_state state = ON;
// IO_O is output. Set to ON, don't care if it's active_high or active_low btw
WGPIO_WriteOutput(IO_O,state);

// IO_I is input, read when needed
WGPIO_ReadInput(IO_I,&state);

// register callback when rising edge occurs on IO named IO_IT
WGPIO_SetCallback(IO_IT,EDGE_RISING,my_callback);
// Unmask to enable further IT-like processing
WGPIO_UnmaskIRQ(IO_IT);

我必须能够在 5 到 10 毫秒内处理一些 GPIO 更改。

多个 FD 上的一些用户空间轮询(WGPIO 会有一个 SCHED_FIFO 线程)是否足以在我的应用程序中模拟“类似中断”的处理?这看起来是最简单的想法。

如果您需要更多详细信息,请随时询问。 提前致谢。

【问题讨论】:

    标签: c++ linux gpio


    【解决方案1】:

    来自kernel gpio/sysfs.txt

    "value" ... reads as either 0 (low) or 1 (high). If the GPIO
      is configured as an output, this value may be written;
      any nonzero value is treated as high.
    
      If the pin can be configured as interrupt-generating interrupt
      and if it has been configured to generate interrupts (see the
      description of "edge"), you can poll(2) on that file and
      poll(2) will return whenever the interrupt was triggered. If
      you use poll(2), set the events POLLPRI and POLLERR. If you
      use select(2), set the file descriptor in exceptfds. After
      poll(2) returns, either lseek(2) to the beginning of the sysfs
      file and read the new value or close the file and re-open it
      to read the value.
    
    "edge" ... reads as either "none", "rising", "falling", or
      "both". Write these strings to select the signal edge(s)
      that will make poll(2) on the "value" file return.
    
      This file exists only if the pin can be configured as an
      interrupt generating input pin.
    

    首选方法通常是在/sys/class/gpio/gpioN/value 上为POLLPRI | POLLERR 配置/sys/class/gpio/gpioN/edgepoll(2) 中断(重要的是不是 POLLIN!)。如果您的流程是一些需要实时处理事件的“实时”流程,请考虑减少它的好处。

    您甚至可以在 github 上找到一些使用 poll 的示例代码,例如。 this repo.

    【讨论】:

    • poll(2) 解决方案已经是最初的想法,我想看看它有一些更有效/更有效的想法。我接受您的回答,因为它应该可以工作并回答我的问题。谢谢!
    • 当您链接到的文档在开头明确指出此接口已弃用且不应使用时,我不会将其称为“首选方式”。我仍在寻找使用新 API 的解决方案。
    • 我认为 libgpiod 在撰写本文时并不那么受欢迎。但可以肯定 - 让我们提一下吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多