【问题标题】:Efficiency of infinite loop to service GPIO无限循环服务 GPIO 的效率
【发布时间】:2013-08-09 23:28:07
【问题描述】:

我在 Raspberry Pi(嵌入式处理器板)上的 Raspbian(一种 linux)上使用 Python 来监控 GPIO 输入。

请参阅下面我的代码的简化版本。我在 python 脚本中有一个无限循环,等待 GPIO i/p 上发生某些事情。这是正确的方法吗? IE。这是否意味着 CPU 正在全力运行,只是围绕这个循环,没有 CPU 周期用于其他东西?特别是因为我需要并行运行其他东西(例如浏览器)。

如果 CPU 忙于做其他事情并且 GPIO i/p 发生变化,会发生什么情况? GPIO 事件是存储在某处以便最终得到服务,还是只是丢失了?

有更好的方法吗?

(对于您的答案,请注意我是 linux 新手,v. python 和实时编程新手)

#!/usr/bin/python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def ButtonHandler(channel):
    print "Button pressed " + str(channel)
    # do stuff here

GPIO.add_event_detect(16, GPIO.FALLING, callback=ButtonHandler, bouncetime=200)

while True:
    pass

【问题讨论】:

标签: python real-time raspberry-pi


【解决方案1】:

是的,执行 while True: pass 将消耗 100% 的 CPU(或尽可能接近它)什么都不做。

据我了解(希望这已记录在某处),RPi.GPIO 模块生成一个后台线程,该线程在 GPIO 上等待并为每个事件调用您的 callback 函数。所以你的主线程真的无关紧要。如果您希望它作为服务运行,请将其设为sleep 很长一段时间。如果您想以交互方式运行它(在这种情况下,您可能希望更容易取消),sleep 更短的时间,可能是 0.5 秒,并添加一些退出循环的方法。

如果您可以在主线程中执行 GPIO select,或者获取 GPIO 后台线程的句柄,您可以只使用 join,那就更好了,其中任何一个都不会烧掉 CPU。但是,该模块的设计似乎并不容易。

但是,查看the source,有一个wait_for_edge 方法。大概你可以循环 GPIO.wait_for_edge 而不是设置回调。但是如果没有文档,也没有设备来测试自己,我不确定我是否愿意向新手推荐这个。

同时:

如果 CPU 忙于做其他事情并且 GPIO i/p 发生变化,会发生什么情况? GPIO 事件是存储在某处以便最终得到服务,还是只是丢失了?

好吧,虽然你的线程没有做任何事情,但 GPIO 后台线程似乎正在等待select,并且select 不会让它错过事件。 (根据名称,wait_for_edge 函数听起来可能是边缘触发而不是电平触发,然而,这也是我对推荐它持谨慎态度的部分原因。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2023-03-28
    • 2013-02-02
    • 2012-03-20
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    相关资源
    最近更新 更多