MCU:マイコン,LPCマイコン,Cortex-M4コアテンプレート,FreeRTOS,LPCXpreosso54114,LPCXpresso SDK,queue,freertos_generic

FreeRTOSアプリケーションテンプレートのQueue利用タスク間データ送受信を説明します。これは、テンプレートのベースとしたMCUXpresso SDK付属FreeRTOSサンプルプロジェクトfreertos_generic解説の後半に相当します。

FreeRTOSアプリケーションテンプレートのベースプロジェクト(まとめ図参照)は、本稿で全て説明済みとなります。下記1~3が、関連投稿です。1~3の順にお読み頂くと、内容が解り易いと思います

  1. FreeRTOSアプリケーションテンプレート構想
  2. FreeRTOS新規プロジェクト作成からアプリケーションテンプレートまで
  3. テンプレートベース:freertos_generic前半(ソフトウェアタイマ関連)

freertos_genericのQueueによるデータ送受信

freertos_genericのQによるデータ送受信
freertos_genericのQによるデータ送受信

FreeRTOSでは、送信タスクと受信タスクの2つに分離しデータ送受信処理を開発します。

送信タスクは、自分の都合の良いタイミングで、いつでもデータ送信を始めます。受信タスクは、いつ始まるか判らないデータ送信に対し、常時受信できるように待機中です。但し、受信タスクの受信開始タイミングは、その他のタスク優先度により変動します。

この受信開始変動があっても送信データを取りこぼし無く受信するために、送受タスク間で一時データを格納するFIFOバッファが必要で、これがQueue(以下Q)です。マルチタスクによる副作用と言えます。

もちろん、データ溢れが生じないようQには複数データを蓄える深さも必要です。受信タスクは、データのQ完了イベントで、FreeRTOSが受信開始を起動します。また、送信タスクよりも、受信タスクの方が優先度が高いのは、Qデータ溢れ防止策です。

1データ長、データ送信タイミング、その他のタスク数やその優先度にも影響されるQの深さは、十分な検討が必要です。

freertos_genericでは、Qの深さを1データ、送信タスク優先度を1、受信タスク優先度を2とし、データを100固定値にして1バイトデータ長の送受信を行い、送信開始タイミングは、vTaskDelayUntil(後述)で作成しています。その他のタスクが、freertos_generic前半で説明したソフトウェアタイマタスク、この優先度が4です。

同一優先度のタスクが無く、他のタスク数もタイマタスク1個で高優先、1バイトデータ長のため、深さ1のQでも送受信データは溢れません。

少ないタスク数と同一優先度無しのシンプルなサンプルプロジェクトですが、簡単に説明しても上記のように長くなります。

ベアメタル開発経験者であれば、RTOS個々の文章説明(=Serial or Sequential動作)は、理解できます。しかし、RTOSによりシングルコアMCUであっても各タスクが時分割Parallel動作しますので、途端に解り難くなります。

BareMetal/SerialからRTOS/Parallelへ、従来の設計手法をステップアップする必要がありそうです。

vTaskDelayUntil対vTaskDelay

vTaskDelayUntilとvTaskDelay比較
vTaskDelayUntilとvTaskDelay比較

freertos_genericは、データ送信タイミングの作成に、他のサンプルでよく見かける待ち処理:vTaskDelayではなく、vTaskDelayUntilを使っている点に注意が必要です。

vTaskDelayは、指定待ち「時間」後、RTOSにより優先度に応じて次処理が実行されます。ゆえに、高優先の他タスクやその状況により、次処理実行までの待ち時間が変動します。

vTaskDelayUntilは、指定待ち「周期」後、次処理が実行されます。仮に2周期よりも長い待ちが発生した時は、次処理はスキップされます。つまり、vTaskDelayよりもデータ送信の(スキップも含めると)定間隔、周期性に優れています。

サンプルプロジェクトの場合、Qの深さが最小の1のため、vTaskDelayUntilの方が、Q溢れ対策として効果があります。vTaskDelayだと、変動を考慮し、より深いQが必要になりそうです。但し、vTaskDelayUntilのRAM使用量は、vTaskDelayよりも増えます。

