我在Raspberry Pi(嵌入式处理器板)上的Raspbian(一种Linux)上使用Python来监控GPIO输入。
请参阅下面的代码简化版。我在python脚本中有一个无限循环,等待GPIO i / p上发生的事情。这是正确的方法吗?即这是否意味着CPU正在全速运行,只是绕过这个循环,没有其他东西的CPU周期?特别是因为我需要并行运行其他东西(例如浏览器)。
如果CPU忙于做其他事情并且GPIO i / p发生变化,会发生什么? GPIO事件是否存储在某处,以便最终得到服务,或者它是否会丢失?
有更好的方法吗?
(对于你的答案,请注意我是linux的新手,而且是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
答案 0 :(得分:4)
是的,做while True: pass
会烧掉100%的CPU(或尽可能接近它),什么都不做。
根据我的理解(希望这在某处记录),RPi.GPIO模块产生一个后台线程,它等待GPIO并为每个事件调用callback
函数。所以你的主线程真的无关紧要。如果您希望将其作为服务运行,请将其设为sleep
很长一段时间。如果你想以交互方式运行它(在这种情况下你可能希望它更容易取消),sleep
更短的时间,可能是0.5秒,并添加一些方法来退出循环。
如果你可以在主线程中执行GPIO select
,或者获得只能join
的GPIO后台线程的句柄,那就更好了,其中任何一个都不会烧掉CPU一点都不但是,该模块的设计似乎并非如此简单。
但是,查看the source,有wait_for_edge
方法。大概你可以循环GPIO.wait_for_edge
而不是设置回调。但是如果没有文档,并且没有自己测试的设备,我不确定是否要向新手推荐这个。
同时
如果CPU忙于做其他事情并且GPIO i / p发生变化,会发生什么? GPIO事件是否存储在某处,以便最终得到服务,或者它是否会丢失?
好吧,当您的线程没有做任何事情时,GPIO后台线程似乎在等待select
,而select
不会让它错过任何事件。 (根据名称,wait_for_edge
函数听起来可能是边缘触发而不是水平触发,但这是我担心推荐它的部分原因。)