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 ↗この記事の内容
この記事の内容
ロボットには、補正が間に合うタイミングで正しい指令が必要です。**リアルタイムOS(RTOS)**は、計測から駆動までの処理を調整します。センサー入力からハードウェア出力まで、1つの関節補正がRTOSアーキテクチャを通る流れを追います。
1. プロセッサーは高速でも、ロボットの反応が遅れる理由
四足歩行ロボットが段差を検知し、正しい補正を計算する
四足歩行ロボットが、崩れた舗装石に足を乗せます。エンコーダーが関節角度の変化を報告し、慣性計測装置(IMU)が胴体の回転を検知します。コントローラーは補正を計算しますが、その指令が関節に届く間もロボットは動き続けます。

計算が正しいだけでは不十分です。以前の姿勢を前提にした指令は、その姿勢がすでに変わった後に到着することがあります。
ロボットが必要とする時点より後に補正が関節へ届く
この例では、アクチュエーター指令をセンサーサンプルから1ms以内に適用する必要があるとします。答えを0.2msで計算できても、応答全体が収まる証明にはなりません。
- 周期
- 定期的な更新の間隔
- 期限
- 完了が許される最も遅い時点
- 応答時間
- サンプリングから指令適用まで
- ジッター
- 更新ごとのタイミングのばらつき
平均応答時間が短くても、ときどき更新が遅れることはあります。リアルタイム制御には、経路全体の遅延を十分に抑え、安定したタイミングで実行する必要があります。ROS 2のリアルタイム解説 がこの違いを説明しています。
2. コントローラーが各ステップを調整する仕組み
CPU、メモリ、ドライバーがセンサー値を関節指令へ変える仕組み
マイクロコントローラーを使う組み込みシステムでは、CPUが計測値を読み、目標値を計算してドライバーを呼び出します。ドライバーが周辺機器を設定し、周辺機器がアクチュエーターインターフェースへ信号を届けます。
ロボットハードウェアガイド では、モーター、伝達機構、センサー、関節負荷がアクチュエーターインターフェースをどう形作るかを解説しています。
- センサーIMU/エンコーダーサンプルを取得
- CPU + RAM制御タスク目標値を計算
- ドライバーレジスター書き込み転送を設定
- 周辺機器タイマー/CAN信号を伝達
- 関節ドライブパワー段指令を適用
PWMドライバーはタイマーの比較レジスターに書き込めます。するとタイマーが各エッジをCPUで切り替えなくてもパルスを生成します。バスドライバーの場合は転送を準備し、DMAが補助することもあります。レジスター書き込み、転送完了、指令適用は別々の瞬間です。
命令レベルでは、メモリーマップドレジスターは周辺バスがデコードするアドレスです。CPUのストアは通常のRAM変数ではなく、ハードウェア状態を変えます。タイマーが新しい比較値を取り込むのは、次の更新境界だけの場合があります。STのタイマー・クックブック がこのプリロード機構を説明しています。CAN転送もバスの使用権を待つ必要があります。その後、ドライブが指令を適用する時点を決めます。これらの待ち時間はタスク選択の外側にあります。