つまり、vTaskDelayUntil 利用か、それとも、vTaskDelayとQの深さ利用か、どちらにRAM資源を割当てる方が、よりQ溢れ対策として効果的か、これが検討ポイントの1つです。freertos_genericでは、前者を選択した、と筆者は解釈しました。

参考資料:Kernel > API Reference > Task ControlのvTaskDelayUntilとvTaskDelay

本稿まとめとFreeRTOSアプリケーションテンプレート目的

FreeRTOSアプリケーションテンプレートのQ利用タスク間データ送受信を説明しました。Qにより、送信タスクと受信タスクを分離して開発できますが、Qの深さは、送受タスク以外の他タスク優先度など多くの要因にも関係するため、設計に注意が必要です。

FreeRTOS利用メリットは、ベアメタル開発に比べ、独立性や流用性が高いタスク開発ができることです。反面、優先度に応じたマルチタスク環境では、ベアメタル開発には無かったスキルも必要になります。

本稿説明のSDK付属FreeRTOSサンプルプロジェクトfreertos_genericをベースにした、Cortex-M4コア最高速150MHz動作LPCXpresso54114対応のFreeRTOSアプリケーションテンプレートは、6E目標に開発中です。

FreeRTOS Application Template (NXP Version)
FreeRTOS Application Template (NXP Version)

同じ動作のアプリケーションを、FreeRTOSとベアメタル、それぞれで開発した2つのプロジェクトを添付します。

FreeRTOSアプリケーションテンプレートの目的は、FreeRTOS特有スキルを、ベアメタルと比較し、具体的に理解・習得すること、基本的なFreeRTOSアプリケーション開発テンプレート(=スタートプロジェクト)としても使えること、の2点です。

なお現行のLPCXpresso54114開発SDKツールデフォルトコア速度100MHzを150MHz動作へ変える方法は、前稿を参照してください。

MCU:マイコン,LPCマイコン,Kinetisマイコン,Cortex-M4コアARMマイコン,IoTマイコン,MCUXpresso,FreeRTOS,LPCXpresso54114,event,queue,freertos_generic

MCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコード調査最終回の本稿は、タスク数=3のプロジェクト、freertos_eventとfreertos_queue、freertos_genericを説明します。

FreeRTOSサンプルコード:タスク数=3

FreeRTOSプロジェクト:タスク数=3
Project Tasks heap_ Additional FreeRTOS APIs Additional Comments
freertos_event 3 4 xEventGroupCreate xEventGroupSetBits
xEventGroupWaitBits

タスクや割込みなどのイベントをグループ化し、他タスク制御。

セマフォと似ているがイベントの論理演算可能。

freertos_queue 3 4 xQueueCreate
xQueueSend
xQueueReceive
vQueueAddToRegistry
タスク間メッセージ通信デモ。キューは、順序維持FIFO構造。
freertos_generic 3 4

キュー、ソフトウェアタイマ、セマフォの組合せデモ。

FreeRTOS.orgサンプルコードに基づき作成。

※freertos_genericのAdditional FreeRTOS APIは、これまでのサンプルAPI組合せのため追加分なし。

FreeRTOS Project:freertos_event

イベントによるタスク制御は、セマフォに似ています。複数のセマフォを1つにまとめたイベントグループを作成(xEventGroupCreate)し、このグループ化した個々のイベント間で論理演算ができることが特徴です。

xEventGroupWaitBitsの例(出典:freertos_event.c)
xEventGroupWaitBitsの例(出典:freertos_event.c)

イベント間の論理演算ができるので、シングルイベントのセマフォよりも柔軟なタスク制御ができます。

FreeRTOS Project:freertos_queue

これまで説明してきたプロジェクトのタスク間制御には、ミューテックスやセマフォ、上記イベントなど全てビット単位のシグナルを使ってきました。最後に説明するプロジェクトfreertos_queueは、タスク間でメッセージを送受信します。

