見出し画像

連載7-SOLIDで使えるリアルタイムOS

前回まで、主にメモリアクセス系の話をしてきました。

今回は、OSカーネルの話です。


1.リアルタイムOS

SOLIDは、OSカーネルとして、μITRON仕様のリアルタイムOSを採用しています。

μITRON仕様のリアルタイムOS といっても、種類がありますよね。
SOLIDでサポートしているのは、オープンソースのTOPPERSです。

https://www.toppers.jp/

※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についてご紹介する予定です。


この記事が気に入ったらサポートをしてみませんか?