メインコンテンツへスキップ
ロボティクス RTOS 組み込みシステム FreeRTOS

ロボット向けRTOSカーネルアーキテクチャ:スケジューリング、割り込み、ハードウェア制御

Akash Verma - VoicePing
ロボット向けRTOSカーネルアーキテクチャ:スケジューリング、割り込み、ハードウェア制御。青緑・青・緑のマイコン、フライトコントローラー、アプリケーションプロセッサーの基板が、小型の四足歩行ロボットとドローンを囲んでいます。 FreeRTOS ESP32 / STM32 / Pico・Pico 2 ↗ Zephyr ESP32 / STM32 / nRF52840 ↗ NuttX / ChibiOS Pixhawk 4 PX4 + NuttX / ArduPilot + ChibiOS ↗ Linux / PREEMPT_RT Raspberry Pi 5 / Jetson Orin / Intel・AMD ↗
ソフトウェア構成の例。ボード対応状況とRTカーネルの提供状況は異なります。
この記事の内容

この記事の内容

ロボットには、補正が間に合うタイミングで正しい指令が必要です。**リアルタイムOS(RTOS)**は、計測から駆動までの処理を調整します。センサー入力からハードウェア出力まで、1つの関節補正がRTOSアーキテクチャを通る流れを追います。

1. プロセッサーは高速でも、ロボットの反応が遅れる理由

四足歩行ロボットが段差を検知し、正しい補正を計算する

四足歩行ロボットが、崩れた舗装石に足を乗せます。エンコーダーが関節角度の変化を報告し、慣性計測装置(IMU)が胴体の回転を検知します。コントローラーは補正を計算しますが、その指令が関節に届く間もロボットは動き続けます。

間に合った補正では、ロボットが立て直せる間に関節が応答します。遅れた補正では、関節が応答する前に姿勢が変わります。同じ四足歩行ロボットが、段差でバランスを保つ様子と傾く様子を示しています。
立て直しが間に合う時間のイメージ。時間の余裕はロボット、コントローラー、地形によって異なります。

計算が正しいだけでは不十分です。以前の姿勢を前提にした指令は、その姿勢がすでに変わった後に到着することがあります。

ロボットが必要とする時点より後に補正が関節へ届く

この例では、アクチュエーター指令をセンサーサンプルから1ms以内に適用する必要があるとします。答えを0.2msで計算できても、応答全体が収まる証明にはなりません。

1つのサンプル・2つの伝達経路計算は正しくても、届く時刻が違う
サンプリング期限は1ms1.5 ms
間に合う
0.6 ms
間に合わない
1.3 ms
どちらも計算時間は0.2ms。差が生まれるのは、待機と伝達の時間です。
時間は説明用の例です。ベンチマークではありません。期限は計算終了ではなく、指令が適用される時点に対して定めます。
この先の経路を読むための4つの用語時間に関する数値が示すもの
周期
定期的な更新の間隔
期限
完了が許される最も遅い時点
応答時間
サンプリングから指令適用まで
ジッター
更新ごとのタイミングのばらつき
図は概念を示しています。測定結果ではなく、共通の数値尺度も使っていません。

平均応答時間が短くても、ときどき更新が遅れることはあります。リアルタイム制御には、経路全体の遅延を十分に抑え、安定したタイミングで実行する必要があります。ROS 2のリアルタイム解説 がこの違いを説明しています。

2. コントローラーが各ステップを調整する仕組み

CPU、メモリ、ドライバーがセンサー値を関節指令へ変える仕組み

マイクロコントローラーを使う組み込みシステムでは、CPUが計測値を読み、目標値を計算してドライバーを呼び出します。ドライバーが周辺機器を設定し、周辺機器がアクチュエーターインターフェースへ信号を届けます。

ロボットハードウェアガイド では、モーター、伝達機構、センサー、関節負荷がアクチュエーターインターフェースをどう形作るかを解説しています。

ソフトウェアから物理的な出力へ関節の補正処理を追う
  1. 01センサーIMU/エンコーダーサンプルを取得
  2. 02CPU + RAM制御タスク目標値を計算
  3. 03ドライバーレジスター書き込み転送を設定
  4. 04周辺機器タイマー/CAN信号を伝達
  5. 05関節ドライブパワー段指令を適用
↶ エンコーダー/電流のフィードバックでループを閉じる
CPUが命令を出し、周辺機器が信号を生成し、ドライブがモーターへ電力を供給します。

PWMドライバーはタイマーの比較レジスターに書き込めます。するとタイマーが各エッジをCPUで切り替えなくてもパルスを生成します。バスドライバーの場合は転送を準備し、DMAが補助することもあります。レジスター書き込み、転送完了、指令適用は別々の瞬間です。

命令レベルでは、メモリーマップドレジスターは周辺バスがデコードするアドレスです。CPUのストアは通常のRAM変数ではなく、ハードウェア状態を変えます。タイマーが新しい比較値を取り込むのは、次の更新境界だけの場合があります。STのタイマー・クックブック がこのプリロード機構を説明しています。CAN転送もバスの使用権を待つ必要があります。その後、ドライブが指令を適用する時点を決めます。これらの待ち時間はタスク選択の外側にあります。

一般的なMCUコントローラーの内部アドレスが違えば、役割も違う
マイコンの機能を示す概念断面図。CPUは命令を実行し、RAMは作業状態を保持し、フラッシュはファームウェアを保存し、タイマーとI/Oは周辺機器の信号を生成します。
保存フラッシュ命令と定数
作業RAMサンプル、スタック、バッファ
制御I/Oレジスター周辺機器の状態と設定
レジスターへの書き込みが物理信号になる
  1. 01CPUのストア命令
  2. 02タイマーの比較レジスター
  3. 03PWM波形
  4. 04モータードライブ
機能を示す概念図であり、実際のダイ配置ではありません。メモリーマップドレジスターを介して、CPUのロード/ストア命令が周辺機器の状態へアクセスします。

制御ピンは信号を運びます。モータードライブが動作電力を供給し、より高速な電流ループを独自に実行することもあります。Physical AIを支えるエレクトロニクス では、その周辺回路と電力経路を追っています。

FreeRTOS・RAM配置の概念図タスクのメモリを確保する2つの方法
RAM・共通の容量枠
グローバル変数、バッファ、その他の領域
RTOSヒープA 制御タスク・スタックとTCBその他のカーネルオブジェクトと空き領域
アプリケーションが確保した領域B テレメトリータスク・スタックとTCB
A 制御タスクxTaskCreate()

設定済みアロケーターがヒープから スタックとTCB を確保します。

B テレメトリータスクxTaskCreateStatic()

アプリケーションが スタック配列とTCB領域を用意します。

スタック
ローカル変数、関数呼び出し、保存したCPUコンテキスト
TCB・タスク制御ブロック
優先度、リストへのリンク、保存スタックへのポインター
各タスクは専用のスタックとTCBを持ちます。 どちらのタスクでも、どちらの生成方法を選べます。これは容量配分の概念図です。配置はビルドによって変わります。

各タスクには、実行スタックとTCBのためのRAMが必要です。スタックは関数呼び出しの状態と保存レジスターを保持し、TCBはそのコンテキストの場所をカーネルに伝えます。タスクがBlocked(待機)状態でも、スタック用の領域は確保されたままです。

