連載7-SOLIDで使えるリアルタイムOS
前回まで、主にメモリアクセス系の話をしてきました。
今回は、OSカーネルの話です。
1.リアルタイムOS
SOLIDは、OSカーネルとして、μITRON仕様のリアルタイムOSを採用しています。
μITRON仕様のリアルタイムOS といっても、種類がありますよね。
SOLIDでサポートしているのは、オープンソースのTOPPERSです。
※FreeRTOSのサポートもあるようです。
具体的には、
・シングルコアプロセッサ向け(TOPPERS/ASP3)
・マルチコアプロセッサ向け(TOPPERS/FMP3、TOPPERS/FMP)
が使えます。
どちらも、32bit(AArch32), 64bit(AArch64)で使用できます。
そして、リアルタイムOSなので、TOPPERSも以下の特色を有します。
リアルタイム性⇒入力に対して即時に応答する
マルチタスクの実行
優先度を考慮したタスクスケジューリング
スモールフットプリント
カーネルシステムコール可
また、加えて、TOPPERS には以下の特色もあります。
Ticklessカーネル採用(TOPPERS第三世代カーネルの TOPPERS/ASP3,
TOPPERS/FMP3)
具体的に見ていきます。
1.1 即時に応答
京都マイクロコンピュータ社で興味深い実験を行った資料を頂いたので、ご紹介します。
Linuxとの対比です。両社同じ評価ボードを使用しています。
[実験内容]
GPIOを1m秒周期で High-⇒Lowを行う。
High(500μ秒) ⇒ Low(500μ秒) ⇒ High(500μ秒) ⇒ Low(500μ秒)…
波形観測し、どれだけ正確に動作しているかを確認。
☆ただし実際の使用を鑑み、他にそこそこ負荷のかかるタスクを実行させておく
[結果]
・SOLID(TOPPERS)
※CPU4つのうちの2つでLinux、のこり2つでSOLIDが動いています。
この動画は、SOLID上で動作しているアプリケーションでLED制御しています。
・Linux
※先程と同様、CPU4つのうちの2つでLinux、のこり2つでSOLIDが動いています。
この動画は、Linux上で動作しているアプリケーションでLED制御しています。
Linuxの方は揺らぎがありますが、SOLID(TOPPERS)の方は揺らぎなく出ているように見えます。
これが、リアルタイムOSの大きな特徴である「リアルタイム性」です。
1.2 マルチタスクを実行
TOPPERSはμiTRON仕様のリアルタイムOSなので、acre_tsk()関数でタスクを生成、act_tsk()関数でタスクを起動、、、という風に、通常のμiTRON仕様のリアルタイムOSでよく見るシステムコールにより複数タスクを実行することができます。
以下のTOPPERS仕様書に、使い方等細かく記載されています。
https://www.toppers.jp/docs/tech/tgki_spec-321_richtext.pdf
ちなみに、SOLIDでは、デバッグ機能として、実行⇒ブレーク時にそれらタスクの情報を見ることができます。
試してみましょう。
起動タスク:
タスク1: エントリ関数child_task()
タスク2: エントリ関数child_task()
タスク3: エントリ関数child_task()
ルートタスク:エントリ関数root_task()
タスク1,2,3で実行する関数は、以下としました。
void child_task(intptr_t exinf)
{
int n = (int)exinf;
ER ercd;
for (;;){
WAIT_SEC(1);
}
}
child_task()関数内のWAIT_SEC(1); にブレークポイントを設定して実行してみます。
ブレーク後、再実行してみます。
各タスクが、かわるがわる実行されていくはずです。
では、実行してみましょう。
①1回目のブレーク時
タスク1がRunning状態で、実行されている関数はchild_task()であることがわかります。
さらに、タスク2と3はReady状態、ルートタスクはWaiting状態になっています。
②2回目のブレーク時
タスク1が中断されWaiting状態になりました。スタックに何やら積まれましたね。
タスク2がRunning状態になりました。
ルートタスクはWaiting状態です。
③3回目のブレーク時
タスク2がWaiting状態になり、スタックに何やら積まれました。
タスク3がRunning状態になりました。
タスク1はまだWaiting状態ですね。
ルートタスクもWaiting状態です。
④4回目のブレーク時
再びタスク1がRunning状態になり。
タスク2と3がReady状態ですね。順番が来るのを待っている状態ですね。
ルートタスクはWaiting状態です。
⑤child_task()関数内のブレークを削除し、ルートタスク内でブレーク
ルートタスクが動作しているところを見たいので、child_task()関数内のブレークを削除した上で、ルートタスク内にブレークを設定し実行します。
ルートタスクがRunning状態になりました。
かわるがわるタスクが実行されていることがわかります。
1.3 タスク優先度
作成したタスクに優先度をつけることができます。
先程の例では、すべてのタスクの優先度が10でした。
より応答性能を上げたいタスクに対し優先度を高くし、そうでもないタスクの優先度を低くしたりすることができます。
1.4 メモリフットプリント
当然のことながら、そのファームウェアで何をしたいのか、によりますが、メモリフットプリントが基本的にLinux等のようなリッチなOSよりも小さいです。
ご参考に、手元のサンプルアプリで見てみると、OSやドライバすべて込みで、コード領域が180KBくらいです。
※手元のサンプルは、MMUドライバ等、いろいろ入ったフルスペックのOSです。
シュリンクすればもっと小さくなります。
1MB全然行っていませんね。
1.5 カーネルのシステムコール
先程、タスクを起動するところで触れましたが、タスク生成、起動等のシステムコールが準備されています。
その他にも、タスク間通信、時間管理機能、、、等々、いろいろあります。
そのことについても、以下のドキュメントの「4. カーネルAPI仕様」に記載されています。
https://www.toppers.jp/docs/tech/tgki_spec-321_richtext.pdf
こういったTOPPERSの持つ機能は、当然ですが、使う事ができます。
一部、SOLIDにおいて機能拡張、変更等されていますが、そちらについては以下URLに記載されています。https://solid.kmckk.com/SOLID/doc/latest/os/kernel/api_spec.html
1.6 Ticklessカーネル
TOPPERS第三世代は、Ticklessカーネルだそうです。
え?インターバルタイマなし?
OSにはタイマが常時動いていて、一定の間隔(インターバル)でタイマ割り込みを発生させる。そしてその定期的な割り込みで、カーネルはタスクスケジューリング等を行う(タスク生成時や割り込みは別として)、というのが常識だと思っていたのですが!
ずいぶん前から、LinuxカーネルもTicklessで動けるようになっているではありませんか!
確かに、消費電力&リアルタイム性という意味では、常時タイマ割り込み発生するのは少し邪魔ではありますよね。
タイマ割り込みで発生する定期的な割り込みが絶対に発生する、という事になるので、その間はCPUが動かなければなりません。
Ticklessカーネルでは、基本的にイベントドリブン。
必要な時のみ、必要なタイマを起動させる。
なので、必要な時に起動させる手間がかかるのは仕方ないとして、必要がない時はCPUはずーっと何もしないので、消費電力は抑えられる&即時応答できる。さらに必要以上にタイマ割り込みルーチンが動かないので、キャッシュの入れ替えが少なくなり効率良くなる。
もちろん、これらはカーネルで行う事なので、アプリ側から特に気を使うことなく今まで通りの使い方でOKです。
TOPPERS第三世代は、そういうカーネルとして動作することも可能との事です。
2.SOLIDのCPU抽象化レイヤ
SOLIDでは、多種多様なCortex-A CPUに対応できるよう、CPUを抽象化するレイヤを持っています。
このレイヤは「SOLID Core Service」と呼ばれています。
以下は公式のSOLID紹介資料内にあるブロック図です。
TOPPERSの下位部にあることがわかります。
SOLIDでは、SOLIDでは、TOPPERSがCPUのリソースをアクセスする必要がある際、SOLID Core Serviceを介してアクセスができるように設計されています。
SOLID Core Serviceは、CPUを操作するための様々なAPIが準備されており、それらは以下のURLに記載されています。
https://solid.kmckk.com/SOLID/doc/latest/os/core-service.html
前回ご紹介した、MMU関連APIも、SOLID Core ServiceのAPIです。
その他にも、割り込みコントローラ制御、タイマ制御等、リアルタイムOSを動作させるのに欠かせない機能が盛り込まれています。
それだけでなく、ユーザ作成タスクからも使えるようになっています。
例えば、割り込みコントローラを制御したいのは、カーネルだけではありませんよね。
ユーザ作成タスクからでも、簡単に割り込みを使えるようにするため、SOLID Core Serviceはユーザ作成タスクからもコールすることができます。
3.まとめ
今回は、SOLIDで動くリアルタイムOSと、そのさらに下位層でCPUを抽象化しているレイヤであるSOLID Core Serviceについてご紹介しました。
今までにご紹介したMMU関連APIやアドレスサニタイザ用API等も、このSOLID Core Serviceに入っています。
リアルタイムOSを動かすために必要になる、CPU扱うためのAPIが一通りここにそろっているという事ですね。
次回はそんなSOLID Core Serviceの機能の一つ、割り込みAPIについてご紹介する予定です。
この記事が気に入ったらサポートをしてみませんか?