簡體   English   中英

從Python阻止在GPIO上讀取:如何使用epoll()和select進行阻止

[英]Blocking read on GPIO from Python: How to block using epoll() and select.EPOLLET

我正在嘗試在嵌入式系統(ARM內核)上從Python訪問GPIO,該嵌入式系統運行的是使用Buildroot(內核4.1.15)構建的linux。

我希望我的代碼阻塞以等待GPIO2上的引腳更改(即,我不想通過重復調用“ read”來輪詢該引腳)。 我正在嘗試在邊緣觸發模式下使用“ epoll”來做到這一點:

有關epoll的信息,請參見Python文檔 select.EPOLLET標志用於獲取epoll的邊沿觸發。 另請參閱Linux文檔以了解epoll

為簡單起見,我已經使用sysfs從控制台設置了GPIO引腳:

# cat /sys/class/gpio/gpio2/direction 
in
# cat /sys/class/gpio/gpio2/edge
rising

這是我的Python代碼:

#!/usr/bin/env python
# coding=utf8

from time import sleep
import select
import sys

if __name__ == '__main__':

    try:
        pinIn = open("/sys/class/gpio/gpio2/value", "r")
    except IOError:
        print("Error setting up GPIO pin")
        sys.exit()

    myPoll = select.epoll()
    myPoll.register(pinIn.fileno(), select.EPOLLPRI | select.EPOLLET)

    while(1):

        events = myPoll.poll(4)
        print("EPoll result: %s" % (str(events),))

        for fd, event_type in events:
            print("FD: %d; Events: %d" % (fd, event_type))
            if event_type & select.EPOLLIN:
                print("-EPOLLIN!")
            if event_type & select.EPOLLPRI:
                print("-EPOLLPRI!")
            if event_type & select.EPOLLERR:
                print("-EPOLLERR!")

        value = pinIn.read(1)
        pinIn.seek(0)
        print("--> %s" % (str(value),))
        sleep(1)

為了進行測試,我以每個周期大約2秒的時間從信號發生器向輸入引腳饋送方波,這樣我就可以看到引腳何時發生變化。

當我在嵌入式系統上運行它時,我得到了:

# python3 /usr/sbin/test-gpio-python.py 
EPoll result: [(3, 10)]
FD: 3; Events: 10
-EPOLLPRI!
-EPOLLERR!
--> 0

代碼在1秒鍾的睡眠中進入睡眠狀態,然后在下一次迭代中,poll()立即返回並且不會阻塞。 由於我的輸入每2秒僅在一個上升沿上運行,因此應該阻塞。

為什么“ poll()”不被阻止?

====編輯:====

最初,當我嘗試使用“ select.EPOLLET”時,代碼導致了一個奇怪的錯誤:

OverflowError: can't convert negative value to unsigned int

但是,我發現我不小心使用了myPoll = select.poll()而不是epoll() 代碼現已修復。

我決定通過查看/ proc / interrupts來檢查中斷信息。

在這里,GPIO引腳的邊沿設置為“上升”后僅幾秒鍾:

# cat /proc/interrupts 
...
 33:        421  gpio-mxc   2 Edge      gpiolib
...

嗯,已經發生了421次中斷!

兩秒鍾后:

# cat /proc/interrupts 
...
 33:        852  gpio-mxc   2 Edge      gpiolib
...

那可以解釋。 中斷的堆積速度約為每秒400個,絕對比我在Python中處理它們的速度快。

在示波器上進行的進一步研究表明,信號發生器的輸出僅為1.6 V,看起來噪聲正在觸發設備上的輸入電路。

當我切換到正確的信號發生器輸出並在GPIO引腳上獲得干凈的信號時,我開始獲得預期的中斷數,並且python代碼正常工作(即poll()在輸入的上升沿之間正確地阻塞了)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM