
現在のコンピュータシステムは「割り込み」なくしては実現できないといっても過言ではないんだ。特に、組込みでは「割り込み」を駆使したプログラミングが必須となる。
今回は「割り込み」とはどういうものか、対極にある「ポーリング」という手法とあわせて紹介していこうと思う。
「ポーリング」に関して
まずは、携帯電話を例に考えてみよう。例えば、こんな動作をするよね。
- キーを押すと、画面が切り替わったり、押した文字が表示されたりする。
- 電話の着信があると、音や振動、画面の表示などで知らせてくれる。
- 電波状況は、リアルタイムに画面のアイコンに反映される。
- しばらく操作しないでおくと、液晶画面が暗くなる。
これらに共通する点は「なにかイベントが起こったときに対応した処理をする」ということだ。それぞれのイベントは
- キーが押された
- 電話の着信があった
- 電波状況に変化があった
- 一定時間、操作されなかった
ということになるよね。
同様の動作は、携帯電話以外でもパソコン、テレビ、ビデオ、ゲーム機など、ほとんどのデジタル機器でよく見ることができる。これらのイベントには基本的に互いに関連がなく、システムからすれば「いつ起こるかわからない」ものばかり。このようなイベントを「非同期イベント」と呼ぶんだ。
コンピュータシステムは、このような「いつ起きるか分からない」たくさんの非同期イベントを監視しながら動いているんだ。でも、どうやっていると思う?まず思いつくのは、「イベントが発生しているかを定期的にチェックする」という方法。これを「ポーリング」という。
でも、チェックする周期が長いと、イベントの発生から検出までにタイムラグが生じてしまう。キーを押してから画面に文字がなかなか出なかったら、イライラするよね?このようなイベントはすぐに応答してもらわないと困るけど、だからといってチェック周期を短くすると、CPUがその処理ばかりやることになってしまって、他の処理に支障がでてしまうんだ。
このように、ポーリングで多くのイベントをさくさくと処理するのはちょっと無理があるというのがわかると思う。そこで、出てくるのが「割り込み」なんだ。
「割り込み」とは
割り込みは、CPUとOSでサポートされる機能で、その名のとおり「今やっている処理に割り込んで特別な処理を実行する」こと。「仕事中に電話がかかってきた状態」と考えるとわかりやすいと思うよ。

Aくんが集中して開発作業をやっているところに電話がかかってきました。
電話に出てみると、お客さんからのクレームです。
Aくんはときに謝りながら一生懸命に対応します。
やっと電話が終わり、元の作業に戻ろうとしてAくんは思いました。
「あれ、さっき何をやってたんだっけ?」
そういえば電話に出る直前にメモを残していました。
メモを見て思い出したAくんは開発作業を再開しました。
「電話に出る」=「割り込みを処理する」であることは分かったかな。実際の割り込み処理のシーケンス(動作の順序)も似たような動作になるよ。
- あるデバイスでイベントが発生すると、CPUに割り込み信号が通知される。
- CPUは割り込み信号を受けると、現在の処理を中断。このとき後で戻ってこられるように現在の状態を保存(退避)しておく。
- 対応する割り込み処理を行う。この処理を行う関数は、割り込みハンドラや割り込みサービスルーチン(ISR)と呼ばれ、あらかじめOSに登録しておく。
- 割り込み処理が終わると、状態を復帰させて、元の処理を継続する。
このように割り込みは、自動的に登録しておいた処理が実行される仕組みなんだ。つまり、ポーリングのようにソフトウエアで監視を行う必要がない。
各イベントが起こったときの処理を記述した割り込みハンドラをあらかじめ用意しておけば、いろいろなイベントがいろいろなタイミングで発生しても、それぞれ勝手に処理してもらえるということになる。これは便利だよね!

