首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阻止从Python读取GPIO :如何使用epoll()和select.EPOLLET阻止

阻止从Python读取GPIO :如何使用epoll()和select.EPOLLET阻止
EN

Stack Overflow用户
提问于 2017-11-30 02:01:51
回答 1查看 1.5K关注 0票数 2

我正在一个嵌入式系统(ARM核)上尝试从Python访问GPIO,它运行的是用Buildroot构建的linux (内核4.1.15)。

我希望我的代码阻止等待GPIO2上的引脚更改(也就是说,我不想通过反复调用"read“来轮询引脚)。我试图在边缘触发模式下使用"epoll“执行此操作:

用于epoll的Python文档。使用select.EPOLLET标志进行边缘触发。另见用于epoll的Linux文档

为了简单起见,我已经使用sysfs从控制台设置了GPIO引脚:

代码语言:javascript
复制
# cat /sys/class/gpio/gpio2/direction 
in
# cat /sys/class/gpio/gpio2/edge
rising

下面是我的Python代码:

代码语言:javascript
复制
#!/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秒每周期,所以我可以看到什么时候针改变。

当我在嵌入式系统上运行这个程序时,我会看到:

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

代码睡上1秒睡眠,然后在下一次迭代时,轮询()立即返回,不阻塞。它应该会阻塞,因为我的输入只在每2秒一个上升的边缘运行。

为什么没有“轮询()”阻塞?

====编辑:====

最初,当我尝试使用“select.EPOLLET”时,代码导致了一个奇怪的错误:

代码语言:javascript
复制
OverflowError: can't convert negative value to unsigned int

但是,我发现我意外地使用了myPoll = select.poll()而不是epoll()。密码现在修好了。

EN

回答 1

Stack Overflow用户

发布于 2017-11-30 19:23:50

我决定通过查看/proc/interrupts.来检查中断信息

在这里,在将边缘设置为GPIO引脚的“上升”后仅仅几秒钟:

代码语言:javascript
复制
# cat /proc/interrupts 
...
 33:        421  gpio-mxc   2 Edge      gpiolib
...

嗯,421个中断已经发生了!

两秒钟后:

代码语言:javascript
复制
# cat /proc/interrupts 
...
 33:        852  gpio-mxc   2 Edge      gpiolib
...

那就可以解释了。中断正在以每秒400左右的速度堆积,肯定比我用Python处理它们的速度要快。

进一步的范围研究表明,信号发生器只输出了1.6V左右,似乎是噪声触发了设备上的输入电路。

当我切换到正确的信号生成器输出并在GPIO引脚上得到一个干净的信号时,我开始获得预期的中断数,python代码正确工作(即在输入的上升边缘之间正确地阻塞了轮询())。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47564734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档