RTOSとベアメタルの設計が変わるポイント

組み込み開発で、ベアメタルとRTOSのどちらを選ぶかは、設計のあり方を大きく変える重要な判断になります。単純なループ処理で動かすベアメタルと、複数のタスクを並行して動かすRTOSでは、割り込み処理・周期処理・共有資源の管理・デバッグといった場面での設計思想が大きく異なるからです。

この記事では、ベアメタルとRTOSの違いを4つのポイントに絞って整理していきます。

ベアメタルとRTOSの設計思想の違い

1本のフローで動くベアメタル設計と、複数タスクを疑似並列処理するRTOSを使用した設計の比較図

ベアメタルとは、OSを介さずにハードウェアを直接制御する実装方式です。処理はsuperloop(無限ループ)を軸に組まれることが多く、実質的には1本のフローで動きます。単純なシステムであれば十分機能しますが、処理が増えるにつれて管理が難しくなります。

一方、RTOSは複数のタスクを独立した実行単位として管理し、スケジューラが優先度と状態に応じて切り替えることで疑似並列処理(マルチタスク)を実現する方式です。

近年の組み込み機器は通信・センサデータ処理・UIの更新を同時にこなすことが求められるようになってきました。そのため、単一フローのベアメタルでは管理しきれないケースが増えています。こうした複数機能の同時処理にはRTOSのマルチタスク機構が有効です。

また、通信などの開発で使われるミドルウェアは、RTOSの使用を前提としているものもあり、このような場合は、RTOSの使用が必須になります。

ポイント①:割り込み処理の設計

ここからは、ベアメタルとRTOSの違いを4つのポイントで比較していきましょう。ポイントの1つ目は、割り込み処理の設計の違いです。

ベアメタル:ISR内に処理を詰め込む設計

ベアメタルではISR(割り込みハンドラ)内に通信処理やデータ解析ロジックを直接記述することが比較的多くなります。割り込み発生時にすべての処理を完結させようとするため、ISRが長くなり、別の割り込みの応答遅延(レイテンシの悪化)を招きます。

処理が増えるほどISRは肥大化し、タイミング管理は複雑になります。

RTOS:ISRは通知だけで処理はタスクに委譲する

RTOSでは「ISRは最小限の処理だけ」が鉄則です。フラグのセットやキューへの送信など、タスクを起こすための通知だけをISR内でおこない、実際の処理はタスク側に委譲します。

「割り込みに対して即時応答しないといけない」といった処理は、タスクの優先度を高くする必要があります。こうすることで割り込みレイテンシを短く保ちながら、複雑な処理をタスクのコンテキストで安全に実行することが可能です。

ポイント②:周期処理の実装

ポイントの2つ目は、周期処理の実装による違いです。

ベアメタル:superloopは処理増加で周期精度が崩れる

ベアメタルの典型実装はsuperloop(無限ループ)にタイマ割り込みを組み合わせたフラグ管理です。処理量が少ない間は問題ありませんが、ループ内の処理が増えると、フラグを検出してから実行を開始するまでの遅延が変動し、起動タイミングに「ジッタ」が生じます。

さらに、処理時間が周期を超えると次の周期に食い込み、デッドラインミスを引き起こします。また、タイマ割り込みを使わず、単純な遅延処理でループを回す実装では注意が必要です。「処理時間+遅延時間」が1周期となるため、処理時間の変動がそのまま周期のずれとなって積み上がる「累積ドリフト」が発生します。

RTOS:周期スケジューリングでドリフトなく周期を保つ

一方、RTOSには累積ドリフトを防ぐための周期実装手段が複数用意されています。

手段 内容
xTaskDelayUntil(FreeRTOS) 前回起床時刻を基点に次の起床時刻を計算するため、処理時間の影響を受けず累積ドリフトが生じない。旧来のvTaskDelayUntilを置き換える形で導入されたAPIで、戻り値で実際に遅延したかを判定できる。
タイマ割り込みでフラグ・セマフォを立ててタスクを通知する方式 タイマ割り込みISR内でフラグを立てるかバイナリセマフォを操作し、タスク側でそれを待ち受ける。ISRとタスクの分離を保ちながら周期を制御できる汎用的な方式。
周期ハンドラ(μITRON系RTOSのsta_cyc/iwup_tsk) カーネルが管理する周期ハンドラを生成・起動する仕組み。ハンドラは非タスクコンテキストで周期的に呼び出されるため、タスクを動かしたい場合はハンドラ内からiwup_tskなどでタスクを起床させる。xTaskDelayUntilがタスク側で絶対時刻まで待つのに対し、こちらはカーネル側が周期管理を担う設計思想の違いがある。