割り込みは一種のマルチタスク手法なんだ。かつて、MS-DOSなどの非マルチタスクOSの環境しかなかった頃は、1個のメイン (ループ)プログラムと複数の割り込み処理を駆使して、同時並列的な処理を実現していたんだ。現在でも、OSを使わないような小規模マイコンシステムでは同じような構造になっているはずだ。大変便利な割り込みだけど、やっぱりデメリットはある。
- ハードウエアに依存する。
各イベントに対応した割り込み信号がCPUに通知されるようにハードウエアを設計しておかなくてはならない。ソフトウエア側も、どのデバイスの割り込みにどの割り込み番号が割り当てられているかを理解する知識が要求されるんだよ。 - OSに依存する。
割り込みハンドラを登録する時に指定する番号(ベクタともいう)や割り込み制御関数の仕様は、OSによって異なっているんだ。 - 割り込みハンドラにはご法度がある。
長時間の処理はダメ、待ち状態になってはいけない、呼んではいけない関数がある、などだ。
普通は、割り込みハンドラでは必要最小限の処理のみを行い、別のタスクに通知して、メインの処理はそっちでさせるように実装すべきなんだけどね。
ついでに、ポーリングのメリットも挙げておこう。割り込みとポーリングは状況に応じて、使い分けることが重要なんだ。
- ハードウエアに依存しない。ソフトウエアだけで実現できる。
- ループするだけなので、簡単に実装できる。
- 割り込みを発生できないイベントも監視できる。

割り込みは、使いこなすには少しコツがいるけど、組込み開発では避けて通ることはできないんだ。実際には、いろんな経験をつんでいくことが必要だけど、まずはイメージだけでもつかんで、考え方になじんでほしい。
-
- 第1回 組込みシステムのこれから
- 第2回 IoTの成功はセキュリティ次第
- 第3回 組込みでもGPUやFPGAと早めに親しんでおこう
- 第4回 電子産業の紅白歌合戦、CEATECで垣間見えた未来
- 第5回 小口開発案件の集合市場、IoTの歩き方(上)
- 第6回 小口開発案件の集合市場、IoTの歩き方(下)
- 第7回 徹底予習:AI時代の組込みシステム開発のお仕事
- 第8回 いまどきのセンサー(上):ありのままの状態を知る
- 第9回 いまどきのセンサー(下):データを賢く取捨選択する
- 第10回 組込みブロックチェーンの衝撃(上)
- 第11回 組込みブロックチェーンの衝撃(下)
- 第12回 エネルギーハーベスティングの使い所、使い方
- 第13回 「人を育てる」から「道具を育てる」へ、農業から学ぶAI有効活用法
- 第14回 CPS時代に組込みシステム開発に求められることとは
- 第15回 次世代車のE/Eアーキテクチャに見る組込みの進む道
- 第16回 RISC-Vが拓く専用プロセッサの時代
- 第17回 振動計測の大進化で、熟練エンジニアのスキルを広く身近に
-
- 零の巻:組込みというお仕事
- 壱の巻:2進数と16進数を覚えよう!
- 弐の巻:割り込みとポーリング
- 参の巻:printf()が使えない?
- 四の巻:これにもIntelが入ってるの?
- 五の巻:Endianってなに?
- 六の巻:マルチタスクとは
- 七の巻:スタックってなあに?(1)
- 七の巻:スタックってなあに?(2)
- 八の巻:メモリを壊してみましょう
- 九の巻:コードが消える?~最適化の罠~
- 拾の巻:例外が発生しました
- 拾壱の巻:コードサイズを聞かれたら
- 拾弐の巻:キャッシュは諸刃の剣
- 拾参の巻:デバイスにアクセスするには
- 拾四の巻:セキュリティってなに?(1)
- 拾四の巻:セキュリティってなに?(2)
- 拾四の巻:セキュリティってなに?(3)
- 拾五の巻 :DMA対応と言われたら(1)
- 拾五の巻 :DMA対応と言われたら(2)
- 拾六の巻:ヒープとスタック
- 拾七の巻:フラグメンテーション
- 拾八の巻:CPU起動とブートローダ
- 拾九の巻:kmとKByteの「kとK」
- ビリーへの質問:DMAとキャッシュの関係
- ビリーへの質問:スタックオーバーフローについて
- ビリーへの質問:CPUレジスタについて