リアルタイムOSの基本動作(★)

[組み込み製品、リアルタイムOS、組み込みドライバーの開発依頼は、フィールドデザインまでお気軽にお問い合わせください。]

リアルタイムOSの基本動作を一言でいいますと、CPUのレジスタをタスクごとに切り替えるだけかと思います。

CPUはPC(プログラムカウンタ)、SP(スタックポインタ)、PSR(状態レジスタ)、汎用レジスタという状態を持っていますが、これをタスクごとに切り替えてあげれば、独立したプログラムとしてCPUで動作しているように振る舞います。

切り替えるタイミングは、割り込みが発生した時とOSシステムコールが呼ばれた時です。

切り替える規則は、優先順位に従って、切り替えてあげます。

切り替えた時のCPUのレジスタの値は、それぞれのタスクが持つスタック上に退避しておきます。再度、そのタスクが実行できるようになったら、そこから取り出して、CPUのレジスタに復帰させます。

やっていることは簡単なのですが、CPUのレジスタ値を変更するため、C言語などの高級言語(?!)ではOSを書けません。必ずアセンブラレベルのコーディングが必要です。また、割り込みのマスクなどCPUの構造を知らないと作ることができません。そのため、少しハードルの高いソフトウェアになっています。


OSの状態

リアルタイムOSのタスクには、下記のようにREADY, RUNNING, WAITという3つの状態があります。
複数のタスクでCPUを取り合うため、動作中のタスク(RUNNING)、 実行待ちのタスク(READY)、資源待ちのタスク(WAIT)です。


OSの状態遷移シーケンス

OSの状態は下記のように変化していきます。変化するトリガは、システムコールか割り込みしかありません。RUNNINGとWAITの状態は、CPUで実行中か、何かを待っているかというのでわかりやすいのですが、READYの状態はちょっとわかりずらいです。
READYというのは実行できるが、他の優先度の高いタスクが動作している状態です。そのケースは、RUNNINGで実行中に割り込みが発生した場合だけ起こります。


最近のリアリタイムOSの使い方

前述のようにリアルタイムOSはタスクに優先度があって動作することが1つの特徴となっていますが、最近の組み込み用CPUは処理速度が速いことや、ハードウェアがある程度自動でデータ処理をできるようになったため、すべて同じ優先度で動かしても問題ありません。
CPUの処理速度が上がったことにより、すべての処理がシステムの要求する応答時間内に終わらせることができてしまうためです。よって、優先度の低い処理から始めても、優先度の高い処理から始めても、システムとしての結果は変わらないということになります。

昔(1990年代)のCPUでは、クロックが8MHz、8bitバスなどというのが一般的で、優先度を考えずに処理をしてしまうと、優先度の高い処理が間に合わなくなり、システムとして破綻してしまうことがありました。そういうケースでは、リアルタイムOSの優先度は大活躍していました。
また、昔のCPUのペリフェラルハードウェアは、自動でプロトコル処理をすることもなく、バッファやDMA機能がなかったため、受信したデータはすぐに処理しないと上書きされてしまうなどの問題が発生していました。
半導体プロセスの微細化が進んだことで、消費電力が劇的に減り、動作周波数もあげることができ、バッファなど面積を食う機能をいくらでも入れることができるようになり、優先度の問題はいつのまにか解決してしまいました。

そのため、最近のリアルタイムOSを使うケースは、機能をタスクに分けてモジュール化することができる点にメリットが置かれています。多くの人数で開発できたり、ソフトウェアの構造をシンプルにできたり、不具合の影響を最小限に留めることができたりと、便利なことがいろいろあります。

とは言っても、100kHz(10us毎)で処理をしなければならない場合などは、優先度を高くして、必ず処理が終わるように設計しないとなりませんので、優先度を使うことはたまにあります。