FreeRTOSのタスクメモリ・配置の概念図タスクごとに2つのオブジェクト。確保方法は2通り。
動的生成xTaskCreate()
設定済みヒープアロケータータスク用の領域を確保
タスクスタック関数呼び出しと保存レジスター
TCB優先度、スタックポインター、リストへのリンク
静的生成xTaskCreateStatic()
アプリケーションが提供する領域これらのオブジェクトにはヒープ割り当て不要
StackType_t[]確保済みスタック配列
StaticTask_t確保済みTCB領域
スタックのみの計算例768要素 × 4バイト = 3,072バイトStackType_tが32ビットの場合。TCB、キュー、その他のバッファーには別途メモリが必要です。
どちらもRAMを使います。実際のアドレス、スタックの伸長方向、TCBのサイズ、アロケーターの配置はポートとビルドによって異なります。すべての環境に共通するRAM配置図ではありません。

本家のFreeRTOSでは、xTaskCreate()が設定済みアロケーターからスタックとTCBを取得します。xTaskCreateStatic()はアプリケーションが用意した領域を受け取ります。どちらもRAMを消費し、静的生成はこれらのオブジェクトのヒープ割り当てをなくすだけです。本家のFreeRTOSではスタック深さをStackType_tの要素数で指定しますが、ESP-IDFのタスク生成APIはバイト数を使います。スタックサイズを転用する前に、タスクAPI とIDFポートの違い を確認してください。

必要なメモリ容量を見ると、プラットフォームの違いが分かります。小さなFreeRTOSカーネルとLinuxシステムでは搭載するサービスが異なります。チップ選定に使う前に、それぞれの数値に何が含まれるかを比べてください。

ソフトウェアの容量 · 公開資料の参考値FreeRTOSとLinuxでは必要なメモリ容量が異なる
異なるビルドの事例であり、条件を揃えた性能・容量比較ではありません
集計の対象FreeRTOSの参考値組み込みLinuxの参考値
カーネルのコード・保存容量約9~18 KBRichard Barryが2022年に示した、実用的なカーネル構成の値。FreeRTOSのサイズに関する議論 ↗約2~4 MB2017年のBootlin講演で示された組み込みカーネルの保存容量の目安。Bootlinのカーネルサイズ資料 ↗
公開事例のRAM使用量21,944バイト 約22 KBSTM32F3を使うCraneアプリケーションの一例。スタック、バッファー、オブジェクト、アプリケーションデータを含みます。2026年の研究 · 表11 ↗32 MB以上より現実的な小規模Linuxシステムについての2022年の目安。ごく基本的な構成なら、これより少なく済む場合があります。BootlinのRAM容量の目安 ↗
Linux + PREEMPT_RTの場合は? このLinuxの数値はRTビルドの測定値ではありません。実際のカーネル、ドライバー、ユーザー空間、ロックするワーキングメモリを見積もる必要があります。RT化で増えるメモリ量は一定ではありません。
最低要件ではなく、参考値です。 コンパイラー、アーキテクチャー、機能、ライブラリー、アプリケーションの保存領域によって結果は変わります。Linuxカーネルイメージとファームウェア全体では測定範囲が異なるため、この表から同条件の容量比を計算することはできません。

メモリの選択:MCUファームウェア、Linux、割り当て

MCUベースの組み込みシステムでは、チップ内SRAMにタスクスタック、サンプル、バッファーを保持し、ファームウェアは通常フラッシュに保存します。外部DRAMとMMUを持つアプリケーションプロセッサーは、Linuxプロセス、仮想メモリ、より大きなドライバースタックを支えられます。メモリ容量だけでタイミング保証は決まりません。

重要な作業領域はループ開始前に準備します。FreeRTOSは静的または動的なオブジェクト割り当て をサポートしますが、開発者はスタック、キュー、バッファーのサイズを決める必要があります。ヒープ管理ガイド で方式を確認できます。

RTOSカーネルの内部:タスク、割り込み、スケジューリングの連携

**RTOSはOSの分類です。**FreeRTOSとZephyrは、スケジューリングと同期を提供する実装です。開発者はそれらの仕組みを設定し、アプリケーションタスクを実装します。

同じ処理を構成する2つの方法順番に呼び出す処理から、イベントを待つタスクへ
スーパーループ
計測制御通信
同じ順序で繰り返します。長い処理があると、後続の呼び出しが遅れます。
RTOS
センサータスク制御タスクテレメトリータスク
イベントでタスクが実行可能になり、スケジューラーが実行対象を選びます。
どちらも処理時間の上限を管理する必要があります。RTOSはタスク実行と同期の仕組みを提供します。

FreeRTOSのタスクスケジューリングを追うため、ここではプリエンプティブなシングルコア構成を使います。制御タスクが新しいデータを待つ間、センシングとテレメトリーにはそれぞれ実行コンテキストを割り当てます。

1つの制御タスク待機 → 実行可能 → 実行中
待機サンプルを待機
サンプル / イベント
実行可能CPUで実行可能
実行への切り替えが可能
実行中CPUがタスクを実行
実行中 → 待機 次のサンプルを待機実行中 → 実行可能 実行可能な別の処理にプリエンプトされる
実行可能とは、実行できる状態であり、すでに実行中という意味ではありません。待機中のタスクは、まず待機条件が満たされる必要があります。

カーネルは**タスク制御ブロック(TCB)**にタスク状態を保存します。pxTopOfStackが保存コンテキストの位置を示し、uxPriorityが優先度を決め、リスト項目が状態リストやイベントリストにつなぎます。RTOSコンテキストスイッチは、保存された実行地点からタスクを再開します。

単純化したシングルコアFreeRTOS保存された状態から、実行できるタスクを判断する
タスク制御ブロック(TCB)

優先度3 + 実行可能リスト / 待機リストへのリンク

保存されたスタックポインター
制御タスクのスタック · RAMローカル変数 · 関数呼び出し
保存されたCPUコンテキスト
実行可能タスク · 優先度の高い順
P3制御← 選択
P2センサー処理
P1テレメトリー
P0アイドル
TCBは、タスクのスタックに保存されたコンテキストを指します。 切り替えが許可されると、実行可能なReadyタスクのうち、優先度が最も高いものが選ばれます。優先度の数値は説明用です。

切り替えが許可されると、実行可能なReadyタスクのうち最も優先度が高いものが選ばれます。高優先度タスクが一度も待機しないと、低優先度の処理が実行機会を失うことがあります。FreeRTOSのタスク実装 を参照してください。

シングルコアモデルでは、Readyリストを優先度別に管理します。キュー待ちでブロックすると、タスクはReady集合から外れ、待機タスクとして登録されます。有限のタイムアウトには遅延リストの管理も必要です。イベントやタイムアウトで再び実行候補になります。カーネルはリスト更新を保護し、割り込みが更新途中のスケジューリング構造を見ないようにします。設定によってはポート最適化ビットマップで優先度を検索しますが、すべてのチップで同じアルゴリズムではありません。

ここでセンサーがデータ準備完了割り込みを発生させます。ここから実行権が引き継がれるまでを追います。Ready(実行可能)になっても、まだRunning(実行中)とは限りません。