- 01CPUのストア命令
- 02タイマーの比較レジスター
- 03PWM波形
- 04モータードライブ
制御ピンは信号を運びます。モータードライブが動作電力を供給し、より高速な電流ループを独自に実行することもあります。Physical AIを支えるエレクトロニクス では、その周辺回路と電力経路を追っています。
xTaskCreate()設定済みアロケーターがヒープから スタックとTCB を確保します。
xTaskCreateStatic()アプリケーションが スタック配列とTCB領域を用意します。
- スタック
- ローカル変数、関数呼び出し、保存したCPUコンテキスト
- TCB・タスク制御ブロック
- 優先度、リストへのリンク、保存スタックへのポインター
各タスクには、実行スタックとTCBのためのRAMが必要です。スタックは関数呼び出しの状態と保存レジスターを保持し、TCBはそのコンテキストの場所をカーネルに伝えます。タスクがBlocked(待機)状態でも、スタック用の領域は確保されたままです。
xTaskCreate()xTaskCreateStatic()本家のFreeRTOSでは、xTaskCreate()が設定済みアロケーターからスタックとTCBを取得します。xTaskCreateStatic()はアプリケーションが用意した領域を受け取ります。どちらもRAMを消費し、静的生成はこれらのオブジェクトのヒープ割り当てをなくすだけです。本家のFreeRTOSではスタック深さをStackType_tの要素数で指定しますが、ESP-IDFのタスク生成APIはバイト数を使います。スタックサイズを転用する前に、タスクAPI
とIDFポートの違い
を確認してください。
必要なメモリ容量を見ると、プラットフォームの違いが分かります。小さな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容量の目安 ↗ |
メモリの選択:MCUファームウェア、Linux、割り当て
MCUベースの組み込みシステムでは、チップ内SRAMにタスクスタック、サンプル、バッファーを保持し、ファームウェアは通常フラッシュに保存します。外部DRAMとMMUを持つアプリケーションプロセッサーは、Linuxプロセス、仮想メモリ、より大きなドライバースタックを支えられます。メモリ容量だけでタイミング保証は決まりません。
重要な作業領域はループ開始前に準備します。FreeRTOSは静的または動的なオブジェクト割り当て をサポートしますが、開発者はスタック、キュー、バッファーのサイズを決める必要があります。ヒープ管理ガイド で方式を確認できます。
RTOSカーネルの内部:タスク、割り込み、スケジューリングの連携
**RTOSはOSの分類です。**FreeRTOSとZephyrは、スケジューリングと同期を提供する実装です。開発者はそれらの仕組みを設定し、アプリケーションタスクを実装します。
FreeRTOSのタスクスケジューリングを追うため、ここではプリエンプティブなシングルコア構成を使います。制御タスクが新しいデータを待つ間、センシングとテレメトリーにはそれぞれ実行コンテキストを割り当てます。
カーネルは**タスク制御ブロック(TCB)**にタスク状態を保存します。pxTopOfStackが保存コンテキストの位置を示し、uxPriorityが優先度を決め、リスト項目が状態リストやイベントリストにつなぎます。RTOSコンテキストスイッチは、保存された実行地点からタスクを再開します。
優先度3 + 実行可能リスト / 待機リストへのリンク
保存されたCPUコンテキスト
切り替えが許可されると、実行可能なReadyタスクのうち最も優先度が高いものが選ばれます。高優先度タスクが一度も待機しないと、低優先度の処理が実行機会を失うことがあります。FreeRTOSのタスク実装 を参照してください。
シングルコアモデルでは、Readyリストを優先度別に管理します。キュー待ちでブロックすると、タスクはReady集合から外れ、待機タスクとして登録されます。有限のタイムアウトには遅延リストの管理も必要です。イベントやタイムアウトで再び実行候補になります。カーネルはリスト更新を保護し、割り込みが更新途中のスケジューリング構造を見ないようにします。設定によってはポート最適化ビットマップで優先度を検索しますが、すべてのチップで同じアルゴリズムではありません。
ここでセンサーがデータ準備完了割り込みを発生させます。ここから実行権が引き継がれるまでを追います。Ready(実行可能)になっても、まだRunning(実行中)とは限りません。
- 1待機
- 制御
- 待機
- CPU
- テレメトリータスク
制御タスクが新しいサンプルを待っています。その間は、優先度の低いテレメトリーがCPUを使えます。
- 2割り込み
- 制御
- 待機
- CPU
- センサーISR
データ準備完了の割り込みがタスクの実行に割り込みます。ISRがセンサーイベントを確認し、割り込み要因を処理します。
- 3起床
- 制御
- 実行可能
- CPU
- センサーISR
ISRから安全に呼べるカーネル操作で制御タスクを起こします。実行可能になりますが、ISRはまだ実行中です。
- 4切り替え
- 制御
- 実行可能
- CPU
- PendSV / コンテキストスイッチ
優先度の高い例外が切り替えを妨げなくなると、ポートが実行中だったタスクのコンテキストを保存し、選ばれたタスクを復元します。
- 5実行
- 制御
- 実行中
- CPU
- 制御タスク
例外からの復帰で制御タスクが再開し、サンプルを使って関節の補正量を計算できます。
Cortex-M4Fポートでは、コンテキストスイッチの要求によって、低優先度例外のPendSVを保留状態にできます。ハードウェアがまず例外フレームを保存し、ポートが残りのタスクコンテキストを保存して別のTCBを選び、そのタスクを復元します。**プロセススタックポインター(PSP)はタスクのスタックを指し、ハンドラーコードはメインスタックポインター(MSP)**を使います。
R0–R3 · R12 · LR · PC · xPSRR4–R11 · EXC_RETURN- 保存PendSVが残りのレジスターを切り替え前のタスクのスタックに保存します。
- 選択
vTaskSwitchContext()が、カーネルの保護下で次に実行できるタスクを選びます。 - 復元次のTCBからスタックポインターを読み込み、ポートが保存したレジスターを復元します。
- 復帰例外からの復帰でハードウェアフレームが復元され、保存されたPCから実行が再開します。
- PSP
- タスクのスタックポインター
- MSP
- ハンドラーのスタックポインター
- BASEPRI
- 割り込み優先度のマスクしきい値
ポートは次のタスクを選ぶ間にBASEPRIを上げ、カーネルデータへアクセスする可能性がある割り込み優先度をマスクします。より緊急度の高い割り込みは有効なままにできますが、対象のFreeRTOS APIを呼んではいけません。PendSVが保留されていても、実行中の高優先度ハンドラーに割り込んでタスクを切り替えることはできません。これはCortex-M4Fポート
に固有の説明で、ESP32のXtensaやRISC-Vアセンブリーの説明ではありません。
プリエンプションはティックの間にも反応できます。タイムスライシングは、同じ優先度の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複数の許可 | 空きバッファースロットを数える |
| ミューテックス | 所有権リソースへの排他アクセス | タスク間でバスアクセスを保護 基本的な優先度継承 |
サンプルが利用可能になると、待機中の受信タスクをBlocked → Readyへ移せます。次にCPUの実行権が必要です。セマフォが伝えるのは利用可能になったという状態であり、サンプルそのものではありません。ミューテックスには所有権と基本的な優先度継承があります。
FreeRTOS内部のキューは、循環ペイロードバッファー、要素数、送受信を待つタスクのリストを組み合わせます。送信は設定されたバイト数をコピーし、待機中の受信タスクを解放することがあります。セマフォはデータサイズ0の項目でキュー機構を再利用します。重要なのはペイロードバッファーではなく、カウントと待機リストです。ミューテックスは保持者も追跡し、カーネルがその所有者の優先度を一時的に上げられるようにします。キュー実装 で関係を確認できます。
キューの鮮度、イベント数、所有権
バイナリーセマフォは許可を最大1つしか保持しないため、繰り返すイベントがまとめられることがあります。カウンティングセマフォは複数の利用可能な許可を数えます。FreeRTOSにはタスク通知もあり、イベントの意味が合う単一の受信タスクに便利です。
制御キューが満杯になったとき、データを拒否するのか、古いデータを上書きするのか、オーバーランを報告するのかを決めます。古い滞留データより、最新の完全なサンプルが役立つ場合があります。ポインターを渡すメッセージには、バッファー所有権も明示する必要があります。キューの例 と共有キュー/セマフォ実装 を確認してください。
3. 重要な補正が遅れる理由
Readyの制御タスクがすぐ実行できない理由
高優先度のタスクでも、実行候補でありながらCPUを取得できないことがあります。依存関係を待っている場合もあります。タスク優先度を上げるだけでは、どちらの待ちも自動的には解消しません。
CPUが保護された処理や割り込み処理を実行中のため、タスクへの切り替えを待つ必要があります。
必要なサンプルやリソースが届いていない、またはタイムアウト条件が満たされていません。
クリティカルセクション、割り込みマスク、スケジューラー停止、ISR実行は、FreeRTOSを含めてタスクディスパッチを遅らせます。保護された処理に特別な「最高タスク優先度」があるわけではなく、切り替え可能な時点を一時的に制限します。
| 仕組み | CPUやカーネルの動作 | 制御が待つもの |
|---|---|---|
| 非RT Linuxのスピンロック | spin_lock() はローカルCPUでのタスクのプリエンプションを禁止します。IRQは有効なままの場合があります。 | 保護区間が終わり、再スケジュールが許可されるまで。 |
| 割り込みマスク | マスクされた割り込み源は、まだハンドラーを実行できません。 | マスク解除、イベント処理、その後の実行切り替えまで。 |
| ISRの実行 | ハンドラーコンテキストが、通常のタスク選択とは別にCPUを使います。 | 例外からの復帰やコンテキストスイッチが可能になるまで。 |
| スケジューラーの一時停止 | vTaskSuspendAll() はタスク切り替えを先送りにしますが、それ自体は割り込みをマスクしません。 | スケジューラーの再開と、保留された管理処理の完了まで。 |
| ミューテックスへの依存 | 別のタスクが所有するリソースを待って、タスクが待機状態になります。 | 所有者が処理を進めて解放するまで。優先度継承は他タスクの干渉を減らせます。 |
PREEMPT_RTを使わないLinuxで、ドライバーがspinlock_tを保持しているとします。有効な割り込みが高優先度の制御スレッドを起こし、再スケジューリング要求を設定できます。割り込みから戻っても、切り替え前にCPUが保護されたドライバー区間を完了しなければならないことがあります。制御スレッドはReadyですが、残りの保護処理も応答時間の予算に含まれます。
FreeRTOSのvTaskSuspendAll()は割り込みマスクとは異なります。ISRは実行できますが、スケジューラーが再開して延期された処理を扱うまでタスク切り替えが遅れます。一方、Cortex-Mのクリティカルセクションはポート固有の割り込みマスクを使います。タスクの優先度を上げても、どちらの仕組みも取り消せません。Linuxのロック規則
が、関連するスピンロックとIRQの違いを説明しています。
数値が大きいほど優先度が高い
- 中 · 2ログ記録を実行
- 低 · 1完了 + ロック解除
- 高 · 3ミューテックスを取得 + 制御
- 低 · 1 → 3完了 + ロック解除
- 高 · 3ミューテックスを取得 + 制御
- 中 · 2ログ記録は後で実行
優先度継承をサポートするミューテックスでは、所有者が待機中の高優先度タスクの優先度を一時的に継承します。所有者が処理を終えて資源を解放しやすくなります。ただし、クリティカルな処理をなくしたり、デッドロックを解消したり、応答しないデバイスの待ち時間を制限したりするものではありません。
カーネル保護、割り込み優先度、マルチコアロック
PREEMPT_RTではないLinux構成で通常のスピンロックを取得すると、そのCPUでのタスクプリエンプションが止まります。IRQを無効化する派生型はローカル割り込みマスクも加えます。Linuxのロック規則 が仕組みを区別しています。
タスク優先度とハードウェア割り込み優先度は別物です。ポート固有のマスク閾値が、どの割り込みがカーネルを呼べるかを決めます。マルチコアシステムでは、ローカルな保護だけで別CPUがアクセスできる資源を守れるとは限りません。
資源を保持する時間に上限を設け、ロックの連鎖を分析します。FreeRTOSの資源管理章 がミューテックスの所有権と基本的な優先度継承を説明しています。
FreeRTOSとデスクトップLinuxの違い、PREEMPT_RTの変更点
RTOSとLinuxを比較するなら、応答経路全体を考慮する必要があります。両方のカーネルがタスク状態、優先度、プリエンプション、割り込みを管理します。違いは、設定したシステムがその経路での干渉をどう制御するかです。
- TCB + 優先度別の実行可能リスト
- 実行可能な最高優先度タスクを選択
- ISR対応APIがタスクを起こす
- 残る遅延: クリティカルセクションで切り替えが遅れる場合がある
SCHED_FIFO / SCHED_RRを利用可能- ハードIRQ処理がタスクへの切り替えを遅らせる場合がある
spinlock_tはローカルのタスクプリエンプションを禁止- 残る遅延: 保護された経路では切り替えが後になる
- 大部分のIRQ処理がスレッドで動く
spinlock_tはRTミューテックスに基づく優先度継承を使用- プリエンプト可能なカーネル経路が増える
- 残る遅延: rawロックと低レベルの経路は保護されたまま
**PREEMPT_RTはLinuxの構成であり、FreeRTOSの機能ではありません。**スレッド化された割り込みと優先度継承(PI)に対応したスリープ可能なロックによって、より多くのカーネル処理をスケジューラーの管理下に置きます。
一般的なスレッド化IRQ経路では、ハード割り込みの短い初期処理で原因を確認またはマスクし、その後IRQスレッドを起こします。IRQスレッドはスケジューリングポリシーと優先度に従って競合します。PREEMPT_RTは通常のspinlock_tをRTミューテックスベースの実装に変えます。ロックを待つスレッドはスリープでき、優先度継承が所有者の処理を進めやすくします。raw_spinlock_t、低レベルの入口経路、明示的に保護された領域はプリエンプト不可のままです。RTカーネルの違い
を参照してください。
目盛り:0~1,500 µs · 破線:1,000 µsの期限
適切に構成したPC上のリアルタイムLinuxはロボット制御を実行できます。通常のUbuntuが厳しい期限を満たすと仮定できないのと同じく、検証していないFreeRTOSシステムも保証できません。オープンソースライセンスは、タイミングの問題とは別です。
スケジューリングで実行が許可された後でも、メモリが遅延を追加することがあります。仮想メモリでは、ページ割り当て、コピーオンライト、ファイルやスワップの読み込みが必要なため命令の実行中にページフォールトが発生することがあります。ストレージを伴うフォールトは一部だけです。一般的なMCUのFreeRTOSシステムはデマンドページングなしで常駐メモリを使いますが、割り当て、フラッシュ/キャッシュ、バス、デバイスによって処理が一時的に止まることはあります。
- 確保済みRAM
- タスクのスタックとバッファーを再利用
- デマンドページングによるページフォールトはない
Linuxの制御スレッドでは、ループ開始前に重要なバッファーとスタックページを準備し、必要なマッピングに事前アクセスしてページを準備し、エラーと上限を確認しながら適切なメモリーロックを使います。mlockall()が将来の割り当てやコピーオンライトを無害にするわけではありません。PREEMPT_RT自体もページフォールトをなくしません。メモリーロックのマニュアル
で制約を確認できます。
Linuxの優先度、ページフォールト、PREEMPT_RTのトレードオフ
Linuxには通常のアプリケーションポリシーと、SCHED_FIFOやSCHED_RRなどのリアルタイムポリシーがあります。nice値は、これらのポリシー設定の代わりにはなりません。スケジューリングマニュアル がインターフェースを定義しています。
アドレスが使えるようになる前に、ページフォールトが処理を追加することがあります。重要な領域を事前割り当てし、ページに事前アクセスし、失敗と上限を確認しながら適切なメモリーロックを使います。mlockall() はメモリの常駐を助けますが、CPU、ロック、キャッシュ、デバイスの遅延は解決しません。
スレッド化された処理や異なるロック方式は、ワークロードによってオーバーヘッドを増やしたりスループットを下げたりします。優先度、割り込み配置、電源管理、CPU配置、ドライバーには注意が必要です。コストはワークロード依存で、固定の割合ではありません。RT理論 、カーネルの違い 、ハードウェア制約 を確認してください。
ここで補正全体の時間配分を考えます。センシング、干渉、計算、転送、出力適用に別々の上限を置き、計算を中断する高優先度処理も含めます。
固定処理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遅れて到着します。これは説明用の値で、ボード上の測定値ではありません。
- 0 µsサンプル取得センサーのタイムスタンプ
- 70 µsISR開始GPIO / トレースマーカー
- 190 µs制御開始タスクマーカー
- 390 µs計算終了ドライバー呼び出しの境界
- 510 µs転送完了バス信号の記録
- 600 µs出力反映ドライブ / 出力マーカー
出力が実際に反映される時点まで測定します。スケジューラー遅延だけではドライブが指令を適用する時点は分かりません。また、1回の実行で観測した最大遅延は最悪値の証明ではありません。
ハードウェアで経路を検証する
センサー取得、ISR入口、タスク開始、計算終了、転送完了、出力適用にタイムスタンプを付けます。GPIOマーカーとロジックアナライザーが役立ちますが、各マーカーが同じイベントを追い、クロックドメインが明確になっている必要があります。競合する通信、ストレージ処理、割り込みも発生させた状態で試験します。
Canonicalのcyclictestガイド は経路のうちスケジューリングに関係する部分を測定します。Linuxリアルタイムアプリケーションモニター は、対応カーネルでフォールトや待機パターンを診断するのに役立ちます。ROS 2のリアルタイム解説 、PREEMPT_RT内部 、Zephyrミューテックス文書 も詳しく説明しています。
4. ローカル制御から完全なロボットへ
制御ファームウェアを構築し、カスタムSDKで公開する
FreeRTOSとLinuxの選択は、センシングと動作を担うハードウェアから始まります。RAM、CPUアーキテクチャ、周辺ドライバー、タイミング要件が、その仕事を担えるソフトウェアを決めます。以下は対応ターゲットでの選択例で、各プラットフォームに2つの選択肢を示します。
| チップ / ボード | 2つのソフトウェア候補 | 適合する理由 | ロボットでの役割とハードウェア上の理由 |
|---|---|---|---|
| ESP32 / S3 / C3無線MCU 数百KBの内蔵SRAM。容量はチップによって異なります。 | 小さなタスクカーネルなので、 スタックと無線バッファーの領域を残せます。IDFはチップのドライバーとサービスを統合します。 | 無線センシング / ロボットI/O。 無線でデータを交換し、タイマーとGPIOでローカルの信号を扱います。 | |
| RP2040 / RP2350Pico / Pico 2 MCU 264 KB / 520 KB SRAM ↗ | ベアメタルではカーネルのタスク管理負荷を避けられます。FreeRTOSは スケジューリングと同期 をSRAM内で提供します。 | エンコーダー / パルス生成。 PIO、タイマー、DMAは、信号の各エッジでCPUが処理しなくても信号を取得・生成できます。 | |
| STM32 F4 / F7 / H7Cortex-M MCUファミリー フラッシュとSRAMの容量は品種によって異なります。 | 構成可能なMCUカーネルが、Linuxの完全なプロセス環境なしで 制御、計測、通信 をまとめて管理します。 | モーター / 関節コントローラー。 ADC、タイマー、DMA、バスが、フィードバックの計測とアクチュエーターへの指令をつなぎます。 | |
| Nordic nRF52840無線Cortex-M4 MCU 256 KB RAM · 1 MBフラッシュ ↗ | Zephyrは無線サービスを統合します。単独のドライバーは より単純な周辺機器ファームウェアに適します。どちらもRAM容量の計画が必要です。 | 電池駆動のセンサー。 無線とスリープモードは間欠的な計測に適します。ベアメタルのnrfx単体はBluetoothスタックではありません。 | |
| STM32F765Pixhawk 4フライトコントローラー 512 KB RAM · 2 MBフラッシュ ↗ | ボードに合わせた飛行ファームウェアが、RTOSと センサードライバー、タスクのスタック、バッファーを組み合わせます。 | ドローンの姿勢安定化。 IMUの計測、推定、制御によって、適切な時刻にESC指令を出します。 | |
| BCM2712Raspberry Pi 5のアプリケーションSoC GB単位の外部DRAM ↗ | MMUと外部DRAMが プロセス、仮想メモリ、ファイルシステム、Linuxドライバーを支えます。 | ROS 2 / カメラ / ゲートウェイ。 マルチコアの演算とカメラ・ネットワークI/Oが、ホスト上の並行処理を支えます。 | |
| NVIDIA OrinJetson CPU / GPUモジュール GB単位のDRAM。容量はモジュールによります。 | LinuxはGPUとデバイスのサービスを提供します。対応リリースでは、RTカーネルが CPUへの実行切り替えと割り込み処理 を変えます。 | 画像認識 / AI推論。 GPUがフレームとテンソルを処理します。CPUのリアルタイム調整で、すべてのGPU処理の時間上限が決まるわけではありません。 | |
| Intel / AMDPC向けアプリケーションプロセッサー 外部DRAM + MMU。 | 幅広いプロセス・ドライバー基盤が大規模アプリケーションに対応し、RT構成が カーネルに起因する待ち時間を減らします。 | 開発 / 計画 / 検証済みの制御。 CPU性能は複雑な処理を支えます。直接制御には、適切なI/Oと時間特性の検証が必要です。 |
センシングとフィードバック制御には、明示的な起床条件、優先度、実行時間の上限、十分なスタックを与えます。解析、ネットワーク通信、ログ、ストレージがクリティカルループの資源を保持し続けないようにします。
カーネルはスケジューリングと同期を提供します。ファームウェアは制御動作とドライバーを提供し、カスタムSDKが指令と測定状態を公開します。
先ほどの割り込み引き渡しを、小さなFreeRTOSパターンで表します。要素数1のキューで最新の完全なサンプルを保持します。割り込みを有効にする前にキューとタスクを作成し、上限を定めたハードウェア経路でサンプルを取得します。
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);
}
}サンプルの合間は待機します。整合性のある目標値と、時間上限のある出力経路を使います。
ISRは完了したサンプルをコピーし、必要なら切り替えを要求します。タスクはCPUを消費せずに待機し、整合性のある目標値のスナップショットを読み、次の出力を計算してドライバーを呼びます。複数フィールドの目標は、メッセージパッシングまたは上限を定めたタスクレベルのロックで整合性を保った状態でまとめてコピーし、遅いI/Oの間はロックを保持しません。
周期ループでは、相対遅延を繰り返して処理時間を積み上げるのではなく、適切なタイマーやxTaskDelayUntil()を使います。ティック分解能は周期に合っていなければならず、ティック未満の要件には適切なハードウェアタイミング源が必要です。
既存のカーネル設定項目を使って、configUSE_PREEMPTION、優先度範囲、割り当て方式、スタックサイズを設定します。続いてタスクと同期を実装します。通常はReadyリストの選択を自分で書くのではなく、スケジューラーを設定して移植します。対応するデュアルコアESP-IDF構成でESP32上のFreeRTOSを動かす場合、スケジューラーはコアアフィニティーも考慮します。タスクを固定しても共有メモリやバスは分離されず、ローカル割り込みマスクで他方のコアを止めることもできません。共有データにはターゲットがサポートするコア間同期が必要です。
- 関節
- joint_3
- position_rad
- 0.15
- sequence
- 42
- 有効期限
- 定義された有効期間
- 実測位置
- ラジアン
- サンプルのタイムスタンプ
- 明示されたクロックドメイン
- 適用したシーケンス番号
- どの指令を使ったか
- ステータス
- 新鮮 / 古い / 障害
単位、受け入れ範囲、タイムスタンプ、シーケンス番号、確認応答、鮮度、タイムアウト動作を定義します。受信したことは、物理的に実行された証拠ではありません。
通信境界では、フィールド幅、バイト順、フレーミング、必要な完全性チェックを含むシリアライズを明示します。ホストによってパディングが異なる可能性のあるC構造体をそのまま送らないでください。コントローラーはパケットを検証し、完全な目標を公開し、実際に適用したシーケンスを報告します。タイムアウト時には、機構に適した保持、減速、故障応答を定義して選択できます。SDKは受信を動作の成功と混同せず、その状態を公開すべきです。
カスタムロボットでは、センシングとアクチュエーター統合とともに、これらのインターフェースの範囲を定めます。VoicePingのカスタムロボット開発 は、タスクと動作環境から始まります。
ESP-IDF、本家のFreeRTOS、マルチコアの選択
ESP-IDFはFreeRTOS実装、ドライバー、起動経路を統合します。対応するマルチコアターゲットでは、アフィニティーと共有資源を考慮します。本家のFreeRTOSもSMPをサポートしており、マルチコアスケジューリングをすべて手作業で実装する必要はありません。
ターゲットとリリースに対応するIDFドキュメント に従います。コア固定で一部の競合は減らせますが、共有バス、メモリ、割り込みの影響は分離できません。クロック同期と、タイムスタンプが取得時刻か送信時刻かを定義し、設定したシステムを検証します。
**カーネルが製品プラットフォームになる仕組み。**カスタマイズはカーネルポート、アプリケーションファームウェア、外部SDK境界のいずれでも行えます。独自のコントローラーを作るために、企業がスケジューラーを書き直す必要はありません。
FreeRTOS↓ターゲット向けポート + SMP統合 + ハードウェアドライバー↓アプリケーションタスク + ネットワーク・周辺機器サービス開発者がカスタマイズする部分タスクの優先度、アフィニティー、バッファー、 同期、アプリケーションの動作。
FreeRTOSタスク↓センサー準備完了 → 推定器 → 制御器 → モーター出力↓設定値、パラメーター、ログ記録 + ボードサポート開発者がカスタマイズする部分制御アルゴリズムとドライバー、 プラットフォーム設定、アプリケーションモジュール。
rt/lowcmd → ロボットqdqkpkdtau⇅rt/lowstate → アプリケーション開発者がカスタマイズする部分ホストの制御ロジックが利用するのは、 モーターの目標値と実測状態。 SDKは関節コントローラーのOSを明らかにしていません。
Espressifはハードウェア固有のFreeRTOS実装と統合を文書化しています。BitcrazeのCrazyflieは別の一般的な構成を示しています。FreeRTOSタスクを使い、センサーから推定器、コントローラー、モーターへ至るパイプラインを追加します。安定化のドキュメント とファームウェアソース でアプリケーション層を確認できます。
Unitreeは公開インターフェース層の例です。SDK2 Go2の例 は低レベルのモーター指令を公開し、状態を購読します。Python SDKはCyclone DDSを文書化 しています。これは拡張可能なロボットインターフェースを示しますが、非公開の関節コントローラーがFreeRTOSを使うことを示すものではありません。文書化されたSDKの動作と、内部ファームウェアへの推測を分けて扱います。
四足歩行ロボットやドローンでローカルRTOS制御とROS 2を接続する
このコントローラーをロボット全体の構成に組み込みます。ホストが動作を計画する間、ローカルコントローラーがフィードバックループを閉じ、関節ドライブが電流を制御します。各ループはタイミングを検証できる場所に割り当てます。

