Team for GR-PEACH Producer Meeting

RTOSに関しての議論

09 Feb 2015

rtosをGR-PEACH上で動作させ始めたのですが、main()にたどり着く前にハングアップするようです。
試したプログラムは下記に置いてあります。

追記(2015/2/8)
現在、一連の不具合は解決し、mbed-srcに正式に反映され安定して動作しています。
従って、このスレッドの役割はほぼ終了したことになります。
中の人の二ケ月近くに及ぶ改善努力に対して、改めて敬意を表します。
残りはスタックサイズの件で皆さんの意見を募っている話題のみです。
http://developer.mbed.org/forum/team-886-GR-PEACH_producer_meeting-community/post/27169
動かなかったプログラムが下記のように動くようになりましたので、名前を変えて再掲します。

Import programGR-PEACH_test_on_rtos_works_well

use mbed-src latest version and everything works well. RTC is also fine.

追加説明
1)プログラムは以前から作って動作確認が進んでいたプログラムで、GR-PEACHに単純に持って来ました。
その為、シンプルな形で何が問題なのかを明確にするための切り分けが上手く出来ません。
2)動作は、LPC1768、NucleoF401RE及びFRDM-K64F上で再度確認しました。
NucleoL152REに関しても動作していますが、RTX_Conf.h及びRTX_Conf_CM.hを修正しなくてはいけません。
3)当初、自作ライブラリーを疑いましたが、原因がよくわかりません(printfによるDebugの限界)。
debug_toolsは、GR-PEACH部分を作成したばかりで何も重要なところは動いていません(他のmbedもrtos上ではdebug不十分ですので使用しないでください)。
4)上記にも関係しますが、プログラムは一切のデバイス接続なしでも確認できます。
つまり、動作しないことはデバイスの反応などに関係ない(しいて言えばI2CではNAK応答のみ)可能性が強いです。
興味のある方は、mbedに何も外部接続させずに、USBケーブルだけを接続して観察していただければ、GR-PEACHと他のmbedの違いが分かっていただけると思います。

お手数ですが、ご確認願います。

14 Dec 2014

自分もRTOSの問題なのか、デバイスのコードの問題なのか、それとももっと別の原因なのか分からず悩んでいます(murataのType YDが動かない件)。

現時点では、どのI/Oも正常に動作することが全く保証されない状況ですので、Araiさんのコードをより単純化して実行してみました。
https://gist.github.com/YuuichiAkagawa/fa01300bb6947c964785

main()までに実行されると思われるものとしてはSerialとLEDのみで、それ以外のインスタンス化部分は削除しました。
これをPEACHで実行すると、DEBUG出力を見る限りstep6までは到達します。LEDは恐らく指定したとおりであろうタイミングで点滅を繰り返します。Mailは動いてない様ですが...。

もぐらたたきはイヤだYo!

15 Dec 2014

Akagawaさん
追試、ありがとうございました。

リンク先のファイルが動作すること確認しました。Mailも事前にどこかで、
show_flag = 1;
にしてあげると、仮想COMに出力されますので、動作しています。
スタックサイズは、4096バイト確保しましたが、これは2048バイトでも動作します。単純なスタックサイズの問題でないこと明らかにするため、大きく確保しました。
mbed-rtosは、現時点(2014年12月15日6:30AM JST)で、オフィシャルRevisionが54で、 GR-PEACH Producer Meeting内のCodeが53ですが、他のmbedボードを動かすにはオフィシャル版を使用しないと動きません。
今回、両方試しましたが、私のプログラムはどちらも動作していません。
mbed-rtosは、Cortex-M用のみだったのが、rtx内にCortex-A部分が追加になり、すべてAで先頭を走るGR-PEACHのために用意された模様で素人の私には解析困難です。
難しいのは、仕様通りに作られたrtos上でも私のプログラムは動かず、他のmbedボードで動くのは拡大解釈部分でたまたま動いているのではないかという点です。

Akagawaさん
後程、プライベートメールでメールアドレスをお知らせしますので、悩んでいるプログラムのリンク先などお知らせいただけませんか?
別の目線で見ると、今まで見えていないものが見えるかもしれません。
但し、今週は出張が多く反応は遅れてしまいます。

中の人へ
rtosに関しては前向き検討願います。

15 Dec 2014

Araiさん
動かしたいのは↓これです。

Import librarySNICInterface

SNIC UART Interface library: Serial to Wi-Fi library for Murata TypeYD Wi-Fi module. For more information about TypeYD: http://www.murata.co.jp/products/microwave/module/lbwb1zzydz/index.html

