#はじめに
pythonで赤外線センサの情報を受け取ってイベントを発火したいってなったときに出てきた割り込み処理。
なんのこっちゃ分らんかったから備忘録的に調べてみる。
##割り込み処理(割り込み)とポーリング
###割り込み
割り込み(わりこみ)とは、コンピュータがその周辺機器などから受け取る要求の一種である。現在の多くのCPUは、割り込みを処理するための機能を備えている。
###ポーリング
通信やソフトウェアにおいて、競合を回避したり、送受信の準備状況を判断したり、処理を同期したりするために、複数の機器やプログラムに対して順番に定期的に問い合わせを行い、一定の条件を満たした場合に送受信や処理を行う通信及び処理方式のことである。
##どっちでもセンサの情報受け取って処理できんじゃん
でもポーリングは駄目らしい
割り込み処理実装しろって言われた。
なんでー?
##割り込み処理の方がいい理由
###1.CPU資源の有効利用
周辺機器の速度はCPUの処理速度より格段に遅いため、周辺機器が処理を行っている間、CPUが他の処理を行ったほうが効率がよい。その場合、周辺機器の処理の終了をCPU側から定期的にチェック(ポーリング)するのは、他の処理の効率を落とすため望ましくない。このため、周辺機器の側から割り込みによって処理の終了を通知する方法がとられる。
###2.応答性の向上
キーボード、マウスなどのユーザインターフェースは、入力の遅延や入力漏れが致命的な欠陥になる。この場合は割り込みを使ってユーザからの入力を確実に処理する必要がある。コンピュータがフリーズした場合でも、マウスカーソルの移動だけが反応することがあるが、これは割り込み処理だけが機能していることになる。
###3.例外処理の効率化
周辺機器に障害が生じた場合、割り込みを用いることでプログラム側に障害を速やかに伝えることが可能になる。またプログラム上でも例外処理を本来の処理と分離して記述することを容易にする。
##割り込みにもいろいろ種類があった
##割り込みの分類
- ハードウェア割り込み - 割り込み要求端子の変化によりCPU外部から発生する
- ノンマスカブル割り込み(NMI)
- マスカブル割り込み(狭義のIRQ)
- ソフトウェア割り込み(SWI) - CPU内部の要因で発生する
- 狭義のソフトウェア割り込み(狭義のSWI) ー CPUの割り込み命令によって発生する
- 例外、トラップ - 割り込み命令以外の要因で発生する
####まぁようわからんが色々あるんやな!
##実装方法
####callback関数
####wait_for_edge
の二つがある。
##callback
import RPi.GPIO as GPIO
import time
class CallBack:
def __init__(self):
# 4番pinを入力、プルアップに設定
pin = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.IN, GPIO.PUD_UP)
# 割り込みイベント設定
# 割り込みを検知するpin番号、エッジ、バウンスタイムを設定
GPIO.add_event_detect(pin, GPIO.RISING, bouncetime=1000)
# コールバック関数登録
#pin ⇒ GPIO4番ピン
#self.my_callback_two ⇒ 割り込み検知後に実行される関数名
GPIO.add_event_callback(pin, self.my_callback_one)
GPIO.add_event_callback(pin, self.my_callback_two)
def my_callback_one(self, channel):
print('Callback one')
def my_callback_two(self, channel):
print('Callback two')
def callback_test(self):
while True:
time.sleep(1)
cb = CallBack()
cb.callback_test() # 割り込みイベント待ち
##wait for edge
import RPi.GPIO as GPIO
class CallBack:
def __init__(self):
# 4番pinを入力、プルアップに設定
self.pin = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.pin, GPIO.IN, GPIO.PUD_UP)
def callback_test(self):
while(True):
# 立下りエッジイベント、タイムアウトイベント待ち
# pin番号、イベント、タイムアウト時間、バウンスタイムを設定
# タイムアウトで設定した時間内に割り込みがあれば、else内の処理が実行。
# 割り込みがなければ、if isr is None内の処理が実行されます。
isr = GPIO.wait_for_edge(self.pin, GPIO.FALLING, timeout=5000, bouncetime=1000)
if isr is None:
# 5秒間割り込みがないときに実行される
print("5秒間割り込みなし")
else:
# 割り込みがあったときに実行される
print("割り込みあり")
cb = CallBack()
cb.callback_test()
####どっちがいいとかはまだわからん。以上