4  ハードリアルタイム制御

車載組込みシステムに求められるリアルタイム特性は,ハードリアルタイム と呼ばれ,最大遅延時間が厳密に指定されます.この特性を実現するための仕組みと実装方式について説明します.

4.1 処理の単位:タスク

プログラムは「タスク」と呼ばれる実行単位で構成されている. 一般的(windowsやlinuxやAndorid)実行単位は,プロセスとスレッドですが,それらとは異なった実行単位です.

プロセスは,独立したメモリ空間を持ちますが,タスクは同じメモリ空間の中に存在します.スレッドは,プロセス内で共通のメモリ空間内に存在しますが,関数やモジュールの変数領域は,OSが提供するスタックメモリやヒープメモリによって独立(相互影響しない)です.ハードリアルタイム制御におけるタスクは,スタックメモリやヒープメモリを使いません.

プロセスやスレッドは,マルチ実行ですが,タスクはシングル実行です.ハードリアルタイム特性を実現するため,多重処理の機能と相互影響を防護する機能を制限している.

実際の製品では,多重処理(例えばCANでの通信や診断機能)が必要になりますが,そのための記述は個別に注意深く実装する必要がある.

4.2 タスクの実行方式:周期タスク

タスクには2種類あり,周期タスクとイベントタスクと呼ばれている.

  • 周期タスク
    • 設定された時間間隔でタスクを無限に繰り返す.
    • 実行管理のキュー管理によって実行順序が決まる.
  • イベントタスク
    • 周期タスクの空き時間にて実行する
    • 一部 POSIX APIも導入(稀)

タスクは,短い処理であり関数相当の処理内容であるが,他のタスクから呼び出されリターンすることは無く,RTOSの周期実行キューの登録状態により起動される. 周期実行キューへの登録は,初期化プログラムがRTOSの組込み関数を使って登録する.

この形態なので,周期タスクでは一般的な結合テストは意味が無い,代わりに,時系列で変化するテストが必要になる.

4.3 タスクの確定性

周期タスクには,確定性が求められる.確定性とは処理時間を含め変動することが無い処理特性です.この特性を守るため,テーブルサーチや再帰処理は使わない. 関数コールの引数は,ソフトウェア工学の規範だと禁止されているアドレス渡ししか使えない.

4.4 協調型のタスク切り替え

周期タスクは,周期的に呼び出されるが,関数のようなリターンは無い.終了は,タスク自身が終了を宣言するまで,実行権を持つ. 一般的な実行管理は,一定時間間隔でラウンドロビン方式であるが,周期タスクは実行中のタスクが終了しないと,次のタスクは起動されない.

異常検出のウオッチドッグ機能でタイムアウトをチェックしているが,この検出は異常状態の検出であり,通常の処理ではない.

4.5 タスク間の同期

組込み諸ステムのI/Oは,ECUに組込まれた電子回路を通して行われる.通常のI/Oと同様に,同時アクセスの禁止や,安定時間のwaitが必要になる. RTOS側にwaitや同期の機能が無いので,タスク間で同期処理を実装する.

ECUの互換性問題のうち,CPU命令の互換性はコンパイラで吸収できるが,I/O関連の互換性は個別に対応する必要があり,かつ確認が電子回路の動作レベルになる.

4.6 プリエンプト機能

優先順位の低い周期タスクを割り込みによって中断できる機能です.実行が次の周期割込みまでに終了しなく,異常状態になるのを防ぐため利用します. イベントタスクにも利用します.

ここ10年ほどで,ほとんどの市販RTOSには機能が入っている.但し,設定しないと動作しないし,設定するとハードリアルタイムのジッタ特性(立ち上がり特性)が悪化する.

4.7 メモリ空間

一般的なOSでは,OSとアプリ間には強力な防護機構があります.プロセス間においても相互影響を遮断する機構があります. ハードリアルタイム処理では,RTOSとタスク間に防護壁はありません.すべてのコードが同じメモリ空間として,静的にリンクして作成されます. 動的な部分は,関数ポインターなどポインタ処理によって実現します. アドレスポインターでの誤操作は,簡単にOS部分を破壊します.

MISRA規範など,コード段階での厳密なレビューが必要なのは,防護機能を使えないことに由来します.

4.8 config によるメモリ空間の変化

メモリ配置が,configによて変化するため