割り込み、ポーリング、タスクによって処理の優先度を分ける


割り込み、タスク・ポーリング、タスク毎に、処理の高速性に応じて処理を分けるべきである。

  1. 10uSec から 500uSec での応答速度が必要なときは、その処理は割り込みルーチンの中に記述する。
  2. 500uSec から 10mSec での応答が速度が必要ときは、その処理はポーリング・ルーチンに記述する
  3. 10mSec を超えて遅いシーケンシャルな処理はタスクとして記述する。

必要な応答速度に応じて、処理す場所を変えるべきである。割り込みルーチンに記述するのは、uSec オーダーでの高速な応答が必要な処理に限って記述すべきである。こうすることで、以下の効果が得られる。

  1. 割り込み処理それぞれの CPU 占有時間を短くすることで、他の割り込み応答を高速にする。
  2. 割り込み処理と非割り込み処理の間で交互に参照するデータを最小にする。割り込みルーチンをカプセル化して、ボラタイルなデータの発生を最小にする。

10mSec 程度まで速さで発生する変化を検出したり応答したりする処理を記述するときポーリングをつかう。中断していたタスクを再開させたりするタスクの同期処理にはポーリングが適している。ポーリング処理以上に高速に処理しても、タスクの応答が早くできないからである。

割り込みルーチンの中からタスクの開始・再開などのタスク制御を禁止した。これの対策の意味が、タスク・ポーリング関数の導入には有る。しかし、元々はタスクの制御は、割り込みの中で行う程に高速に行う必然性はなかった。

  1. タスクの応答速度は、全体のポーリング速度以上にはできない。
  2. CPU が一つだけのときは、プリエンプティブにして、タスクに多重の優先度を設けても、タスクを高速に応答させる効果はない。

からである。

ボタン入力のような数 10mSec の応答しか必要ない入力変化の検出にも、ポーリングを使うべきである。割り込みを使うべきではない。ボタンのような機会接点の入力には 1mSec 程度のチャタリングがある。チャタリング周期以上に高速に取り込んでも、意味がない。機械接点入力のサンプリングは 10mSec の周期であれば十分である。

                        ↓チャタリング                          ↓チャタリング
スイッチ ON            ┌┐┌─────────────────┐┌┐  
         OFF ─────┘└┘                                  └┘└──────
サンプリング    ↑              ↑              ↑              ↑            ↑

ましてやボタン入力を割り込みで高速にとりこみ、その後で、チャタリングをマスクするためのフィルター・タイマー・プログラムを追加するなどといったことは、CPU タイムやROM 領域の無駄使いである。

タスクには数 10 mSec 以下の応答速度で良い、シーケンシャルな処理を記述する。ここに記述するコードをできるだけ多くすべきである。割り込みルーチンやポーリング・ルーチンに記述するほど高速な処理が必要なければタスクで記述すべきである。

人間は 50mSec の応答と、 10mSec の応答を区別できない。多くの人間に対するインターフェースは 50mSec 以内に応答してやれば良い。これらはタスクとして記述してやれば十分である。割り込みルーチンやポーリング・ルーチンで記述すべきではない。

割り込みと、タスク・ポーリング関数とタスクとが、密接に関連した一つの制御対象として括れるならば、それらを一つのファイルに纏めるべきである。


以上に述べたような割り込みルーチン、ポーリング・ルーチン、タスクへの処理の分担させることで、以下の効果が得られる。全体として、プログラムの信頼性・安定性が増す。

  1. CPU タイムの適切な割り振りによる、結果のしての高速処理
  2. 危険な割り込みルーチンのカプセル化。
  3. ボラタイルなデータの最小化

このように処理を分担させることてやれば、ノンプリエンプティブな単純な RTOS でも十分に複雑・大規模なプログラムを記述できるようになる。