PR:この記事にはアフィリエイトリンクが含まれます。
FreeRTOSをCortex-Mで使うと、タスク管理の考え方は大きく変わります。処理をタスクに分け、優先度や待ち時間を設計するのが基本です。API名よりも割り込みとタスクの境目を理解するところで、混乱が起きやすいですね。
センサー受信、制御演算、ログ出力を一つの関数で続けると、遅い出力処理に制御まで引きずられがちです。RTOSなら仕事を分けられます。ただし、共有データや優先度を誤ると、止まった理由が見えにくくなるところがあります。
小さな計測器でセンサー受信、データ処理、出力を別のタスクに分けると、ISRやキュー、ミューテックスの役割が見えてきます。どの処理を待たせるか、値をどう渡すか。実践では、その判断が欠かせません。
書籍早見表
Cortex-MでFreeRTOSを始める本は、実機の動作例を追うものからRTOSの仕組みを広く学ぶものまであります。扱う範囲を見ておくと、手元の開発環境と照らし合わせやすくなります。
| 書籍 | 主な題材 | 合う読み方 |
|---|---|---|
Hands-On RTOS with Microcontrollers | STM32F767ZI、FreeRTOS、DMA、SEGGER | 実例を動かしデバッグまで追う |
| Beginning STM32 第2版 | STM32、Cortex-M3、GCC、libopencm3 | 環境構築と章末演習を試す |
Embedded RTOS Design | Nucleus SE、小規模カーネル | スケジューラや同期の背景を読む |
The Designer’s Guide to the Cortex-M Processor Family | Cortex-M0、M0+、M3、M4、M7、CMSIS-RTOS | 割り込みとCPU機能を整理する |
書籍の価格は紙版と電子版、在庫、販売時期によって変わります。版や送料も含め、注文時の販売画面で確認してください。
タスクに分ける
タスクは処理のまとまりです。ひとつずつ専用のスタックと優先度があります。センサーを読むタスク、値を計算するタスク、画面に出すタスクに分ければ、表示が遅れても読み取りを続けやすくなります。
スケジューラは、実行できるタスクの中から優先度が最も高いものを動かします。高優先度のタスクが待ち状態に入れば、CPUは別のタスクへ移ります。優先度は機能の重要度より締切の厳しさで決めましょう。
細かく分ければよい、というものでもありません。タスクが増え過ぎると、キューやスタックの管理が複雑になります。まずは入力、判断、出力のように役割で分け、同じデータを複数タスクが直接書き換えない形にすると見通しがよくなりますね。
状態と優先度
タスクの状態は、実行中、実行可能、ブロック中、停止中などに分けられます。時間経過やキューの到着を待つタスクはブロック中です。CPUを使わず再開条件を待てます。
周期処理には、短いループと遅延を重ねるよりvTaskDelayUntilのような周期起動が便利です。処理時間の揺れを抑えやすくなります。ただしティック周期より細かい精度は出ません。厳しいタイミングにはタイマー周辺回路も検討します。
高優先度タスクがずっと実行可能だと、低優先度の通信やログ処理は動けないことがあります。待てる場面ではきちんと待つ、処理を短く保つ。この基本が大切です。同じ優先度間の切り替えは設定に左右されるので、前提も確認してください。
割り込みから渡す
ISRは割り込みサービスルーチンです。周辺機器のイベントにすぐ応じる短い関数で、UARTの受信完了やタイマー更新を確認したら、必要なデータを退避して後続の処理をタスクへ渡します。解析までISRで抱え込まないこと。
ISRからタスクに知らせるには、FromISR付きのAPIを使います。通常のタスク用APIとは呼び出せる状況が異なるためです。受信イベントをキューへ送り、高優先度のタスクが起きた場合は割り込み終了後に切り替えを要求します。
Cortex-Mでは、割り込み優先度の番号が小さいほど緊急です。FreeRTOSのAPIを呼べる優先度には境界があります。設定値より緊急側のISRからカーネルAPIを呼ぶと不具合の原因に。数値の向きと設定を一緒に確認しましょう。
ISR内でミューテックスを取ったり、長く待ったり、大量のログを出したりするのは避けます。DMAを使う場合も、ISRでは転送完了を知らせるところまでにして、データの解釈や表示はタスクに任せると応答性を保ちやすくなります。
共有データを守る
Cortex-Mが単一コアでも、タスクの途中で別タスクに切り替わり、同じ変数を更新すれば競合します。割り込みとの間でも同様です。複数タスクが同時に走らなくても、切り替わりを前提に共有範囲を設計します。
値を渡すならキュー、単純な起床通知にはタスク通知を使います。イベントの合図にはバイナリセマフォが便利です。複数タスクで共有バスやログ出力先を使うときは、ミューテックスで共有を制御します。
ミューテックスには優先度継承があります。低優先度タスクが資源を使っている間、高優先度タスクを長く待たせにくくする仕組みです。ただし割り込みからは使えません。ロック中に通信完了を待つなど、長い処理を含めないのが基本です。
短い共有区間ならクリティカルセクションも使えますが、割り込み禁止時間が延びるほど応答は遅れます。volatileはコンパイラーの読み書き最適化を抑える指定です。排他制御や複数段階の更新を安全にする機能ではありません。
UARTとDMAの例
UARTで受けたコマンドに応じてセンサー値を返す流れを考えます。UART割り込みまたはDMA完了ISRが受信バッファを確定し、解析タスクへ通知。タスクはコマンドを読み、応答を送信タスクへ渡します。
受信データをキューにコピーするか、バッファ番号を通知するかはデータ量で決めます。小さなコマンドならコピーが簡単です。大きなパケットにはダブルバッファを使い、解析タスクが読み終えるまでDMAが同じ領域に上書きしないルールを設けます。
キューが満杯になったとき、古いデータを捨てるか、新しいデータを拒否するかを決めます。エラー数を記録する方法もあります。方針が曖昧なままだと、通常は動いても連続受信で壊れることがあります。
Cortex-M7などデータキャッシュを使う構成では、DMAとCPUのメモリー整合にも注意が必要です。バッファの配置やキャッシュのクリーン・無効化を確認してください。CPU側で正しく見えていても、DMA側で同じとは限りません。
遅れを測る
応答時間にはタスクの処理時間に加え、割り込み禁止区間、高優先度ISR、先行するタスクの実行時間が影響します。締切のある処理は、イベント発生から開始までを測りましょう。
GPIOをイベント受付時とタスク開始時に切り替えると、オシロスコープやロジックアナライザーで遅れを確認できます。タイムスタンプを残す方法も有効です。通信集中時やログ出力時の最大値も見ておきたいところです。
スタック不足は不定期な停止やメモリー破壊に見えることがあります。各タスクのスタック余裕、キューの最大使用数、取りこぼし数を記録しておくと、再現しにくい問題に備えられます。診断処理そのものが負荷にならない工夫も必要です。
本で補う
実機ならHands-On RTOS with Microcontrollers 第2版が合います。STM32 Nucleo-F767ZIでタスク、同期、UART・USB・DMAのISRを扱い、20以上の例とSTM32CubeIDE、SEGGER Ozone、SystemViewのデバッグを追えます。
Beginning STM32 第2版はGCCとlibopencm3の環境づくりから扱います。STM32F103を含むCortex-M3でFreeRTOSのタスク、ミューテックス、USART割り込みを学び、章ごとの演習も試せます。
Embedded RTOS DesignはNucleus SEを題材にした本です。スケジューリング、割り込み、イベント、メールボックス、スタック配置をコードで学びます。FreeRTOSのAPI解説とは役割が異なります。
The Designer’s Guide to the Cortex-M Processor Family 第3版では、例外処理、メモリー保護、CoreSightを扱います。CMSIS-RTOSも含み、Cortex-Mの動作原理を学べます。
結論
Cortex-M上のFreeRTOSは、優先度を決めるだけでは安定しません。ISRは短く保ち、タスクへはキューや通知で渡します。共有資源には目的に合う同期方法を使う。この基本がそろうと、遅れやデータ競合の原因を追いやすくなります。
まずはUART受信や周期センサーなど、小さな処理で試します。割り込みからの通知、キューが満杯になった場合、最大応答時間まで記録してください。そこまで確認しておくと、機能を増やした後も原因を探りやすいですね。
STM32F767ZIでFreeRTOSとデバッグを学ぶ人にはHands-On RTOSをおすすめします。GCCと演習でSTM32を学ぶならBeginning STM32が合います。
書籍の価格は版や時期で変わります。注文時に販売画面で確かめてください。
Amazon の PC をスコア化してみた
Amazonにある8〜14インチの小型WindowsタブレットやノートPCを、スペック別にスコア化して比較・ランキング。