**ROS 2はミドルウェアであり、RTOSはOSカーネルまたはプラットフォームです。**役割が異なり、組み合わせて使うことが多くあります。選択したループを適切なLinux/PREEMPT_RTホストで実行することもできます。ROS 2のリアルタイム設計の議論 がアプリケーションレベルの制約を説明します。
Linuxはプロセス、カメラ/ネットワークドライバー、ロボットライブラリー、デプロイツールを提供するため、ホストに適しています。PREEMPT_RTはそのプラットフォームを保ったままカーネルの応答性を高めます。ROS 2のコールバックにも適切なエグゼキューター/スレッドポリシー、上限を定めた処理、準備済みメモリが必要です。RTカーネルだからといって、すべてのコールバックが自動的にリアルタイムになるわけではありません。FreeRTOSはローカルファームウェア向けの小さな実行環境であり、ホストのLinuxソフトウェア全体を置き換えるものではありません。
**カーネルより先にタイミング要件を決めます。**ビジョンやマッピングのホストは、別のMCUが高速ループを閉じる間、スループットと幅広いドライバースタックを必要とする場合があります。厳しい制御期限をLinuxホストが直接担うなら、適切なリアルタイム構成とエンドツーエンド検証が必要です。PCはPREEMPT_RTを実行できますが、通常のデスクトップ処理に同じ厳しいレイテンシー目標が必要とは限りません。
| 負担・対応事項 | 発生する理由 | 用途に応じた判断 |
|---|---|---|
| スループットが下がる可能性 | IRQスレッドへの切り替えと、優先度継承ロックの管理処理が加わります。 | 実際の負荷で測定します。すべてに共通するオーバーヘッド率はありません。 |
| 設定項目の増加 | タスク・IRQの優先度、アフィニティー、共有リソースが相互に影響します。 | ネットワーク、ストレージ、システム管理処理が動く状態で制御を検証します。 |
| 低優先度処理が進まなくなるリスク | 常に実行可能なRTスレッドは、低優先度の処理から実行機会を奪う場合があります。 | 実行と待機の上限を管理します。このリスクはPREEMPT_RTなしでも存在します。 |
| 消費電力とのトレードオフ | 遅延を減らす調整の一部は、深いアイドル状態や周波数変更を制限します。 | 消費電力と熱のバランスを取ります。PREEMPT_RTの有効化だけで、これらの調整が必須になるわけではありません。 |
| ドライバーの前提条件 | 通常のスピンロックと割り込みの実行コンテキストが変わります。 | スピンロックは常にプリエンプションを禁止する、という前提の独自ドライバーを見直します。 |
これらのコストはワークロードに依存します。IRQスレッドと優先度継承ロックは管理処理を増やし、CPU配置とドライバーの前提を見直す必要があります。深いスリープや周波数変更を無効にすると、応答時間と引き換えに電力効率が下がることがありますが、これはPREEMPT_RTの自動的な効果ではなく調整の選択です。Canonicalのレイテンシーガイド が実務上のトレードオフを説明します。CPUを占有し続けるリアルタイムスレッドは、非RTカーネルでも他の処理から実行機会を奪うことがあります。
この共存は開発者調査にも表れます。以下の2つのカテゴリは異なるハードウェア役割を扱っており、どちらもベンチマークでも特定MCUへの推奨でもありません。
- Linux/Raspbian45%
- FreeRTOS32%
- ベアメタル21%
- Zephyr RTOS17%
- ThreadX17%
- ROS 27%
- Contiki / Contiki-NG5%
- Huawei LiteOS5%
- Linux/Raspbian62%
- Android23%
- Windows19%
- ベアメタル12%
- ThreadX10%
- Zephyr9%
「制約がある」という言葉は、アプリケーションに使えるRAM、フラッシュ、CPU、電力、I/Oの範囲に照らして捉えます。ESP32クラスのコントローラーとLinuxエッジコンピューターでは制約が異なります。調査でLinuxの利用率が高くても、デスクトップLinuxがESP32に合うことは示しません。実際のボードで、メモリ容量、MMU対応、ドライバー、測定したループ時間を確認する必要があります。
- IMU動きを測定
- 推定器姿勢を推定
- 制御器補正量を計算
- ESCモーターの各相を駆動
- モーター推力を変化
同じ構成はドローンの安定化にも使われます。対応するフライトボードでは、PX4は一般にNuttXを使い、多くのSTM32ターゲットでArduPilotはChibiOSを使います。PX4フライトスタック概要 、システムアーキテクチャ 、ArduPilot移植ガイド を確認してください。
四足歩行ロボットに戻る
これで、段差への補正が関節に届くまでを追えます。カーネルは実行順序を管理しますが、間に合うかどうかを決めるのは計測、制御、駆動の経路全体です。
次のコントローラーでは、1つのセンサーイベントを物理出力まで追跡します。期限を明示し、各待ち時間を計上し、出力が反映される時点までハードウェアで検証してください。
そのコントローラーをアプリケーションに展開するには、VoicePingのロボット開発アプローチ を確認し、ハードウェア、制御インターフェース、受け入れ基準を一緒に定義してください。