処理の引き継ぎ · 全5段階センサー割り込みから制御タスクまで
  1. 1
    待機
    制御
    待機
    CPU
    テレメトリータスク

    制御タスクが新しいサンプルを待っています。その間は、優先度の低いテレメトリーがCPUを使えます。

  2. 2
    割り込み
    制御
    待機
    CPU
    センサーISR

    データ準備完了の割り込みがタスクの実行に割り込みます。ISRがセンサーイベントを確認し、割り込み要因を処理します。

  3. 3
    起床
    制御
    実行可能
    CPU
    センサーISR

    ISRから安全に呼べるカーネル操作で制御タスクを起こします。実行可能になりますが、ISRはまだ実行中です。

  4. 4
    切り替え
    制御
    実行可能
    CPU
    PendSV / コンテキストスイッチ

    優先度の高い例外が切り替えを妨げなくなると、ポートが実行中だったタスクのコンテキストを保存し、選ばれたタスクを復元します。

  5. 5
    実行
    制御
    実行中
    CPU
    制御タスク

    例外からの復帰で制御タスクが再開し、サンプルを使って関節の補正量を計算できます。

プリエンプションが有効で、カーネルAPIの割り込み優先度規則を満たすCortex-Mの例。 ティック境界を待つ必要はありません。実行可能になっても、まだ実行中とは限りません。

Cortex-M4Fポートでは、コンテキストスイッチの要求によって、低優先度例外のPendSVを保留状態にできます。ハードウェアがまず例外フレームを保存し、ポートが残りのタスクコンテキストを保存して別のTCBを選び、そのタスクを復元します。**プロセススタックポインター(PSP)はタスクのスタックを指し、ハンドラーコードはメインスタックポインター(MSP)**を使います。

Cortex-M4Fの例 · 基本整数フレームコンテキストスイッチは保存先のスタックポインターを切り替える
切り替え前のタスクのスタック · PSP
ハードウェア例外フレームR0–R3 · R12 · LR · PC · xPSR
ポートが保存するタスクコンテキストR4–R11 · EXC_RETURN
TCB.pxTopOfStack → 保存されたコンテキスト
  1. 保存PendSVが残りのレジスターを切り替え前のタスクのスタックに保存します。
  2. 選択vTaskSwitchContext() が、カーネルの保護下で次に実行できるタスクを選びます。
  3. 復元次のTCBからスタックポインターを読み込み、ポートが保存したレジスターを復元します。
  4. 復帰例外からの復帰でハードウェアフレームが復元され、保存されたPCから実行が再開します。
PSP
タスクのスタックポインター
MSP
ハンドラーのスタックポインター
BASEPRI
割り込み優先度のマスクしきい値
概念上の順序であり、アセンブリーではありません。浮動小数点を使うと保存状態が増える場合があり、アラインメントやFPUの遅延スタッキングもフレームに影響します。ESP32では別のポートを使います。

ポートは次のタスクを選ぶ間にBASEPRIを上げ、カーネルデータへアクセスする可能性がある割り込み優先度をマスクします。より緊急度の高い割り込みは有効なままにできますが、対象のFreeRTOS APIを呼んではいけません。PendSVが保留されていても、実行中の高優先度ハンドラーに割り込んでタスクを切り替えることはできません。これはCortex-M4Fポート に固有の説明で、ESP32のXtensaやRISC-Vアセンブリーの説明ではありません。

優先度による切り替えと、同じ優先度での交代プリエンプションとタイムスライスは別の仕組み
プリエンプション
テレメトリー P1制御 P3が起床 → 実行
高優先度のタスクはティックの途中でも実行を引き継げます。
タイムスライス
タスクA · P1タスクB · P1タスクA · P1
同じ優先度の実行可能タスクが、ティックで順番に交代します。
ティックはタイムアウトの時間管理も進めます。スケジューラーは、周期的なタイムスライスとは別にイベントへ応答できます。

プリエンプションはティックの間にも反応できます。タイムスライシングは、同じ優先度のReadyタスクをティックごとに順番に実行します。両者には別々のFreeRTOS設定スイッチ があります。

コンテキストスイッチの内部:レジスター、スタック、他のスケジューラー

Cortex-Mの例外はCPUコンテキストの一部を保存します。ポートが残りのタスクコンテキストとスタックポインターを保存し、例外から復帰すると、選ばれたタスクの保存位置から実行を再開します。Memfaultの解説 では、PSP/MSP、例外フレーム、BASEPRIマスク、浮動小数点コンテキストを扱います。

ISRは適切なISRから安全に呼べるカーネル操作を使い、APIやポートが要求するときに切り替えを要求します。次のティックを待つ必要はありません。該当するCortex-Mポートでは、API呼び出し可能な閾値より高い優先度の割り込みはFreeRTOS APIを呼べません。

FreeRTOSのタスク管理例 では、シングルコアモデルをさらに詳しく説明しています。Zephyrのスケジューリング には、異なるReadyキュー実装と協調型・プリエンプティブ型のスレッドクラスがあります。

キュー、セマフォ、ミューテックスがタスクと共有資源を調整する仕組み

ここでのRTOSタスク同期には2つの役割があります。センサーサンプルを届けることと、待機中の制御タスクを起こすことです。受け渡すものの性質に合わせてカーネルオブジェクトを選びます。

用途に合うオブジェクトを選ぶデータ、利用可能数、それとも所有権?
タスク間通信とリソース保護
カーネルオブジェクト保持するものロボットでの用途
キューデータバッファーに蓄えたメッセージタイムスタンプ付きセンサーサンプル
バイナリーセマフォ0または1利用可能な許可は1つ転送完了の通知
連続したイベントが1つにまとまる場合がある
カウンティングセマフォ0 … N複数の許可空きバッファースロットを数える
ミューテックス所有権リソースへの排他アクセスタスク間でバスアクセスを保護
基本的な優先度継承
セマフォはカウントと待機タスクの状態を持つ同期オブジェクトであり、データをFIFO順に格納するキューではありません。ミューテックスはISRから通知するためのオブジェクトではありません。

サンプルが利用可能になると、待機中の受信タスクをBlocked → Readyへ移せます。次にCPUの実行権が必要です。セマフォが伝えるのは利用可能になったという状態であり、サンプルそのものではありません。ミューテックスには所有権と基本的な優先度継承があります。

FreeRTOS内部のキューは、循環ペイロードバッファー、要素数、送受信を待つタスクのリストを組み合わせます。送信は設定されたバイト数をコピーし、待機中の受信タスクを解放することがあります。セマフォはデータサイズ0の項目でキュー機構を再利用します。重要なのはペイロードバッファーではなく、カウントと待機リストです。ミューテックスは保持者も追跡し、カーネルがその所有者の優先度を一時的に上げられるようにします。キュー実装 で関係を確認できます。

キューの鮮度、イベント数、所有権

バイナリーセマフォは許可を最大1つしか保持しないため、繰り返すイベントがまとめられることがあります。カウンティングセマフォは複数の利用可能な許可を数えます。FreeRTOSにはタスク通知もあり、イベントの意味が合う単一の受信タスクに便利です。

制御キューが満杯になったとき、データを拒否するのか、古いデータを上書きするのか、オーバーランを報告するのかを決めます。古い滞留データより、最新の完全なサンプルが役立つ場合があります。ポインターを渡すメッセージには、バッファー所有権も明示する必要があります。キューの例 と共有キュー/セマフォ実装 を確認してください。

3. 重要な補正が遅れる理由

