2013-01-12 108 views
5

我試圖監視GPIO引腳,每Linux的文檔,我應該能夠通過監視/sys/class/gpio/gpio##/value文件,select做到這一點:GPIO監控與選擇

"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 

我試圖在做這個紅寶石,並且按照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不應該能夠監控這個?

回答

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