はじめまして。Tanigawaと申します。
RX65N envision kitを用いて、RenesasのGithubにある「GLCDC RW2D emWin(Segger GUIミドルウェア)」を参考に、RTOSでGUIアプリケーションを作成しようとしています。
emWinのイベント処理(スイッチのオンオフなど)からシリアルに送信キューを送りたいとき、どう書いてよいかわかりません。
以下のようにApplication.cに記述すると動作はするのですが、いかにもまずい書き方な気がして自信がありません。
emWinの処理ととRTOSのタスクの兼ね合いがわからないので、良い方法を教えていただきたいです。
#include "Application.h"
char string[32];
extern QueueHandle_t queue_handle_1;
void process_switch_on(WM_HWIN hDisplayedText)
{
TEXT_SetText(hDisplayedText, "ON");
TEXT_SetBkColor(hDisplayedText, GUI_WHITE);
TEXT_SetTextColor(hDisplayedText, GUI_BLUE);
led_on();
sprintf(string, "ON\r");
xQueueSend(queue_handle_1, string, portMAX_DELAY);
}
シリアル通信のほうは「queueの活用 printデバッグのシリアライズ」を参考に、キューによるシリアル送信タスクを実装しています。
よろしくお願いします。
tanigawaさん、こんにちは。NoMaYと申します。RTOSのAPIの具体的な使用方法に詳しいわけではないのですけれども、そのあたりは追々調べてみますけれども、まずはBing先生に聞いてみました。以下、Microsoft BingのAI回答の取り掛かりの画面コピーです。[追記]Bing先生の回答の出だしはルネサスさんのウェブページと同じですね。以下、ルネサスさんのウェブページの画面コピーです。www.renesas.com/jp/ja/products/gadget-renesas/reference/gr-rose/rtos-queue
NoMaYさん、こんにちは。tanigawaです。
返信ありがとうございます。
現状、FreeRTOSでのキューによるシリアル送信の方法自体はわかっているのですが、通常はタスク関数内でキューに送信するところを、emWinのルーチン内で行うことに疑問を感じています。
「RX72N Envision kit を用いた 音声認識・発話および LCD 表示ソリューション」のアプリケーションノートを読んだところ(残念ながらソースは提供されていないようです)、emWinのメインルーチンをRTOSのタスクで実装しているみたいです。
具体的な方法はまだよくわかっていませんが、その方針でやってみようと考えています。
tanigawaさん、こんにちは。NoMaYです。> 現状、FreeRTOSでのキューによるシリアル送信の方法自体はわかっているのですが、通常はタスク関数内でキューに送信するところを、emWinのルーチン内で行うことに疑問を感じています。そういうことだったのですね。こういうことでは無かったのですね。私は大昔にWindowsアプリケーションを作っていたこともちょっとだけありましたけれども、ボタンのいわゆるメッセージハンドラ関数内でデバッグメッセージをデバッグコンソールに表示させることには抵抗は無かったです。(大昔のことなので、過去の記憶を勝手に思い込んでいるだけだったりする可能性もありすけれども。) (もちろん、Windowsアプリケーションはノンリアルタイムアプリケーションです。)私が思った今の方法の問題点:sprintf()で動的に生成した文字列を格納した素朴なただひとつのバッファのアドレスをQUEUEに入れているので、QUEUEからの読み出しが間に合わなくなると、その素朴なひとつのバッファに新しくsprintf()で動的に生成した文字列が格納されてしまうけれども、そうなってから、その前の文字列をQUEUEから読み出そうてしても、既に新しい文字列に書き変わってしまっている
NoMaYさん、こんにちは。
そうですね。試しに一秒ごとに固定文字列をQUEUEに送信するタスクを加え、画面上のスイッチをトグルすると「ON」「OFF」とQUEUEに送信するプログラムをかいてみたところ、高確率でフリーズしてしまいます。
やはりRTOSの処理はタスクの管理内で行わないと不具合が生じるようです。
QUEUE内の文字列の上書きについては、renesas githubの
queueの活用 printデバッグのシリアライズ
にて複数タスクによるシリアル送信の動作を確認しているので、今のところ問題はないと考えています。
tanigawaさん、こんにちは。NoMaYです。> 「RX72N Envision kit を用いた 音声認識・発話および LCD 表示ソリューション」のアプリケーションノートを読んだところ(残念ながらソースは提供されていないようです)、emWinのメインルーチンをRTOSのタスクで実装しているみたいです。ということは、以下で検索するような案件のようですね。Qiitaには充分な情報が無いみたいでしたので、Segger社のウェブサイトもしくはエンビテックさんのウェブサイトで探すことになりそうな気がします。Google検索: emWin タスク site:qiita.comwww.google.com/search?q=emWin+タスク+site:qiita.comエンビテックさんのウェブサイトのURLに関しては以前に以下のスレッドで探しがことがあります。RX65N/RX72N emWin+AppWizardでJapanese Language Displayが出来るか調べてみることにしました(Is it available?)community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/8320/rx65n-rx72n-emwin-appwizard-japanese-language-display-is-it-available
tanigawaさん、こんにちは。NoMaYです。> 試しに一秒ごとに固定文字列をQUEUEに送信するタスクを加え、画面上のスイッチをトグルすると「ON」「OFF」とQUEUEに送信するプログラムをかいてみたところ、高確率でフリーズしてしまいます。やはりRTOSの処理はタスクの管理内で行わないと不具合が生じるようです。 以下の記事自体はスーパーループ向けですけれども、tanigawaさんは既にFreeRTOSとくっつけられていますけれども、以下のMainTask()をどこに記載されましたか?1 GLCDC DRW2D emWin(Segger GUIミドルウェア)github.com/renesas/rx72n-envision-kit/wiki/1-GLCDC-DRW2D-emWin(Segger-GUIミドルウェア)・rx72n_envision_kit.cのソースコード全体を以下に記載する(説明は後述)
#include "GUI.h"void main(void);void main (void){ /* The follow function is generated by the AppWizard. */ MainTask();}
NoMayさん、こんにちは。tanigawaです。
プロジェクトのメインファイル(プロジェクト名.c)に記述していました。
新たにタスクを作成して、そのタスク内に上記のMainTask()を記述すればよいということですね?
たしかにそれで解決しそうです。
ありがとうございます。
tanigawaさん、こんにちは。NoMaYです。> プロジェクトのメインファイル(プロジェクト名.c)に記述していました。後で自分でソースを確認してみようとは思いますけれども、これは、FreeRTOSプロジェクトでRXスマートコンフィグレータが生成したソースのmain_task()から呼び出されているmain()でしょうかね。(Amazon FreeRTOSプロジェクトの場合だったかも。)> 新たにタスクを作成して、そのタスク内に上記のMainTask()を記述すればよいということですね?いえ、上の場合だったりしますと、実質的に既にもうタスクのひとつであるmain_task()から呼ばれていることになるのです。そして、気になることは、RTOSですので、タスクの優先度はどうすれば良いのか、MainTask()は何をトリガとして実行状態に移行するのか、逆に、どういう状態だと待機状態に移行するのか、また、そういったことをコンフィグレーションする関数があったりしないか、とか気になるのです。
main_task()は画像の通り、FreeRTOSプロジェクトでスマートコンフィグレータが生成したソースで、その中にMainTask()を記述しています。
また、画面のスイッチをトグルしたときの動作は以下の画像の通りapplication.cに記述しています。
たしかに、新たにタスクを生成して(emWinの)MainTaskを記述するのは優先順位などがわからないですし、そもそもFreeRTOSプロジェクトで自動生成されたmain_task()で処理している分には問題なさそうですね。
問題は、applicarion.cのイベント処理でQUEUE送信を行うと動作がフリーズすることなのですが、おそらくmain_task()内の処理で呼ばれている(つまり実質タスク関数内)ので、application.cに記述しても大丈夫な気もするのですが...
tanigawaさん、こんにちは。NoMaYです。実はきちんと分かっていないのですけれども、以下のオンラインドキュメントを見てみようと思います。(見ている最中です。)www.segger.com/doc/UM03001_emWin.html#Execution_Model_Single_Task_Multitask「Execution Model: Single Task / MultitaskemWin has been designed from the beginning to be compatible with different types of environments. It works in single task and in multitask applications, with a proprietary operating system or with any commercial RTOS such as embOS or uC/OS.」