Readyの制御タスクがすぐ実行できない理由

高優先度のタスクでも、実行候補でありながらCPUを取得できないことがあります。依存関係を待っている場合もあります。タスク優先度を上げるだけでは、どちらの待ちも自動的には解消しません。

2種類の待ち時間実行可能なのに遅れる状態と、待機状態は異なる
実行可能タスクは実行できる

CPUが保護された処理や割り込み処理を実行中のため、タスクへの切り替えを待つ必要があります。

保護された処理切り替え制御
待機タスクはまだ実行できない

必要なサンプルやリソースが届いていない、またはタイムアウト条件が満たされていません。

待機リソースが利用可能に実行可能
優先度は、実行可能なタスクの中から選ぶためのものです。 依存関係をなくしたり、CPUの保護区間をプリエンプト可能にしたりするものではありません。

クリティカルセクション、割り込みマスク、スケジューラー停止、ISR実行は、FreeRTOSを含めてタスクディスパッチを遅らせます。保護された処理に特別な「最高タスク優先度」があるわけではなく、切り替え可能な時点を一時的に制限します。

タスクの優先度だけでは足りない理由どの仕組みが実行の引き継ぎを妨げるのか
カーネル内の遅延要因と制御タスクへの影響
仕組みCPUやカーネルの動作制御が待つもの
非RT Linuxのスピンロックspin_lock() はローカルCPUでのタスクのプリエンプションを禁止します。IRQは有効なままの場合があります。保護区間が終わり、再スケジュールが許可されるまで。
割り込みマスクマスクされた割り込み源は、まだハンドラーを実行できません。マスク解除、イベント処理、その後の実行切り替えまで。
ISRの実行ハンドラーコンテキストが、通常のタスク選択とは別にCPUを使います。例外からの復帰やコンテキストスイッチが可能になるまで。
スケジューラーの一時停止vTaskSuspendAll() はタスク切り替えを先送りにしますが、それ自体は割り込みをマスクしません。スケジューラーの再開と、保留された管理処理の完了まで。
ミューテックスへの依存別のタスクが所有するリソースを待って、タスクが待機状態になります。所有者が処理を進めて解放するまで。優先度継承は他タスクの干渉を減らせます。
最初の4つは、タスクへの切り替えやイベント通知を遅らせる場合があります。ミューテックスを待つタスクは、依存関係が解消されるまで待機状態です。保護された処理は、特別な最優先タスクではありません。

PREEMPT_RTを使わないLinuxで、ドライバーがspinlock_tを保持しているとします。有効な割り込みが高優先度の制御スレッドを起こし、再スケジューリング要求を設定できます。割り込みから戻っても、切り替え前にCPUが保護されたドライバー区間を完了しなければならないことがあります。制御スレッドはReadyですが、残りの保護処理も応答時間の予算に含まれます。

FreeRTOSのvTaskSuspendAll()は割り込みマスクとは異なります。ISRは実行できますが、スケジューラーが再開して延期された処理を扱うまでタスク切り替えが遅れます。一方、Cortex-Mのクリティカルセクションはポート固有の割り込みマスクを使います。タスクの優先度を上げても、どちらの仕組みも取り消せません。Linuxのロック規則 が、関連するスピンロックとIRQの違いを説明しています。

優先度継承 · CPU 1つ · ミューテックス1つミューテックスの所有者に高優先度タスクの優先度を貸す
3高ロボット制御
2中ログ記録
1低デバイス設定

数値が大きいほど優先度が高い

低優先度タスクがミューテックスを所有しています。 高優先度タスクが要求し、次の状態に: 待機。
優先度継承なし実行可能な中優先度タスクは低優先度タスクより優先される
CPUの実行順序
  1. 中 · 2ログ記録を実行
  2. 低 · 1完了 + ロック解除
  3. 高 · 3ミューテックスを取得 + 制御
高優先度タスクの待ち時間中優先度の処理 + 低優先度の残りの処理
優先度継承ありカーネルが低優先度タスクの優先度を引き上げ: 1 → 3
CPUの実行順序
  1. 低 · 1 → 3完了 + ロック解除
  2. 高 · 3ミューテックスを取得 + 制御
  3. 中 · 2ログ記録は後で実行
高優先度タスクの待ち時間低優先度の残りの処理のみ。中優先度タスクは割り込めない
高優先度タスクがミューテックスを待っているため、その所有者である低優先度タスクが一時的に高い優先度を継承します。 この例では、ロックを解除すると低優先度タスクは優先度1に戻ります。ブロックは実行順序を示しており、所要時間ではありません。

優先度継承をサポートするミューテックスでは、所有者が待機中の高優先度タスクの優先度を一時的に継承します。所有者が処理を終えて資源を解放しやすくなります。ただし、クリティカルな処理をなくしたり、デッドロックを解消したり、応答しないデバイスの待ち時間を制限したりするものではありません。

カーネル保護、割り込み優先度、マルチコアロック

PREEMPT_RTではないLinux構成で通常のスピンロックを取得すると、そのCPUでのタスクプリエンプションが止まります。IRQを無効化する派生型はローカル割り込みマスクも加えます。Linuxのロック規則 が仕組みを区別しています。

タスク優先度とハードウェア割り込み優先度は別物です。ポート固有のマスク閾値が、どの割り込みがカーネルを呼べるかを決めます。マルチコアシステムでは、ローカルな保護だけで別CPUがアクセスできる資源を守れるとは限りません。

資源を保持する時間に上限を設け、ロックの連鎖を分析します。FreeRTOSの資源管理章 がミューテックスの所有権と基本的な優先度継承を説明しています。

FreeRTOSとデスクトップLinuxの違い、PREEMPT_RTの変更点

RTOSとLinuxを比較するなら、応答経路全体を考慮する必要があります。両方のカーネルがタスク状態、優先度、プリエンプション、割り込みを管理します。違いは、設定したシステムがその経路での干渉をどう制御するかです。

カーネル構造 · 3つの構成例制御タスクとハードウェアの間にあるもの
FreeRTOSシングルコアMCUの例
高優先度の制御タスク
FreeRTOSカーネル
  • TCB + 優先度別の実行可能リスト
  • 実行可能な最高優先度タスクを選択
  • ISR対応APIがタスクを起こす
  • 残る遅延: クリティカルセクションで切り替えが遅れる場合がある
PREEMPT_RTなしのLinuxプリエンプションモデルは構成による
設定済みの制御スレッド
Linuxカーネル
  • SCHED_FIFO / SCHED_RR を利用可能
  • ハードIRQ処理がタスクへの切り替えを遅らせる場合がある
  • spinlock_t はローカルのタスクプリエンプションを禁止
  • 残る遅延: 保護された経路では切り替えが後になる
Linux + PREEMPT_RT同じLinuxアプリケーション基盤
設定済みのRT制御スレッド
Linux RTカーネル
  • 大部分のIRQ処理がスレッドで動く
  • spinlock_t はRTミューテックスに基づく優先度継承を使用
  • プリエンプト可能なカーネル経路が増える
  • 残る遅延: rawロックと低レベルの経路は保護されたまま
いずれもドライバー → I/O → アクチュエーターを経由してハードウェアへ到達
プリエンプションは実行を引き継げるようにしますが、処理そのものはなくしません。 FreeRTOSには独自のスケジューラーがあります。PREEMPT_RTが変更するのはLinuxです。
PIは優先度継承です。いずれも割り込み、ロック、実行、デバイス遅延の上限を管理する必要があります。

