質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.32%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

組み込み開発

組み込み開発とは、スマートフォンや家電、自動車などに組み込まれているコンピューターシステムの開発のことです。特定の用途に特化しており、限られた機能のための開発を指します。組み込み開発で作られた機器を組み込み機器と呼び、近年ではPCのオペレーションシステム(OS)にも採用されています。

Q&A

解決済

2回答

333閲覧

FreeRTOSのキューの排他制御について

Kumatter

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

組み込み開発

組み込み開発とは、スマートフォンや家電、自動車などに組み込まれているコンピューターシステムの開発のことです。特定の用途に特化しており、限られた機能のための開発を指します。組み込み開発で作られた機器を組み込み機器と呼び、近年ではPCのオペレーションシステム(OS)にも採用されています。

0グッド

0クリップ

投稿2025/02/27 04:00

実現したいこと

FreeRTOSのキュー機能を使って、イベント通知する処理を
実装したい。

このため、FreeRTOSのxQueueSend関数やxQueueReceive関数が
スレッドセーフに実行されるのかを知りたいです。

前提

ESP-IDFの環境において、BuletoothLEイベントをキューを通して
イベント処理タスクに通知しています。

これがESP32(マイコンです)では動いたのですが
ESP32-C6では、キューイングのタイミングでエラーになっています。

発生している問題・エラーメッセージ

assert failed: xQueueGenericSend queue.c:936 (pxQueue) Core 0 register dump: MEPC : 0x4080096e RA : 0x4080e374 SP : 0x4083c740 GP : 0x40815514 --- 0x4080096e: panic_abort at D:/ESP32/esptools/idf/esp-idf-v5.4/components/esp_system/panic.c:468 0x4080e374: __ubsan_include at D:/ESP32/esptools/idf/esp-idf-v5.4/components/esp_system/ubsan.c:311 TP : 0x4083c9a0 T0 : 0x37363534 T1 : 0x7271706f T2 : 0x33323130 S0/FP : 0x00000091 S1 : 0x00000001 A0 : 0x4083c77c A1 : 0x40816ae9 A2 : 0x00000001 A3 : 0x00000029 A4 : 0x00000001 A5 : 0x40821000 A6 : 0x0000000c A7 : 0x76757473 S2 : 0x00000009 S3 : 0x4083c886 S4 : 0x40816ae8 S5 : 0x00000000 S6 : 0x00000000 S7 : 0x00000000 S8 : 0x00000000 S9 : 0x00000000 S10 : 0x00000000 S11 : 0x00000000 T3 : 0x6e6d6c6b T4 : 0x6a696867 T5 : 0x66656463 T6 : 0x62613938 MSTATUS : 0x00001881 MTVEC : 0x40800001 MCAUSE : 0x00000002 MTVAL : 0x00000000``` ### 該当のソースコード ```C言語 //========================================================================== // イベントのエンキュー処理 //========================================================================== if (xQueueSend(s_evt_queue, &e_evt, 0) != pdPASS) { return ESP_FAIL; } // 正常終了 return ESP_OK;

試したこと

基本設定としてBLE4.2の機能を有効化する一方で、BLE5の機能については
無効化しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

はじめに:
私自身はFreeRTOSに関してはこれまでリアルタイムOSのひとつとして技術的に興味を覚え、基本的な部分をWEBの記事などで読んでいた程度の知見です。が、ルール無視のAI投稿が横行していて辟易しているので、一矢報いる(<言い過ぎ)程度の参考の回答としてご参照ください。本回答を読んでFreeRTOSやESP32の開発環境に知見のある方からのフォローのコメントや回答がいただければうれしく思います。

以下、本題です。


これがESP32(マイコンです)では動いたのですが
ESP32-C6では、キューイングのタイミングでエラーになっています。

以前動いていた環境でも潜在的に持っていたコードの問題が今回発現したのかもしれませんし、或いはやっぱり実行環境に依存した問題かもしれません。

このため、FreeRTOSのxQueueSend関数やxQueueReceive関数が
スレッドセーフに実行されるのかを知りたいです。

FreeRTOSにおいては公式には「スレッド(thread)」と言う用語は使わず、タスク(task)ですが、ここでいうスレッドセーフがいわゆるリエントラントであったりマルチスレッド/タスクでも同時に使用できることを意識した安全な関数であるかと言うことであれば、その通りのようです。例えばxQueueSendについてはxQueueGenericSend関数のマクロですが、FreeRTOSのカーネルのコードqueue.cで定義されているxQueueGenericSend関数のコードを眺めてみた限りそれっぽい作りになっていますね。(あくまで私が読んで・眺めて抱いた印象で、コードの一行一行を実際に動かして精査した訳ではありません)

ただ、正しく動作するかどうかはFreeRTOSのカーネルのビルド時にそのターゲットボード用に正しくコンフィグレーションされていることが条件でしょう。同じボードのファミリーであれば、多少のコンフィグレーションの違いがあってもパッと見、動いてしまうこともあるので適切なカーネルを選択して使用していることを確認する必要はあると思います。