いずれの方式でも「周期の基点をどこに置くか」を明確にして設計することが、精度確保のポイントとなります。

ポイント③:共有資源の管理

共有資源の管理でも、ベアメタルとRTOSでは違いが生じます。

ベアメタル:割り込み禁止でクリティカルセクションを保護する

ベアメタルでは割り込みを一時的に禁止することでクリティカルセクションを保護する方法が一般的です。実装はシンプルですが、禁止区間が長いと割り込みレイテンシに直接影響するため、保護範囲を必要最小限に絞る必要があります。

RTOS:コンテキストに応じて保護手段を使い分ける

RTOSでは保護の目的とコンテキストに応じて複数の手段を使い分けます。

手段 内容
ミューテックス タスク間で共有リソースを保護する場合の基本手段。優先度継承機能を持つため優先度逆転を緩和できるが、取得・解放のオーバーヘッドが生じる
バイナリセマフォ/ISR専用キューAPI(FromISR系) ISRとタスク間ではミューテックスが使用不可なため、FromISR系APIを使ったバイナリセマフォやキュー操作が必要
割り込み禁止 RTOSのコンテキストでも、クリティカルセクションがきわめて短い場合は割り込み禁止の方がオーバーヘッドを抑えられる場面がある。また、割り込み内で処理がされるような場合で、それを抑止したい場合は割込み禁止を使用

割り込み禁止・セマフォ・ミューテックスのどれを選ぶかは、保護範囲の長さとリアルタイム要件を考慮して判断することが重要になります。

ポイント④:デバッグの手法

ベアメタルとRTOSの違いの4つ目は、デバッグ手法の違いです。

ベアメタル:JTAGとprintfが主役

ベアメタルのデバッグはJTAGを使ったブレークポイント設定とprintfによるログ出力が中心になります。処理が1本のフローで動くため、問題の発生箇所を比較的特定しやすいという特徴を持ちます。

RTOS:タスク状態・スタック使用量・CPU占有率を可視化する

RTOSでもJTAGやprintfは、引き続き有効なデバッグ手段として活用できます。ただし、RTOS使用時に問題になる「スタックオーバーフロー」「デッドロック」「優先度逆転」を捉えるためには、それだけでは不十分です。

RTOSでは各タスクの状態や、遷移・スタック高水位・CPU使用率のモニタリングが欠かせません。FreeRTOSであればvTaskListやuxTaskGetStackHighWaterMark、vTaskGetRunTimeStatsがそれぞれ利用できます。

タスク数が増えるほど、これらの可視化ツールの重要性は高まると覚えておきましょう。

RTOSを選ぶ判断基準

RTOSを選ぶか迷った際は、主に次の点を軸に判断するとよいでしょう。

  • タスク数
  • 通信プロトコルの複雑さ
  • リアルタイム要件の厳しさ
  • メモリ制約
  • 使用したいミドルウェアの必要要件

処理の種類が少なくリアルタイム要件が緩い場合は、ベアメタルの方がシンプルで管理しやすくなります。一方、複数の機能が並行して動き、それぞれの応答時間に要件がある場合はRTOSの採用を検討する価値があります。

まとめ

ベアメタルとRTOSの設計の違いは、主に割り込み処理・周期処理・共有資源・デバッグという4つの場面に表れます。RTOSを使うとコードの複雑さは増しますが、マルチタスクによる並行処理と優先度管理によって、現代の組み込み機器が求める複数機能の同時制御に対応しやすくなるでしょう。

これら4つのポイントを踏まえた上で、プロジェクトの要件に合った選択をしてみてはいかがでしょうか。

組み込みソフトの世界 トップへ戻る