**PREEMPT_RTはLinuxの構成であり、FreeRTOSの機能ではありません。**スレッド化された割り込みと優先度継承(PI)に対応したスリープ可能なロックによって、より多くのカーネル処理をスケジューラーの管理下に置きます。

一般的なスレッド化IRQ経路では、ハード割り込みの短い初期処理で原因を確認またはマスクし、その後IRQスレッドを起こします。IRQスレッドはスケジューリングポリシーと優先度に従って競合します。PREEMPT_RTは通常のspinlock_tをRTミューテックスベースの実装に変えます。ロックを待つスレッドはスリープでき、優先度継承が所有者の処理を進めやすくします。raw_spinlock_t、低レベルの入口経路、明示的に保護された領域はプリエンプト不可のままです。RTカーネルの違い を参照してください。

説明用のタイムライン · ベンチマーク結果ではありません計算は同じでも、待ち時間の配分は違う
計測 · 70 µs待機 · 可変計算 · 200 µs転送 + 出力反映 · 210 µs

目盛り:0~1,500 µs · 破線:1,000 µsの期限

PREEMPT_RTなしのLinuxSCHED_FIFO制御スレッド
待機 800 µs合計1,280 µs · 280 µsの遅れ
Linux + PREEMPT_RTSCHED_FIFO制御スレッド
待機 120 µs合計600 µs · 400 µsの余裕
FreeRTOS高優先度タスク · プリエンプション有効
待機 120 µs合計600 µs · 400 µsの余裕
この例で変えているのは待ち時間の配分だけです。実際の順序と遅延はハードウェア、設定、負荷に左右されます。この図は性能の順位や保証を示すものではありません。

適切に構成したPC上のリアルタイムLinuxはロボット制御を実行できます。通常のUbuntuが厳しい期限を満たすと仮定できないのと同じく、検証していないFreeRTOSシステムも保証できません。オープンソースライセンスは、タイミングの問題とは別です。

スケジューリングで実行が許可された後でも、メモリが遅延を追加することがあります。仮想メモリでは、ページ割り当て、コピーオンライト、ファイルやスワップの読み込みが必要なため命令の実行中にページフォールトが発生することがあります。ストレージを伴うフォールトは一部だけです。一般的なMCUのFreeRTOSシステムはデマンドページングなしで常駐メモリを使いますが、割り当て、フラッシュ/キャッシュ、バス、デバイスによって処理が一時的に止まることはあります。

メモリの常駐性は、別に検討すべき時間要因実行可能なタスクもメモリを待つことがある
一般的なMCU上のFreeRTOS
  1. 確保済みRAM
  2. タスクのスタックとバッファーを再利用
  3. デマンドページングによるページフォールトはない
Linuxの仮想メモリアクセス
仮想アドレスを変換
常駐済み + アクセス許可ありRAMにアクセス
または
回復可能なページフォールトページを確保・コピー・読み込み → 命令を再実行
Linux制御メモリの準備: 事前確保 → 事前アクセス → 必要なマッピングをロック → 再利用。TLBミスだけではページフォールトとは言えず、すべてのフォールトでストレージを読むわけでもありません。
不正なアクセスは、そのまま失敗することがあります。 静的な生成とメモリの常駐性は別の問題です。 PREEMPT_RTはページフォールトをなくしません。MCUのメモリでも、キャッシュ、バス、デバイスによる待ちが発生します。

Linuxの制御スレッドでは、ループ開始前に重要なバッファーとスタックページを準備し、必要なマッピングに事前アクセスしてページを準備し、エラーと上限を確認しながら適切なメモリーロックを使います。mlockall()が将来の割り当てやコピーオンライトを無害にするわけではありません。PREEMPT_RT自体もページフォールトをなくしません。メモリーロックのマニュアル で制約を確認できます。

Linuxの優先度、ページフォールト、PREEMPT_RTのトレードオフ

Linuxには通常のアプリケーションポリシーと、SCHED_FIFOやSCHED_RRなどのリアルタイムポリシーがあります。nice値は、これらのポリシー設定の代わりにはなりません。スケジューリングマニュアル がインターフェースを定義しています。

アドレスが使えるようになる前に、ページフォールトが処理を追加することがあります。重要な領域を事前割り当てし、ページに事前アクセスし、失敗と上限を確認しながら適切なメモリーロックを使います。mlockall() はメモリの常駐を助けますが、CPU、ロック、キャッシュ、デバイスの遅延は解決しません。

スレッド化された処理や異なるロック方式は、ワークロードによってオーバーヘッドを増やしたりスループットを下げたりします。優先度、割り込み配置、電源管理、CPU配置、ドライバーには注意が必要です。コストはワークロード依存で、固定の割合ではありません。RT理論 、カーネルの違い 、ハードウェア制約 を確認してください。

ここで補正全体の時間配分を考えます。センシング、干渉、計算、転送、出力適用に別々の上限を置き、計算を中断する高優先度処理も含めます。

説明用の時間配分 · 完全な2例補正処理はどれだけ待てるのか
計測 70 µs計算 200 µs転送 120 µs出力を反映 90 µs

固定処理480 µs + 待機120 µs = 合計600 µs

1,000 µsの期限内 · 残り400 µs

固定処理480 µs + 待機800 µs = 合計1,280 µs

1,000 µsの期限を超過 · 280 µsの遅れ

計測 + 待機・干渉 + 計算 + 転送 + 出力反映 ≤ 期限。固定の各段階は合計480 µsです。 2つの例で変えているのは待ち時間の配分だけです。

時間配分のモデルであり、ロボットのシミュレーションや実測に基づく保証ではありません。有効な上限値は、実際のシステムから得る必要があります。

待ち時間が120µsなら、この例の合計は600µsで、1,000µsの期限まで400µs残ります。待ち時間が800µsなら、固定処理が同じでも全体は1,280µsとなり、280µs遅れて到着します。これは説明用の値で、ボード上の測定値ではありません。

出力が反映される時点を観測可能にする1つのイベント、6つのタイムスタンプ
  1. 0 µsサンプル取得センサーのタイムスタンプ
  2. 70 µsISR開始GPIO / トレースマーカー
  3. 190 µs制御開始タスクマーカー
  4. 390 µs計算終了ドライバー呼び出しの境界
  5. 510 µs転送完了バス信号の記録
  6. 600 µs出力反映ドライブ / 出力マーカー
600 µs − 0 µs = 応答時間全体。タスクの開始遅延だけでは、計算と出力の伝達を見落とします。
標準の時間配分に対応する説明用のトレースです。指令の反映をどう観測するかは、アクチュエーターのインターフェースによって決まります。

出力が実際に反映される時点まで測定します。スケジューラー遅延だけではドライブが指令を適用する時点は分かりません。また、1回の実行で観測した最大遅延は最悪値の証明ではありません。

ハードウェアで経路を検証する

センサー取得、ISR入口、タスク開始、計算終了、転送完了、出力適用にタイムスタンプを付けます。GPIOマーカーとロジックアナライザーが役立ちますが、各マーカーが同じイベントを追い、クロックドメインが明確になっている必要があります。競合する通信、ストレージ処理、割り込みも発生させた状態で試験します。

