如何在 Linux 用户空间中处理类似 GPIO 中断的处理
How to handle GPIO interrupt-like handling in Linux userspace
不确定我是否应该post这里,但我得问一下。
上下文:
- Linux 在嵌入式平台上 (CPU @~500MHz)
- 一个团队开发单用户space 软件
- 一个团队致力于Linux+驱动+uboot等
软件必须处理GPIO,有些是输出(需要时写入),有些是输入(有些需要时读取,其他最好是类似中断的)。
该软件是一个多线程应用程序,在 SCHED_FIFO 调度策略中具有约 10-15 个线程。
假设我有一个名为 WGPIO 的模块,它是一个处理 GPIO 的包装器。 (这是由 Linux 团队开发的 btw。WGPIO 仍在用户 space 中,但如果需要他们可以开发驱动程序)
这是我们所说的一些 pseudo_code 设计内容。
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 变化。
一些用户space 轮询(WGPIO 会有一个 SCHED_FIFO 线程)在多个 FD 上足以模拟我的应用程序中的 "interrupt-like" 处理吗?这看起来是最简单的想法。
如果您需要更多详细信息,请随时询问。
提前致谢。
"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.
首选方法通常是为 POLLPRI | POLLERR
配置 /sys/class/gpio/gpioN/edge
和 poll(2)
中断(重要的是 而不是 POLLIN!) /sys/class/gpio/gpioN/value
。如果您的进程是一些需要实时处理事件的“real-time”进程,请考虑降低它的友好度。
您甚至可以在 github 上找到一些使用轮询的示例代码,例如。 this repo.
不确定我是否应该post这里,但我得问一下。
上下文:
- Linux 在嵌入式平台上 (CPU @~500MHz)
- 一个团队开发单用户space 软件
- 一个团队致力于Linux+驱动+uboot等
软件必须处理GPIO,有些是输出(需要时写入),有些是输入(有些需要时读取,其他最好是类似中断的)。
该软件是一个多线程应用程序,在 SCHED_FIFO 调度策略中具有约 10-15 个线程。
假设我有一个名为 WGPIO 的模块,它是一个处理 GPIO 的包装器。 (这是由 Linux 团队开发的 btw。WGPIO 仍在用户 space 中,但如果需要他们可以开发驱动程序)
这是我们所说的一些 pseudo_code 设计内容。
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 变化。
一些用户space 轮询(WGPIO 会有一个 SCHED_FIFO 线程)在多个 FD 上足以模拟我的应用程序中的 "interrupt-like" 处理吗?这看起来是最简单的想法。
如果您需要更多详细信息,请随时询问。 提前致谢。
"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.
首选方法通常是为 POLLPRI | POLLERR
配置 /sys/class/gpio/gpioN/edge
和 poll(2)
中断(重要的是 而不是 POLLIN!) /sys/class/gpio/gpioN/value
。如果您的进程是一些需要实时处理事件的“real-time”进程,请考虑降低它的友好度。
您甚至可以在 github 上找到一些使用轮询的示例代码,例如。 this repo.