2013-01-12 53 views
5

Tôi đang cố gắng để theo dõi một pin GPIO, và mỗi tài liệu Linux tôi sẽ có thể làm điều này bằng cách giám sát các tập tin /sys/class/gpio/gpio##/value với select GPIO:giám sát với chọn

"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 

Tôi đang cố gắng để làm điều này trong Ruby, và theo số IO.Select documentation, nó gọi số select(2).

Như vậy, với kiến ​​thức này tôi đã ném cùng các chương trình thử nghiệm sau đây:

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 

Tuy nhiên, nó không phát hiện bất kỳ thay đổi pin. Khi tôi khởi động ứng dụng này nó sẽ ngay lập tức rơi vào khối if và hiển thị giá trị hiện tại của pin, và sau đó cứ 5 giây chỉ in timeout.

Tôi đã đọc tài liệu sai chưa? Không nên select có thể giám sát điều này?

Trả lời

4

Trước khi select kích hoạt chính xác trên ghim GPIO, bạn cần phải thiết lập trình kích hoạt cạnh của ghim. Từ 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. 

Trong Ruby đơn giản:

File.open("/sys/class/gpio/gpio17/edge", "w") { |f| f.write("both") } 

Các ví dụ hoàn chỉnh từ ở trên sẽ giống như:

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