Azure RTOS習得(4):メッセージキュー

Azure RTOSのキューを使ったプロジェクトを作成し、スレッド間のメッセージ送受信方法を説明します。メッセージキューは、比較的判り易い機能です。先にまとめ、次に詳細の順に説明します。

まとめ

Azure RTOSメッセージキュー送受信
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へ流用します。

STM32G4 Azure RTOSキューサンプルコードの探し方
STM32G4 Azure RTOSキューサンプルコードの探し方

AzureRtosQueueプロジェクト

下表が、Tx_Thread_MsgQueueの処理内容です。STM32G4評価ボード:NUCLEO-G474REとArduinoプロトタイプシールド用に、赤の工夫を加えました。評価ボード+Arduinoプロトタイプシールドの目的は、Azure RTOS習得(2)を参照してください。

スレッド名 処理内容:Q1/Q2によるメッセージ送受信

(LD2:評価ボード単体+
Arduinoプロトタイプシールド

優先度 プリエンプション閾値
送信スレッド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.c追記ソースコード抜粋(橙色は注意箇所)
app_threadx.c追記ソースコード抜粋(橙色は注意箇所)

app_threadx.h追記例

app_threadx.h追記ソースコード抜粋
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)の例です。

AzureRtosQueueプロジェクトVCP出力
AzureRtosQueueプロジェクトVCP出力

キュー イベント チェーン

Azure RTOS ThreadX 機能第 3 章の中程に、“キュー イベント チェーン”の説明があります。簡単に抜粋すると、

本受信スレッドのようにQ1とQ2の両方からメッセージを受信し、メッセージ無しの時、受信中断もある場合は、Q1/Q2に通知関数を登録(tx_queue_send_notify)し、カウントセマフォを使うキュー イベント チェーンが有効。キュー イベント チェーンなしでの実現は“非常に困難”。

流用サンプルコードのreadme.htmlにもキーワード:Event chainingがあります。しかし、このキュー イベント チェーンは未実装です。

カウントセマフォなしでは非常に困難でRTOSらしい機能ですが、各自でお試しください、ということでしょう😢。本ブログもこの方針に従いました。