Canonicalのcyclictestガイド は経路のうちスケジューリングに関係する部分を測定します。Linuxリアルタイムアプリケーションモニター は、対応カーネルでフォールトや待機パターンを診断するのに役立ちます。ROS 2のリアルタイム解説 、PREEMPT_RT内部 、Zephyrミューテックス文書 も詳しく説明しています。

4. ローカル制御から完全なロボットへ

制御ファームウェアを構築し、カスタムSDKで公開する

FreeRTOSとLinuxの選択は、センシングと動作を担うハードウェアから始まります。RAM、CPUアーキテクチャ、周辺ドライバー、タイミング要件が、その仕事を担えるソフトウェアを決めます。以下は対応ターゲットでの選択例で、各プラットフォームに2つの選択肢を示します。

ハードウェア容量 ≠ ソフトウェアの使用量どのチップに、どのソフトウェアが合うのか
各プラットフォームに2つのソフトウェア例。用途はハードウェアの使い方を示すものです
チップ / ボード2つのソフトウェア候補適合する理由ロボットでの役割とハードウェア上の理由
ESP32 / S3 / C3無線MCU
数百KBの内蔵SRAM。容量はチップによって異なります。
  1. ESP-IDF FreeRTOS
  2. Zephyr
小さなタスクカーネルなので、 スタックと無線バッファーの領域を残せます。IDFはチップのドライバーとサービスを統合します。無線センシング / ロボットI/O。 無線でデータを交換し、タイマーとGPIOでローカルの信号を扱います。
RP2040 / RP2350Pico / Pico 2 MCU
264 KB / 520 KB SRAM ↗
  1. ベアメタルC/C++
  2. FreeRTOS
ベアメタルではカーネルのタスク管理負荷を避けられます。FreeRTOSは スケジューリングと同期 をSRAM内で提供します。エンコーダー / パルス生成。 PIO、タイマー、DMAは、信号の各エッジでCPUが処理しなくても信号を取得・生成できます。
STM32 F4 / F7 / H7Cortex-M MCUファミリー
フラッシュとSRAMの容量は品種によって異なります。
  1. FreeRTOS
  2. Zephyr
構成可能なMCUカーネルが、Linuxの完全なプロセス環境なしで 制御、計測、通信 をまとめて管理します。モーター / 関節コントローラー。 ADC、タイマー、DMA、バスが、フィードバックの計測とアクチュエーターへの指令をつなぎます。
Nordic nRF52840無線Cortex-M4 MCU
256 KB RAM · 1 MBフラッシュ ↗
  1. nRF Connect SDKのZephyr
  2. ベアメタル + nrfx
Zephyrは無線サービスを統合します。単独のドライバーは より単純な周辺機器ファームウェアに適します。どちらもRAM容量の計画が必要です。電池駆動のセンサー。 無線とスリープモードは間欠的な計測に適します。ベアメタルのnrfx単体はBluetoothスタックではありません。
STM32F765Pixhawk 4フライトコントローラー
512 KB RAM · 2 MBフラッシュ ↗
  1. PX4 + NuttX
  2. ArduPilot + ChibiOS
ボードに合わせた飛行ファームウェアが、RTOSと センサードライバー、タスクのスタック、バッファーを組み合わせます。ドローンの姿勢安定化。 IMUの計測、推定、制御によって、適切な時刻にESC指令を出します。
BCM2712Raspberry Pi 5のアプリケーションSoC
GB単位の外部DRAM ↗
  1. Raspberry Pi OS
  2. Ubuntu Linux
MMUと外部DRAMが プロセス、仮想メモリ、ファイルシステム、Linuxドライバーを支えます。ROS 2 / カメラ / ゲートウェイ。 マルチコアの演算とカメラ・ネットワークI/Oが、ホスト上の並行処理を支えます。
NVIDIA OrinJetson CPU / GPUモジュール
GB単位のDRAM。容量はモジュールによります。
  1. Jetson Linux
  2. Jetson Linux + PREEMPT_RT
LinuxはGPUとデバイスのサービスを提供します。対応リリースでは、RTカーネルが CPUへの実行切り替えと割り込み処理 を変えます。画像認識 / AI推論。 GPUがフレームとテンソルを処理します。CPUのリアルタイム調整で、すべてのGPU処理の時間上限が決まるわけではありません。
Intel / AMDPC向けアプリケーションプロセッサー
外部DRAM + MMU。
  1. Ubuntu Linux
  2. Ubuntu + PREEMPT_RT
幅広いプロセス・ドライバー基盤が大規模アプリケーションに対応し、RT構成が カーネルに起因する待ち時間を減らします。開発 / 計画 / 検証済みの制御。 CPU性能は複雑な処理を支えます。直接制御には、適切なI/Oと時間特性の検証が必要です。
メモリ容量は制約の1つであり、それだけで選定は決まりません。 ハードウェアの数値は搭載メモリであり、OSに必要な容量ではありません。ボード、ポート、ドライバー、リリースを正確に確認し、用途ごとの時間特性も実測する必要があります。

センシングとフィードバック制御には、明示的な起床条件、優先度、実行時間の上限、十分なスタックを与えます。解析、ネットワーク通信、ログ、ストレージがクリティカルループの資源を保持し続けないようにします。

ローカルRTOSファームウェア · データフローの例通信と制御ループを分離する
受信する指令ホストのメッセージが届いたとき
指令タスクSDK指令を解析・検証
最新の目標値固定サイズのメールボックス例:30°
最新の目標値 → 制御タスク最新の有効な目標値を読む
ローカル制御予定された更新のたびに
センサーサンプル実測した関節位置例:27°
制御タスク目標値 − 実測値 = 誤差3°補正量を計算
ドライバー → 関節アクチュエーター指令を反映
制御タスク → 状態スナップショット実測状態のコピーを公開
送信するフィードバック低優先度のテレメトリータスク
状態スナップショット実測位置、ステータス、タイムスタンプ
テレメトリータスクホストSDKへフィードバックを送る
制御は、新しいメッセージやテレメトリーを待ちません。 期限切れの目標値は、設定されたタイムアウト方針に従って扱います。
矢印は タスク間のデータの受け渡しを示します。メールボックスとスナップショットへのアクセス時間には上限が必要です。時間のかかる解析やテレメトリーが、制御ループに必要なリソースを占有してはいけません。

カーネルはスケジューリングと同期を提供します。ファームウェアは制御動作とドライバーを提供し、カスタムSDKが指令と測定状態を公開します。

先ほどの割り込み引き渡しを、小さなFreeRTOSパターンで表します。要素数1のキューで最新の完全なサンプルを保持します。割り込みを有効にする前にキューとタスクを作成し、上限を定めたハードウェア経路でサンプルを取得します。

Cortex-M / FreeRTOSのアプリケーション構成例取得処理は短く。制御は専用タスクで。
割り込みコンテキスト
void sample_isr(void) {
  BaseType_t wake = pdFALSE;
  Sample s = read_ready_sample();
  xQueueOverwriteFromISR(
    sample_q, &s, &wake);
  portYIELD_FROM_ISR(wake);
}

取得済みサンプルを1つコピーし、高優先度タスクが起きたら切り替えを要求します。

