我正在尝试监控GPIO引脚,根据Linux文档,我应该可以通过使用/sys/class/gpio/gpio##/value
监控select
文件来执行此操作:
"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
我试图在Ruby中执行此操作,并根据IO.Select documentation调用select(2)
。
所以,凭借这些知识,我将以下测试程序汇总在一起:
fd = File.open("/sys/class/gpio/gpio17/value", "r")
loop do
rs,ws,es = IO.select(nil, nil, [fd], 5)
if es
r = es[0]
puts r.read(1)
else
puts "timeout"
end
end
但是,它没有检测到任何引脚变化。当我启动此应用程序时,它将立即进入if
块并显示引脚的当前值,然后每5秒打印一次timeout
。
我是否读过错误的文档? select
不应该监控这个吗?
答案 0 :(得分:4)
在select
正确触发GPIO引脚之前,您需要设置引脚的边沿触发。来自the GPIO docs:
"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.
简单地在Ruby中:
File.open("/sys/class/gpio/gpio17/edge", "w") { |f| f.write("both") }
上面的完整示例如下:
fd = File.open("/sys/class/gpio/gpio17/value", "r")
File.open("/sys/class/gpio/gpio17/edge", "w") { |f| f.write("both") }
loop do
rs,ws,es = IO.select(nil, nil, [fd], 5)
if es
r = es[0]
puts r.read(1)
else
puts "timeout"
end
end