Azure RTOSのキューを使ったプロジェクトを作成し、スレッド間のメッセージ送受信方法を説明します。メッセージキューは、比較的判り易い機能です。先にまとめ、次に詳細の順に説明します。
まとめ
Azure RTOSのスレッド間メッセージ送受信には、キューが用いられます。
STM32G4評価ボードのAzure RTOSメッセージキューサンプルコードが無いため、NUCLEO-G0B1REのTx_Thread_MsgQueueサンプルコードを流用し、AzureRtosQueueプロジェクトを作成しました。
作成したAzureRtosQueueプロジェクトを使い、基本的なAzure RTOSメッセージキュー機能を、STM32G4評価ボードにArduinoプロトタイプシールドを追加し説明、動作確認しました。
本稿説明のAzure RTOS APIは、下記です。
・メッセージキュー作成:tx_queue_create
・メッセージキュー送信:tx_queue_send
・メッセージキュー受信:tx_queue_receiveと、TX_NO_WAIT / TX_WAIT_FOREVER
・メッセージキュー送信時通知:tx_queue_send_notifyと、キュー イベント チェーン
複数のQメッセージを受信スレッドで処理し、かつ、メッセージ無しの時、受信処理を中断する場合は、Azure RTOSキュー イベント チェーン(Queue Event chaining)機能が効果的です。
STM32G4 Azure RTOSサンプルコード探し
現在、STM32G4(Cortex-M4/170MHz)評価ボード:NUCLEO-G474REへのAzure RTOSサンプルコードは、3個、この中にキューサンプルコードはありません。
そこで、逆にExample Selectorから流用できるキューサンプルコード:Tx_Thread_MsgQueueを探します。選定条件は、利用中のCubeIDE版数(v1.9.0)、評価ボード(Nucle-64)に近いものが良いでしょう。
CubeIDEのInformation Centerℹ️でImport STM32CubeMX exampleをクリックし、Example SelectorタブでThreadXにチェックを入れて選定します。
選定したNUCLEO-G0B1REのTx_Thread_MsgQueueコードを、STM32G4へ流用します。
AzureRtosQueueプロジェクト
下表が、Tx_Thread_MsgQueueの処理内容です。STM32G4評価ボード:NUCLEO-G474REとArduinoプロトタイプシールド用に、赤の工夫を加えました。評価ボード+Arduinoプロトタイプシールドの目的は、Azure RTOS習得(2)を参照してください。
スレッド名 | 処理内容:Q1/Q2によるメッセージ送受信
(LD2:評価ボード単体+ |
優先度 | プリエンプション閾値 |
送信スレッド1 | 500ms毎にSET_GRN_LEDメッセージをQ1へ送信 Q送信失敗時、LD2点灯+停止 |
5 | 5 |
送信スレッド2 | 1s毎にRESET_GRN_LEDメッセージをQ2へ送信 Q送信失敗時、LD2点灯+停止 |
5 | 5 |
受信スレッド | Q1とQ2、両方からメッセージ受信 Q1受信成功時、LED1トグル点灯+VCP出力 Q2受信成功時、LED2トグル点灯+VCP出力 受信失敗時、LD2点灯+停止 |
10 | 10 |
AzureRtosQueueプロジェクト作成
AzureRtosQueueプロジェクト作成方法は、前稿のAzureRtosEventFlagと同じです。汎用テンプレートAzureRtos0をコピー&別名AzureRtosQueueでペーストし、AzureRtosQueueプロジェクトを作成します。ペースト先のAzureRtos0.icoも、AzureRtosQueue.icoへRenameします。
これで、AzureRtosQueueプロジェクトのひな型ができました。
NUCLEO-G0B1REのTx_Thread_MsgQueueコードapp_threadx.c/hを流用し、AzureRtosQueueプロジェクトの、app_threadx.cとapp_threadx.h へ追記します。追記コードの一部抜粋が下記です。
app_threadx.c追記例
app_threadx.h追記例
Azure RTOSメッセージキュー
Azure RTOSのスレッド間メッセージ送受信には、メッセージキューが用いられます。
送信スレッド1/2のtx_queue_sendで、Q1/2へメッセージ送信、受信スレッドのtx_queue_receiveで、Q1/2からメッセージ受信、メッセージ内容を確認し、受信成功ならLED1/2をトグル点灯させます。
送信スレッド1/2は、同じ優先度とプリエンプション閾値です。送信間隔が同じ500msだと煩雑ですので、スレッド2は、1秒送信間隔へ変更しました。
Azure RTOSメッセージキューの送受信は、比較的判り易い機能です。メッセージキューを作り(tx_queue_create)、そのQへの送受、STのKnowledge Baseに判り易いアニメもあります。
しかしながら、受信スレッドが、複数Qからのメッセージ処理を行い、かつ、メッセージ無しの時に無限待ち(TX_WAIT_FOREVER)の場合には、キュー イベント チェーン(Event chaining)が効果的です。
本サンプルは、複数Qからの受信処理を行いますが、待ち無し(TX_NO_WAIT)の例です。
キュー イベント チェーン
Azure RTOS ThreadX 機能第 3 章の中程に、“キュー イベント チェーン”の説明があります。簡単に抜粋すると、
本受信スレッドのようにQ1とQ2の両方からメッセージを受信し、メッセージ無しの時、受信中断もある場合は、Q1/Q2に通知関数を登録(tx_queue_send_notify)し、カウントセマフォを使うキュー イベント チェーンが有効。キュー イベント チェーンなしでの実現は“非常に困難”。
流用サンプルコードのreadme.htmlにもキーワード:Event chainingがあります。しかし、このキュー イベント チェーンは未実装です。
カウントセマフォなしでは非常に困難でRTOSらしい機能ですが、各自でお試しください、ということでしょう😢。本ブログもこの方針に従いました。