Serialの実装がおかしかったので、気づいたものは修正しましたが、未だ動作出来ていない状況です。
→現状はSNIC_WifiInterface.cppの78行目でエラーとなります。Serial経由で送信したコマンドに対する応答が来ない?

15 Dec 2014

Araiさん、ご報告ありがとうございます。
本件現在確認中です。

15 Dec 2014

Araiさん

置いていただいたプログラムを動かしてみました。
どうやらOSのmutexの資源数が足りないようで、OS内部でエラーとなっていました。
以下のように修正して、試していただけますでしょうか。

RTX_Conf_CA.c 197行目
#define OS_MUTEXCNT    8
↓ 
#define OS_MUTEXCNT    12


また、デバイスを接続させずに動作させたところ、
以下の処理にて引っかかっていました。

L3GD20.cpp 40行目

i2c.write(gyro_addr, dbf, 1); 
i2c.read(gyro_addr, dbf, 1);  ★

通信相手がいない場合、i2c.readを行うと、コール先から処理が返らない問題が確認されております。
ご迷惑をおかけしており、大変申し訳ございません。
現在、I2Cの処理を見直し中です。

21 Dec 2014

一週間、多忙で反応できませんでした。申し訳ありません。
本日、各ライブラリーを「update」したのち、上記の197行目のみ変更し、不具合が解消できたことを報告します
コメントのように、I2Cラインにデバイスが接続されていないとハングすることも合わせて確認できました。
I2Cのプログラム修正に期待します。
ご苦労様でした。
尚、「ご迷惑をおかけしており、大変申し訳ございません」のコメントは、今後不要と思います。
現在、正式リリースに向けて、GR-PEACHを持っている方々がプロデューサ活動を実施しているだけで、将来迷惑をかけないための事前活動です。
正式リリース後に上記のコメントが不要になるよう、もう少し頑張る必要があると思います。

21 Dec 2014

Akagawaさん
公開いただいたライブラリー、まだゆっくり拝見できていません。
大作で、素人の私には問題点にたどり着くのがやっとで、その次に進めません。
ところで、UARTの割り込みが発生することは確認できているのですか?
別のForumでSerialの改修が行われたようですが、それによる改善はないのですか?
今週から年末年始にかけては少し落ち着いて、調べる時間が取れるかもしれません。

22 Dec 2014

同様の混乱を防ぐため、OSの各資源の使用数の初期値を他のmbedとあわせました。
変更したのは下記の設定の初期値です。

  • OS_RUNPRIV
    • 0→1に変更
  • OS_TIMERSTKSZ
    • 400→WORDS_STACK_SIZEに変更
  • OS_MUTEXCNT
    • 8→12に変更

I2Cの処理については継続して見直し中です。

24 Dec 2014

Araiさん
受信処理の最後にあるQueue.get()のタイムアウト値を500ms→1000msに延ばすと動くようになりました。
詳細な原因についてはまだ調査中ですが、最初のget()でデータは取得できているのでRTOS か割り込みかのどちらかなのかなと思ってます。
https://gist.github.com/YuuichiAkagawa/0b9197414707be21be76

24 Dec 2014

Akagawaさん
先ずは、よかったですね!
ちょっと覗いただけではわかりませんが、sendUart()内でかなり長い時間(?)、リソースを占有していますが、影響してませんか?
それにしても大作ですね!楽しみにしてます。

24 Dec 2014

大変申し訳ありません。
12/22にRyo Hagimotoからコメントしました、mbed-rtosの更新に関して、
現在、mbed-rtosをupdateしても、
今回の修正が反映されない現象が確認されています。
原因を確認しております。
改善次第、ご連絡いたします。

今回の修正内容については、別の方法でご提供致します。
準備が出来次第、ご連絡致します。

25 Dec 2014

お待たせ致しました。
12/22にRyo Hagimotoからコメントしました、mbed-rtosの更新を反映したLibraryを、
暫定版として以下にアップ致しました。
http://developer.mbed.org/teams/GR-PEACH_producer_meeting/code/mbed-rtos-v60-pre/

上記URLにアクセスし、画面右側、
Repository toolboxからImport this libraryをクリックすると、mbed-rtos-v60-preを取得できます。
ご自身のprojectのmbed-rtosを、mbed-rtos-v60-preに差し替えをお願い致します。
mbed-rtos全体の差し替えがNGな方は、大変お手数ですが、下記ファイルの差し替えをお願い致します。

libraries/rtos/rtx/TARGET_CORTEX_A/

  • RTX_Conf_CA.c

    mbed-rtosのupdateに関する問題が解決するまで、
    お手数をお掛けいたしますが、よろしくお願い致します。
27 Dec 2014