質問者さんがお使いのESP32-C6はシングルコアなので、カーネルではそれ用のコンフィグが常にセットされている旨の記載がありますね。

FreeRTOS Overview - ESP32-C6 - ESP-IDF Programming Guide latest documentation

As ESP32-C6 is a single core SoC, the CONFIG_FREERTOS_UNICORE configuration is always set.

しかしながらその前に疑って確認するべきは以下のエラー部分だと思います。

assert failed: xQueueGenericSend queue.c:936 (pxQueue)

これはお使いのFreeRTOSのカーネルのソースコードの一部である queue.cの936行目に仕込まれたassertが出力しているもので、具体的には後に掲げるコード中のconfigASSERT( pxQueue );がそれに該当するはずで、xQueue変数がNULL(0/偽)であることを示しています。FreeRTOSの公式サイトのダウンロードページからダウンロードできるFreeRTOSのソースコードは本回答の投稿時点(2025年3月1日)で以下の3つのバージョンがありますが、

  • FreeRTOSv202210.01-LTS
  • FreeRTOSv202212.01
  • FreeRTOSv202406.01-LTS

この内、最新のFreeRTOSv202406.01-LTS」から「FreeRTOS/FreeRTOS-Kernel/queue.c」からxQueueGenericSend関数を一部引用、コメントを追記させてもらい、以下に掲げます。

C

1/* FreeRTOSv202406.01-LTS/FreeRTOS/FreeRTOS-Kernel/queue.c 939行目から引用、抜粋 */ 2 3BaseType_t xQueueGenericSend( QueueHandle_t xQueue, 4 const void * const pvItemToQueue, 5 TickType_t xTicksToWait, 6 const BaseType_t xCopyPosition ) 7{ 8 BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; 9 TimeOut_t xTimeOut; 10 Queue_t * const pxQueue = xQueue; 11 12 configASSERT( pxQueue ); /* <<<<これ */ 13...

このQueueHandle_txQueue変数は使用に先だってxQueueCreate関数で生成したハンドルの値を使うはずで、xQueueCreateの呼び出しが失敗していたり、あるいは呼び出しのタイミングが誤っていて、NULLのままなのではないでしょうか。まずその辺りから確認し、問題があれば解決しましょう。

xQueueCreate - FreeRTOS>Kernel>Queues

Returns:

If the queue is created successfully then a handle to the created queue is returned. If the memory required to create the queue could not be allocated then NULL is returned.

尚、上記で述べたソースコードでは質問者さんが提示されたエラー内容のassertで報告されている行番号とは異なっていて、これは過去の違うバージョンのカーネルだったり、更にカスタマイズされたカーネルである可能性があることを示唆していますので注意してください。

投稿2025/03/01 02:14

dodox86

総合スコア9349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kumatter

2025/03/13 17:46

回答ありがとうございます。 メッセージがキューハンドラ引数のNullPointerでエラーになっている旨でしたので 調べたところ イベント処理用のタスクを起動する直前のタイミングで、キューを生成しておりました。 その一方で、BluetoothLEの初期処理はその前に終了しており イベント処理タスクが始まる前の短時間に、アドバタイズ処理が完了していまっていたので キューが存在していない状態で実行されているとの問題でした。 ESP32で動いていた処理なので油断していましたが、ハードが変わったので 処理順序に差が出ていたようです。 非常に参考になりました。 ありがとうございます。
guest

0

FreeRTOSのxQueueSend関数とxQueueReceive関数はスレッドセーフですが、ESP32-C6で問題が発生しています。キューが正しく初期化されているか、メモリ割り当てが十分か、割り込みハンドラ内でISRバージョンの関数を使用しているか確認してください。assertエラーの行を確認し、ESP32-C6のドキュメントやフォーラムで互換性の問題を調べてください。他に質問があれば教えてください。

投稿2025/02/27 05:11

Erika383Rivera

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kumatter

2025/02/27 11:40

>割り込みハンドラ内でISRバージョンの関数を使用しているか確認してください。 これは考慮していませんでした。 BluetoothLEのGAPプロファイルやGATTプロファイルのコールバック関数は 他のタスクによる実行と言う扱いなのか? それともハードウェア割込みによるISR処理として実行される扱いなのか? どちらなのでしょうか?
dodox86

2025/02/28 06:22

@質問者 Kumatterさん この回答は、あくまで推測(個人的にはほぼ確信)ですが、最近頻出しているAI回答と思われます。常に間違っているではないので厄介ですが、レスは期待できませんね。 @Responder You have to indicate your post is AI generated. [https://teratail.com/help#about-ai-terms] > AIが生成した回答・コメントについて > > AIが生成した回答・コメントを投稿する場合は、1行目に「[アルゴリズム/サービス名]により生成された文章です」と明記する必要があります。明記されていない場合は運営チームで削除させていただく場合がございます。
Kumatter

2025/02/28 12:07

回答ありがとうございます。 AIの回答なのですか 同じ質問に対して、GeminiとCoPilotで回答が違っていたので 困っていたのですが、ここでも同様の事が起きるのですね 参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.32%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問