タスクコンテキスト
void control_task(void *arg) {
  Sample s;
  for (;;) {
    xQueueReceive(sample_q, &s,
                  portMAX_DELAY);
    Target t = target_snapshot();
    Command u =
      control_step(s, t);
    actuator_write(u);
  }
}

サンプルの合間は待機します。整合性のある目標値と、時間上限のある出力経路を使います。

前提条件: 要素数1のキュー、ISR APIで許される割り込み優先度、初期化済みのハードウェア、処理時間に上限のある補助関数。実際のコントローラーでは、鮮度確認、時間超過、障害処理を追加します。
構造を示すCの例であり、完全なファームウェアではありません。型と補助関数は省略しています。ISR内の取得処理に、待ちを伴うバス転送を隠してはいけません。yieldマクロはポートごとに異なります。

ISRは完了したサンプルをコピーし、必要なら切り替えを要求します。タスクはCPUを消費せずに待機し、整合性のある目標値のスナップショットを読み、次の出力を計算してドライバーを呼びます。複数フィールドの目標は、メッセージパッシングまたは上限を定めたタスクレベルのロックで整合性を保った状態でまとめてコピーし、遅いI/Oの間はロックを保持しません。

周期ループでは、相対遅延を繰り返して処理時間を積み上げるのではなく、適切なタイマーやxTaskDelayUntil()を使います。ティック分解能は周期に合っていなければならず、ティック未満の要件には適切なハードウェアタイミング源が必要です。

既存のカーネル設定項目を使って、configUSE_PREEMPTION、優先度範囲、割り当て方式、スタックサイズを設定します。続いてタスクと同期を実装します。通常はReadyリストの選択を自分で書くのではなく、スケジューラーを設定して移植します。対応するデュアルコアESP-IDF構成でESP32上のFreeRTOSを動かす場合、スケジューラーはコアアフィニティーも考慮します。タスクを固定しても共有メモリやバスは分離されず、ローカル割り込みマスクで他方のコアを止めることもできません。共有データにはターゲットがサポートするコア間同期が必要です。

ベンダーAPIではなく、インターフェース仕様の例意図を送り、実測状態を返す
指令 → コントローラー
関節
joint_3
position_rad
0.15
sequence
42
有効期限
定義された有効期間
コントローラー → ホスト
実測位置
ラジアン
サンプルのタイムスタンプ
明示されたクロックドメイン
適用したシーケンス番号
どの指令を使ったか
ステータス
新鮮 / 古い / 障害
値の範囲、キューの方針、応答確認、単位、クロック同期、タイムアウト時の動作を文書化します。
応答確認で受信は分かっても、関節がいつ目標値を反映したかまでは証明できません。

単位、受け入れ範囲、タイムスタンプ、シーケンス番号、確認応答、鮮度、タイムアウト動作を定義します。受信したことは、物理的に実行された証拠ではありません。

通信境界では、フィールド幅、バイト順、フレーミング、必要な完全性チェックを含むシリアライズを明示します。ホストによってパディングが異なる可能性のあるC構造体をそのまま送らないでください。コントローラーはパケットを検証し、完全な目標を公開し、実際に適用したシーケンスを報告します。タイムアウト時には、機構に適した保持、減速、故障応答を定義して選択できます。SDKは受信を動作の成功と混同せず、その状態を公開すべきです。

カスタムロボットでは、センシングとアクチュエーター統合とともに、これらのインターフェースの範囲を定めます。VoicePingのカスタムロボット開発 は、タスクと動作環境から始まります。

ESP-IDF、本家のFreeRTOS、マルチコアの選択

ESP-IDFはFreeRTOS実装、ドライバー、起動経路を統合します。対応するマルチコアターゲットでは、アフィニティーと共有資源を考慮します。本家のFreeRTOSもSMPをサポートしており、マルチコアスケジューリングをすべて手作業で実装する必要はありません。

ターゲットとリリースに対応するIDFドキュメント に従います。コア固定で一部の競合は減らせますが、共有バス、メモリ、割り込みの影響は分離できません。クロック同期と、タイムスタンプが取得時刻か送信時刻かを定義し、設定したシステムを検証します。

**カーネルが製品プラットフォームになる仕組み。**カスタマイズはカーネルポート、アプリケーションファームウェア、外部SDK境界のいずれでも行えます。独自のコントローラーを作るために、企業がスケジューラーを書き直す必要はありません。

公開資料のある製品例 · カスタマイズする層の違いカーネルを再利用し、その上に製品を作る
01 · カーネル + プラットフォームEspressif対応ESPターゲット上のESP-IDF
FreeRTOSターゲット向けポート + SMP統合 + ハードウェアドライバーアプリケーションタスク + ネットワーク・周辺機器サービス

開発者がカスタマイズする部分タスクの優先度、アフィニティー、バッファー、 同期、アプリケーションの動作。

02 · 制御ファームウェアBitcrazeCrazyflieの飛行アプリケーション
FreeRTOSタスクセンサー準備完了 → 推定器 → 制御器 → モーター出力設定値、パラメーター、ログ記録 + ボードサポート

開発者がカスタマイズする部分制御アルゴリズムとドライバー、 プラットフォーム設定、アプリケーションモジュール。

03 · ロボットSDKUnitree公開SDK2のGo2インターフェース
rt/lowcmd → ロボットqdqkpkdtaurt/lowstate → アプリケーション

開発者がカスタマイズする部分ホストの制御ロジックが利用するのは、 モーターの目標値と実測状態。 SDKは関節コントローラーのOSを明らかにしていません。

カーネルの適応、アプリケーションファームウェア、ホストSDKは別の層です。フィールド名とトピック名は引用したGo2の例に基づき、機種によってインターフェースは異なります。

Espressifはハードウェア固有のFreeRTOS実装と統合を文書化しています。BitcrazeのCrazyflieは別の一般的な構成を示しています。FreeRTOSタスクを使い、センサーから推定器、コントローラー、モーターへ至るパイプラインを追加します。安定化のドキュメント とファームウェアソース でアプリケーション層を確認できます。

Unitreeは公開インターフェース層の例です。SDK2 Go2の例 は低レベルのモーター指令を公開し、状態を購読します。Python SDKはCyclone DDSを文書化 しています。これは拡張可能なロボットインターフェースを示しますが、非公開の関節コントローラーがFreeRTOSを使うことを示すものではありません。文書化されたSDKの動作と、内部ファームウェアへの推測を分けて扱います。

四足歩行ロボットやドローンでローカルRTOS制御とROS 2を接続する

このコントローラーをロボット全体の構成に組み込みます。ホストが動作を計画する間、ローカルコントローラーがフィードバックループを閉じ、関節ドライブが電流を制御します。各ループはタイミングを検証できる場所に割り当てます。

四足歩行ロボットの構成例必要な時間条件を満たせる場所に各ループを置く
ホストからマイコン、関節ドライブへ目標値を送ります。青緑の矢印は送信指令、藍色の矢印は実測フィードバックを示します。
目標値 →← 実測フィードバック
ホストLinux + ROS 2動作を計画
コントローラーローカルRTOSフィードバックループを実行
関節ドライブドライブのファームウェア電流と電力を制御
矢印は通信を示しており、電源配線ではありません。この分担は設計上の選択肢です。検証済みのLinux/PREEMPT_RTによる制御を、アクチュエーター側のループの上に置くこともできます。