上記、GR-PEACH_test_on_rtos_not_fixed_yetを、
1) mbed-srcとmbed-rtosをGR-PEACH最新版に
2) i2c_api.cppに対して修正実施
3) L3GD20とLIS3DHのRevisionをそれぞれひとつ前のものに戻し、true/false挿入
した状況で、下記のosThreadDefの優先度をすべてosPriorityNormal修正後に動作させましたが、displayのタスクが動きません。

main.c

// Thread definition
osThreadDef(update_angle, osPriorityNormal, 4096);
osThreadDef(rotor_control, osPriorityNormal, 4096);
osThreadDef(monitor, osPriorityNormal, 4096);
osThreadDef(display, osPriorityNormal, 4096);

int main(void) {
//  省略
    // Starts 1st thread
    osThreadCreate(osThread(update_angle), NULL);
    // Starts 2nd thread
    osThreadCreate(osThread(rotor_control), NULL);
    // Starts 3rd thread
    osThreadCreate(osThread(monitor), NULL);
    // Starts 4th thread
    osThreadCreate(osThread(display), NULL);
// 省略
}

そこで、タスクの生成順序を下記のようにすると、今度はmonitorタスクが起動しません。

int main(void) {
//  省略
    // Starts 4th thread
    osThreadCreate(osThread(display), NULL);
    // Starts 1st thread
    osThreadCreate(osThread(update_angle), NULL);
    // Starts 2nd thread
    osThreadCreate(osThread(rotor_control), NULL);
    // Starts 3rd thread
    osThreadCreate(osThread(monitor), NULL);
// 省略
}

何が問題なのでしょうか?

05 Jan 2015

Araiさん
お待たせ致しました。

こちらで動作確認しましたところ、
スレッド用に確保しているスタックが足りておらず、
4つ目のスレッド(displayスレッド)作成時に、OS内でエラーとなっておりました。
以下のように修正し、displayスレッドが正常に生成されることを確認しました。

rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 78行目

  1. define OS_PRIVSTKSIZE 4096
    ⇒#define OS_PRIVSTKSIZE 8192

    お手元のrtosのスタック設定を修正いただき、ご確認お願いします。

    また、各スレッドのスタックサイズに関しては、
    作成するシステムによって検討/調整する必要があると考えます。
    以下、ケース毎に調整が必要な、設定値をまとめます。

    【スレッドの生成に失敗する場合】
     osThreadCreate()戻り値 = NULLの場合、スレッドの生成に失敗しています。
     (Threadクラスを使用する場合は、_tid = NULL)
     以下の設定値を調整してください。
     
     1) スタックサイズ
      rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 78行目
         #define OS_PRIVSTKSIZE 4096
     
     2) スタックサイズ指定のスレッド数(osThreadDef()の第三引数が0以外のスレッド数)
      rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 71行目
       #define OS_PRIVCNT 8

    【スレッドの生成後、正常動作しない場合】
     スタックオーバーフローを起こしている可能性があります。
     スタックオーバーフローが起きた場合、以下の処理がコールされます。
      rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 301行目
       os_error関数

     この場合、以下の設定を調整ください。
      1) mainスレッド
     rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 64行目
      #define OS_MAINSTKSIZE 512

      2) mainスレッド以外のスレッド
      rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 78行目
         #define OS_PRIVSTKSIZE 4096
     
      3) Timerスレッド
      rtos\rtx\TARGET_CORTEX_A\RTX_Conf_CA.c 168行目
      #define OS_TIMERSTKSZ WORDS_STACK_SIZE


    その他OSのユーザ設定に関しての詳細は以下を参照ください。
    スレッドについて
     http://www.keil.com/pack/doc/cmsis_rtx/_thread_config.html

    Timerについて
     http://www.keil.com/pack/doc/cmsis_rtx/_system_config.html#UserTimer
     
    この辺りの内容については、別途、Wikiに情報を掲載する予定です。(1/14予定)
07 Jan 2015

上記を反映して、動作確認しました。
スタックを奢ったせいでタスクが起動しないとの件、上記のOS_PRIVSTKSIZE 変更と同時に各タスクのスタックサイズを再調整して動作することが確認できました。
新たな問題点が発覚したので、その内容を紹介するために、GR-PEACH_test_on_rtos_not_fixed_yetをRevision-Upしたいのですが、
http://developer.mbed.org/teams/GR-PEACH_producer_meeting/code/mbed-rtos-v60-pre/
をLibとして用いているので追加修正しているために私のプログラムを公開できません。
上記回答の記述を反映した最新版を同じ/mbed-rtos-v60-preの名前でupdateしてもらえませんか?
同じように、
http://developer.mbed.org/teams/GR-PEACH_producer_meeting/code/mbed-src-v442-pre/
も最新版にUpdate願います。