メッセージは、キュー=有限長FIFO(First In First Out)経由で送受信されますので、メッセージの順番は維持されますが、キューが溢れないような使い方が必要です。深すぎるキューはメモリ効率が悪く、浅いキューではメッセージが溢れます。深さ見積もりなどのためにプロトタイプ開発が必要でしょう。

例えば、複数センサ出力をMCUでまとめ、定期的にクラウドへ送信するようなFreeRTOSアプリケーションソフトの素になりそうなプロジェクトです。クラウドサービスにAmazon Web Service(AWS)を使う時には、専用のネットワーク接続ライブラリもFreeRTOSで提供されますので、このアプリケーションとの親和性も良いと思います。

FreeRTOS Project:freertos_generic

MCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコード11個の説明の最後が、このfreertos_genericプロジェクトです。これまで説明してきた10個のサンプルコードを総合的にまとめたプロジェクトで、出典はhttp://www.freertos.org/Hardware-independent-RTOS-example.htmlです。

筆者の下手な説明よりも、実際にソースコードを見て頂くと丁寧なコメント付きです。このソースコードを読んでFreeRTOSの仕組みがすんなりと理解できれば、ベアメタルからFreeRTOSソフトウェア開発へのステップアップ初期段階は完了と言えるでしょう。つまり、10個サンプルコード習得度の自己評価に使えます。

FreeRTOSサンプルコード:タスク数=3の調査結果

  • 複数セマフォを1つにまとめたイベントグループタスク制御は、イベント間の論理演算が可能
  • キュー利用のタスク間メッセージ通信は、深さ設定にプロトタイプ開発が有効
  • freertos_genericは、SDK付属サンプルコード10個の習得度評価に使える
  • メモリ使用法は、heap_4を利用

まとめ:MCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコード調査

5回に渡ってMCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコードをタスク数が少ない順に調査しました。基本的なFreeRTOS機能は、解説済み11個のサンプルプロジェクトでカバーされています。

各プロジェクトの追加分FreeRTOS APIのみを表で示し、しかも弊社サイトマイコンRTOS習得2017の内容は既にご存じという前提で説明したので、解りにくい部分もあったかもしれません。
要するに、ベアメタル開発にFreeRTOS APIを追加すればRTOSソフトウェア開発ができることを強調したかったからです。

FreeRTOSのマルチタスク並列動作、タスク間同期/競合回避手段、これらのFreeRTOS APIのみを理解すれば、ベアメタル開発経験がそのまま活かせます。

今回の1~5回の解説は、マイコンRTOS習得2020年版として2017年版サイトへ改版する予定です。改版後にご覧になれば解りにくさが改善されるかもしれません。

調査目的は、開発予定のベアメタルCortex-M4テンプレートへのRTOS機能応用でした。現時点で、応用内容は不明確です。しばらく時間を頂いて明確化します。

ただ、マルチタスクFreeRTOSと異なり、ベアメタルテンプレートは、全て自分の制御下タスクです。タスク間同期やメッセージ送受信も、特別な工夫なく簡単に実現できます。

FreeRTOS利用MCUのAWS接続(出典:Amazon FreeRTOSの開始方法に加筆)
FreeRTOS利用MCUのAWS接続(出典:Amazon FreeRTOSの開始方法に加筆)

上図のように、AWSへの接続やIoTセキュリティ機能追加など今後必須になるIoT MCUの機能実装は、専用ライブラリベース、特にFreeRTOSライブラリで提供される可能性が高いと予想できます。

これらライブラリは、ベアメタル開発でも利用可能ですが、FreeRTOSソフトウェアの方が親和性も高く開発が容易なことも事実です。

しかも、これら専用ライブラリで実行される処理内容は、本来我々開発者が変更を加えるべきでない定型処理です(もちろんプロパティなどのパラメタは、開発者依存です)。

いずれにしても、MCUXpresso54114を使ったFreeRTOSソフトウェア開発環境と基本機能は習得できたので、ベアメタルCortex-M4テンプレート開発へ活かしていきます。