**ROS 2はミドルウェアであり、RTOSはOSカーネルまたはプラットフォームです。**役割が異なり、組み合わせて使うことが多くあります。選択したループを適切なLinux/PREEMPT_RTホストで実行することもできます。ROS 2のリアルタイム設計の議論 がアプリケーションレベルの制約を説明します。

Linuxはプロセス、カメラ/ネットワークドライバー、ロボットライブラリー、デプロイツールを提供するため、ホストに適しています。PREEMPT_RTはそのプラットフォームを保ったままカーネルの応答性を高めます。ROS 2のコールバックにも適切なエグゼキューター/スレッドポリシー、上限を定めた処理、準備済みメモリが必要です。RTカーネルだからといって、すべてのコールバックが自動的にリアルタイムになるわけではありません。FreeRTOSはローカルファームウェア向けの小さな実行環境であり、ホストのLinuxソフトウェア全体を置き換えるものではありません。

**カーネルより先にタイミング要件を決めます。**ビジョンやマッピングのホストは、別のMCUが高速ループを閉じる間、スループットと幅広いドライバースタックを必要とする場合があります。厳しい制御期限をLinuxホストが直接担うなら、適切なリアルタイム構成とエンドツーエンド検証が必要です。PCはPREEMPT_RTを実行できますが、通常のデスクトップ処理に同じ厳しいレイテンシー目標が必要とは限りません。

用途で選ぶ · デスクトップホストか、期限を担う制御ホストか得られる効果と、見込むべき負担
汎用Linuxホスト画像認識 · 計画 · UI · 開発応答性、スループット、消費電力のバランスを取ります。高速なフィードバックは別のコントローラーに任せられます。
Linux + PREEMPT_RTの制御ホスト厳しい応答要件を持つ、検証済みのループLinuxのエコシステムを保ちつつ、カーネル起因の待ちを減らします。アプリケーションとI/O経路の準備も必要です。
PREEMPT_RTの仕組みと用途ごとのトレードオフ
負担・対応事項発生する理由用途に応じた判断
スループットが下がる可能性IRQスレッドへの切り替えと、優先度継承ロックの管理処理が加わります。実際の負荷で測定します。すべてに共通するオーバーヘッド率はありません。
設定項目の増加タスク・IRQの優先度、アフィニティー、共有リソースが相互に影響します。ネットワーク、ストレージ、システム管理処理が動く状態で制御を検証します。
低優先度処理が進まなくなるリスク常に実行可能なRTスレッドは、低優先度の処理から実行機会を奪う場合があります。実行と待機の上限を管理します。このリスクはPREEMPT_RTなしでも存在します。
消費電力とのトレードオフ遅延を減らす調整の一部は、深いアイドル状態や周波数変更を制限します。消費電力と熱のバランスを取ります。PREEMPT_RTの有効化だけで、これらの調整が必須になるわけではありません。
ドライバーの前提条件通常のスピンロックと割り込みの実行コンテキストが変わります。スピンロックは常にプリエンプションを禁止する、という前提の独自ドライバーを見直します。
PCでもPREEMPT_RTは動作します。その価値は時間要件によって決まります。どちらのカーネルを選んでも、アプリケーションにRT優先度や期限保証が自動的に与えられるわけではありません。

これらのコストはワークロードに依存します。IRQスレッドと優先度継承ロックは管理処理を増やし、CPU配置とドライバーの前提を見直す必要があります。深いスリープや周波数変更を無効にすると、応答時間と引き換えに電力効率が下がることがありますが、これはPREEMPT_RTの自動的な効果ではなく調整の選択です。Canonicalのレイテンシーガイド が実務上のトレードオフを説明します。CPUを占有し続けるリアルタイムスレッドは、非RTカーネルでも他の処理から実行機会を奪うことがあります。

この共存は開発者調査にも表れます。以下の2つのカテゴリは異なるハードウェア役割を扱っており、どちらもベンチマークでも特定MCUへの推奨でもありません。

Eclipse Foundation · 2025年開発者調査デバイスの役割によってソフトウェア構成は異なる
リソース制約のあるデバイス0~100% · 利用の回答割合
  • Linux/Raspbian45%
  • FreeRTOS32%
  • ベアメタル21%
  • Zephyr RTOS17%
  • ThreadX17%
  • ROS 27%
  • Contiki / Contiki-NG5%
  • Huawei LiteOS5%
IoTゲートウェイとエッジノード0~100% · 利用の回答割合
  • Linux/Raspbian62%
  • Android23%
  • Windows19%
  • ベアメタル12%
  • ThreadX10%
  • Zephyr9%
複数のシステムの利用が回答されています。割合は排他的な市場シェアでも、期限達成のテスト結果でもありません。分類は出典に従っており、ROS 2はミドルウェア、RaspbianはLinuxディストリビューションです。
図のレイアウトは次の資料を基に改変: 2025 Eclipse IoT・組み込み開発者調査レポート、15ページ。© Eclipse Foundation AISBL and contributors。図の改変版: CC BY-SA 4.0。数値と分類は維持しています。

「制約がある」という言葉は、アプリケーションに使えるRAM、フラッシュ、CPU、電力、I/Oの範囲に照らして捉えます。ESP32クラスのコントローラーとLinuxエッジコンピューターでは制約が異なります。調査でLinuxの利用率が高くても、デスクトップLinuxがESP32に合うことは示しません。実際のボードで、メモリ容量、MMU対応、ドライバー、測定したループ時間を確認する必要があります。

フライトコントローラーでも同じ経路IMUサンプル → 姿勢安定化 → モーター指令
  1. IMU動きを測定
  2. 推定器姿勢を推定
  3. 制御器補正量を計算
  4. ESCモーターの各相を駆動
  5. モーター推力を変化
PX4アプリケーション対応する飛行ボード上のNuttXArduPilotアプリケーション多くのSTM32ターゲットでChibiOSを使用
飛行アプリケーションがRTOSとボードのドライバーを使い、必要に応じて搭載するコンパニオンコンピューターが上位の目標値を供給します。

同じ構成はドローンの安定化にも使われます。対応するフライトボードでは、PX4は一般にNuttXを使い、多くのSTM32ターゲットでArduPilotはChibiOSを使います。PX4フライトスタック概要 、システムアーキテクチャ 、ArduPilot移植ガイド を確認してください。

四足歩行ロボットに戻る

これで、段差への補正が関節に届くまでを追えます。カーネルは実行順序を管理しますが、間に合うかどうかを決めるのは計測、制御、駆動の経路全体です。

段差の場面に戻る1回の補正を、時間経路全体で捉える
01変化を捉えるサンプルの取得時刻と鮮度を確認します。
02制御を実行可能にするイベントやリソースの待ちを解消します。
03時間配分内で実行する干渉と計算時間に上限を設けます。
04期限前に反映する転送とドライブの時間も含めます。
求める結果は、コントローラー構造全体が支える、間に合う物理的な補正です。

次のコントローラーでは、1つのセンサーイベントを物理出力まで追跡します。期限を明示し、各待ち時間を計上し、出力が反映される時点までハードウェアで検証してください。

そのコントローラーをアプリケーションに展開するには、VoicePingのロボット開発アプローチ を確認し、ハードウェア、制御インターフェース、受け入れ基準を一緒に定義してください。

この記事をシェア
動画
0:00 0:00