07 Jan 2015

一晩動作させたところ停止しました。
まだ幾つか問題があります。
Hamanakaさんの説明ですと、
「rtosを使用するときには、ユーザープログラムが何をするかでスタックサイズが異なるので、RTX_Conf_CA.c を変更するのは、ユーザー側の仕事である」
とも取れますが、そのような解釈でしょうか?
何度も言いますが、私の公開しているプログラムは他のmbedでは、動作しています。
特にスタックを意識して作成しなくても、1KBから多くて2KBのスタックサイズでフリーズなく動作し続けます。
またmbedの思想から考えても、Lib内に存在する意味がすぐに分からない定義をいちいちユーザーが気にしながら作らないといけないのでしょうか?
今回のスタックの件で言えば、
1) 他のmbedのスタック消費量の測定や推定(ARMさんからの情報提供など、printfなどの最大値等々)
2) RZ/A1H のスタック消費量
3) おおよその比率
から、
「一般的にM3に比較して、スタックサイズを3倍(?)くらいに設定してもらえれば、他のmbedから移植できるはずです」
と言っていただき、
「RTX_Conf_CA.cの各種定義数もそれに合わせてありますので、気にしなくてもほとんどの場合は済むはずです」
と言えないでしょうか?
それとも販売開始後に、
「GR-PEACHは、従来のmbedとは違いLib.内部に精通した方にお使いいただくよう、お願いします」
とコメントしますか?

07 Jan 2015

Araiさん、大変お待たせしました。
mbed-src-v442-preおよびmbed-rtos-v60-preをアップデート致しました。
以下をご確認のうえ、お手元のmbed-src-v442-preおよびmbed-rtos-v60-preを置き換えてご確認ください。

  • mbed-src-v442-preについて
    • I2C
        暫定対応としておりました、Yamanakaさんの修正を反映致しました。
        恒久対策については継続調査中です。

    • メモリマップ
        MBRZA1H.sctファイルを修正し、1MB以上の変数を定義できるようになりました。

  • mbed-rtos-v60-preについて
     OS_PRIVSTKSIZE の変更を反映致しました。

    また、Araiさんよりいただいたコメントに関しては、ARMさんとお話ししてみます。
    もう少し、お時間ください。
08 Jan 2015

以前から公開のプログラムをアップデートしました。
自分でも問題の切り分けが難しいので簡素化しました。
rtosは、

 #define OS_MAINSTKSIZE 2048
 #define OS_TIMERSTKSZ  2048

と修正して(上記公開プログラムは未修正)して動かしましたが、まだスタックエラーとなります。
同じプログラムは、Nucleo F401REでは一晩7時間以上、連続動作で停止しません。
スタックを倍以上にしていますが、それでも足りないのでしょうか?
何か他の原因がありませんか?
必要なら追加HWをすべてお貸ししますので調査いただけませんか?
土日のDebugでは限界です。

09 Jan 2015

がじぇるね岡宮です。

Arai様、ご不便をおかけしており申し訳ありません。 HWを送付いただき、こちらで調査いたします。送付先についてご連絡したいと思いますので、大変お手数をおかけしますが、一度下記がじぇっとるねさすのメールアドレスに簡単なメールをいただけないでしょうか。 gadget_renesas@lm.renesas.com

09 Jan 2015

もはや自分では切り分けができないので、これ以上の調査はあきらめました。RTOSに原因があるかもしれないし無いかもしれないという感じです。
これ

Import programSNIC-FluentLogger-example

Murata TypeYD - FluentLogger example.

が動くようになったと思ったものの、1時間程度で停止します。

では、一切の外部デバイスを使わない場合はどうだろうと、

Import programFluentLogger_Hello

Sample for the FluentLogger library.

を試してみたところ、こちらもしばらく動かしていると停止してしまう様です。
※やっていることはどちらも最初にTCPコネクションをサーバに張り、一定間隔でメッセージを送信だけするものです。

もちろん、LPC1768やFRDM-K64Fでは24時間以上連続動作します。
電源供給はPCのUSBからではなく、5V1Aの電源を使用していますので電力不足による動作不安定では無いと思います。

10 Jan 2015

がじぇるね岡宮さん
メールで情報をお伝えしましたので、今後の詳細は別メールで相談させてください。
世の中は三連休でしょうから、火曜日以降の対応で問題ありません。

