割り込みとポーリング | 組み込み

目次

割り込みとポーリング

組み込みソフトにおいて、周辺機器(ペリフェラル)からのイベントを検知する2大手法が「割り込み(Interrupt)」と「ポーリング(Polling)」です。システムのリアルタイム性や処理効率を大きく左右するため、それぞれの特性を理解して適切に使い分けることが不可欠です。

ポーリング

CPUが主導権を持ち、メインプログラムの実行フローの内部において、特定のステータスレジスターやフラグビットの値を定期的に、継続的に監視する手法です。

割り込み

周辺機器が主導権を持ち、イベントが発生した瞬間にCPUへ通知する手法です。

日常的な例をあげると、ご飯が炊けたかを5分毎に確認しに行くのがポーリングで、ご飯が炊けた音を聞いたら確認しに行くのが割り込みです。

割り込みとポーリングの比較

メリットとデメリット

スクロールできます
ポーリング割り込み
リアルタイム性【低い】
監視周期に依存します。また応答が遅れたり、応答時間にムラが発生したりします。
【高い】
即座に応答できます。また応答に要する時間も安定します。
CPUの負荷【高い】
いつイベントが発生するかわからないため、常に監視を続ける必要があります。
【低い】
イベントがない間はメイン処理に集中できます。
消費電力【高い】
CPUは常にフル稼働しています。
【低い】
イベント待ちの間はスリープモードに移行することができます。
実装の難易度【低い】
上から下に流れる単純なコードになります。
【高い】
排他制御の考慮が必要になります。

処理例

周辺機器から受信したデータを処理する例です。ポーリングと割り込みで、同じ番号は同じ処理を表します。

割り込みについて

割り込み処理の流れ

割り込みが発生すると、CPUは実行中のメイン処理を一時中断し、割り込みハンドラ(ISR:Interrupt Service Routine)を実行した後、再び元のメイン処理に戻ります。この一連の動きは大きく4つのフェーズに分かれます。

  1. 割り込み要求の検知
    ・周辺機器(GPIO、タイマーやUART)から割り込みの通知が入ります。
    ・このとき複数の割り込みが同時に発生した場合、割り込みの優先度(Priority)を比較し、最も優先度の高いものをCPUに通知します。
  2. レジスターやフラグの退避
    ・CPUは実行中の命令をキリの良いところまで進めます。
    ・ISR処理が終わった後に、元の位置に元の状態で戻れるように、現在使用中のレジスター(プログラムカウンターや各種レジスターなど)の値をスタックメモリーに退避します。
    ・CPUは発生した割り込みに対応するベクターテーブルを参照し、該当する先頭アドレスを取得します。
  3. 割り込みハンドラの実行
    ・ベクターテーブルから取得したアドレスへジャンプして、ISRを実行します。
  4. レジスターやフラグの復帰
    ・ISRを終えると、スタックメモリーに退避しておいたレジスターの値がCPUに戻され、何事もなかったかのようにメイン処理を再開します。

割り込みの注意点

割り込みは強力な機能ですが、注意点も多くあります。

  1. 割り込みハンドラ(ISR)内で重い処理を実行しない
    ISRの動作中メイン処理は止まっています。時間のかかる処理を割り込み内で実行すると、他の重要な割り込みをブロックし、システム全体のリアルタイム性を損ないます。
  2. 優先度の割り振り
    優先度を適切に割り振らないと、重要度が低い割り込みが先に実行されてしまいます。重要度の高い処理や、リアルタイム性が厳しい割り込みは優先度を高く設定する必要があります。
  3. スタックオーバーフローに気を付ける
    割り込みが発生するとレジスターをスタックメモリーに退避します。さらにISRの中でローカル変数を大量に定義したり、関数を深くコールしたりするとスタック領域を急激に消費します。多重割り込みを許可している処理系では特に注意が必要です。
  4. volatile修飾子の明記(C言語の場合)
    ISR内で書き換えるグローバル変数はメイン処理からみると「いつの間にか値が変わっている変数」になります。このためコンパイラーが最適化によって処理を省いてしまう恐れがあります。これを防ぐため、volatile修飾子を付与する必要があります。

コメント

コメントする

CAPTCHA


目次