Akagawaさん
一時間ちょっとが気になります。
申し訳ありませんが、停止までの時間測定は出来ないでしょうか?
1時間11分過ぎではないでしょうか?
もう一点、上記FluentLogger_Helloをコンパイルしようとするとlwipopts_conf.hがないとエラーが出ます。
GR-PEACH用にarchのDirectory下にファイル群が必要なのではないでしょうか?

10 Jan 2015

Araiさん、メールありがとうございました。あて先の方を送付させていただきましたので、お手数ですが着払いにて郵送をお願いいたします。

10 Jan 2015

Okamiyaさん、発送完了です。1月13日午前中に到着予定です(656円用意願います)。

10 Jan 2015

Araiさん
スミマセン。掲載したのはPEACHでは動かないものです。こちらがPEACH版です。

Import programpeach_fluentlogger

FluentLogger sample for GR-PEACH

確かに、SNIC版の方は1時間11分30秒後を最後にログが来なくなりました。1回しかテストしてないので再現性は不明です。
Ethernet版はもっと短くて、13分25秒や16分22秒で止まりました。
※いずれもサーバ側のログのタイムスタンプです

10 Jan 2015

Akagawaさん
情報提供有難うございました。
やはり1時間11分31秒問題と思われます。
32bitタイマーを使用するように変更となりましたが、上位ルーチンとのインターフェイスに何らかの齟齬があるように思えます。
不具合を中の人に認識していただき、対応を待ちましょう。

rtos特有の問題は、私のプログラムでも時間はマチマチですが、同じように20分と動作せずにすぐに結果が判ります。
Hamanakaさんが解説してくれてますが、os_error()関数がスタックで問題が起きると呼ばれます。
このルーチン中で、更にmbed_die()という恐ろしい名前の関数が呼ばれます。
私は、main.cppに下記のルーチンを追加してコンソールへのメッセージとLED点滅を入れて、ここが原因で止まっていることを確認しました。
weakで書かれているので、ユーザー側に制御が移ります。

mbed_die()

void mbed_die(void) {
    PRINTF("Error, came from os_error()!\r\n");
    gpio_t led_1; gpio_init_out(&led_1, LED1);
    gpio_t led_2; gpio_init_out(&led_2, LED2);
    gpio_t led_3; gpio_init_out(&led_3, LED3);
    gpio_t led_4; gpio_init_out(&led_4, LED4);

    while (1) {
        gpio_write(&led_1, 1);
        gpio_write(&led_2, 0);
        gpio_write(&led_3, 0);
        gpio_write(&led_4, 1);
        wait_ms(100);
        gpio_write(&led_1, 0);
        gpio_write(&led_2, 1);
        gpio_write(&led_3, 1);
        gpio_write(&led_4, 0);
        wait_ms(100);
    }
}

これが確認できても何も前には進みませんが、同じ境遇なのか調べてお互い慰め合いませんか?
いずれにしても私は、スタックがオバーフローしているとは(確信は何もありませんが)思えません。
何か他の要因があると思われます。
接続するHWはルネサスに送りましたので、何も接続していないGR-PEACHで動作させていますが、それでもこのルーチンに飛び込んできます。

10 Jan 2015

Araiさん
やってみましたが、どちらもLチカしませんでした。os_error()に行って無い様です。
SNIC版はやはり1時間11分30秒で停止しましたが...。

10 Jan 2015

そうでしたか、違う要因ですかね?
ここまで来ると、私自身は触れたくなかった割り込み制御に踏み込んでいかないといけないような気がします。
RZ/A1Hを何も知らないので、コメントは最小限にしますが、私としては下記が気になります。

RZ/A1Hグループ ユーザーズマニュアル ハードウェア編 ルネサスマイクロプロセッサ
RZファミリ/RZ/Aシリーズ Rev.1.00 2014.04
7.8.1 割り込み要因クリアのタイミング
割り込み要因フラグは、割り込み例外サービスルーチン中でクリアしてください。割り込み要因フラグを クリアしてから実際にCPU への割り込み要因が取り下げられるまでに、時間を必要とします。そのため、 クリアしたはずの割り込み要因を誤って再度受け付けないように、クリア後割り込み要因フラグをリード し、その後復帰命令を実行します。

いずれにしても、ユーザー側でかつ知識不足の私としては、中の人のもうひと踏ん張りに期待します。

11 Jan 2015

自分の1:11:30ハング問題は、us_ticker_read()の不具合によりwait_us()から返ってこないことが原因であると判明しました。
詳細はdelay_ms()のバラツキに書いておきます。
Ethernetの方はまだわかりません...

13 Jan 2015

Araiさん、機材送付の件、ご対応ありがとうございました。本日(1/13)AMで到着しました。 まずは再現確認から着手していきます。

You need to log in to post a reply