FITでのSCI使用時に、PCから文字を1文字受信すると、プログラムが固まります。

こんにちは。

タイトルの通り、「FITを利用したSCIのプログラム」について、皆様のアドバイスを頂けると幸いです。

【発生している問題】

テラタームを用いて、PCよりシリアル通信を行うプログラムの試験中です。(エコーバック)

PCより一文字受信すると、CPUが固まります。

一度固まると(デバッグモードで)再開を押しても固まったままです。

一度終了(デバッガと切断)し、再度デバッグを開始するとCPUは動きます。

【不具合詳細】

CPUが固まった時は、添付画像の用にe2studio上に

"0x446の_$s_bsp_swint_nested_int_status()"に対して使用できるリソースがありません。

と表示されます。

その時の逆アセンブルを表示すると、

0000446:dbt

という命令が表示されています。

何を以て「CPUが固まった」と判断してるかと言うと、RTOSの周期ハンドラでLEDを点滅させています。

これが消えたままになったり、ついたままになっているからです。

(SCIを受信しなけれなば点滅を繰り返しています。)

【環境】

e2studioにて、FITを用いてのプログラム作成中です。

CPUはRX65Nです。

また、μITORN仕様のOS「NORTi」を使用しています。

(NORTiのメーカーの)ミスポ様より、RX231用でのFITを用いたサンプルは頂いていますので参考にしています。

【考察】

FITのマニュアル等も確認し、FITのヘッダファイルでのチャンネル指定や

R_SCI_Open関数コール前後のピンの設定の記述等も確認したつもりです。

が、なぜかr_sci_rx65n.c内の割込み関数の引数に対して、エディター上でエラーが出ます。

しかし、ビルドは通ります。ここが怪しいかとは思うのですが、思いつく限りの確認はしたのですが

症状は改善されません。

具体的に言うと、(SCIの割込み関数4つ全てなのですが1つの例として)

void sci2_eri2_isr(void *cb_args)
{
ient_int();
eri_handler(&ch2_ctrl);
iret_int();
}

※ient_int()とiret_int()というのはRTOSとFITを接続するための関数ですので、今回は関係ないかとは思います。

のch2_ctrlに対して「シンボルが解決できません」と赤波下線がエディタ上で表示されています。

しかし、デバッグ状態にしてカーソルを持ってい行きF2を押すと、値は入っています。(添付画像)

アドバイスを頂けると幸いです。

よろしくお願いいたします。

r_sci_rx65ndata.c内に、ch_ctrlが定義されており、e2stduioでもホワイトアウト?されていないので、しっかりと参照されています。
(コードが向こうであれば、エディタ上で背景が塗潰された状態ではないということです)
  • 明日は所用で一日おりませんので、明日以降にも再度プログラムを見直しますが、アドバイスを頂けると幸いです。

  • しんちょろす さん、こんにちは。NoMaYです。

    たぶん、しんちょろすさんの頭の中では、ツールがバグっている筈が無い、という観念があるかと思うのですが、そういう人とe2 studioは相性が悪い、ということの実際の事例になっているような気がするのです。どうしても私は思ってしまうのですが、そういう人はCS+を使った方が良い、と思うのです。当然、初学者さんは皆そういう観念を持っているのでは?という話になるかと思うのですが、ですので、私は初学者さんはCS+を使った方が良い、と思っているのです。(もちろんCS+にバグが全く無いとは言いませんけれど。)

    それはそれとして、現象に関してですが、まずタイトルが良くないですよね、、、送信というのはPC視点ですよね、、、文面を追っていってすぐ気付いたのですが、マイコン側での受信時のトラブルの話、でしたね、、、

    そして、これはまず第一に、マイコン側での受信割り込みで何か起きているのでは?というのが、たぶん、多くの人の最初の考えだと思います。きっと、受信割り込みは発生しているに違いない、と。(ですので、その場合、もうピン設定を確認するなどしても、無意味(といっていいぐらい)かなぁ、とも思うのですけど。)

    次にすることは、FITの受信割り込み処理は多くの人が使っていますので単純素朴なバグは無いと思いますので、受信割り込みコールバックのソースを再確認することですね。

    そうして、問題が見付からなければ、その次はデバッグですね。まずは、以下の2点の確認かと思います。(もし、コールバック内でNORTiのシステムコールを行っていたら、一時的にコメントアウトしてみるのも手かと思います。)

    (1) ちゃんとRETI命令まで辿り着いているか(FITのソースを追いかけて割り込み処理の最後にブレークポイントを設定して、ブレークポイントで止まるか)どうかですね。(もちろん、割り込み処理の最初にもブレークポイントを設定して、ブレークポイントで止まるかどうかは、念のため、確認しておきます。)

    (2) ちゃんとRETI命令まで辿り着いたら、RETI命令を命令単位ステップ実行して、ちゃんとメイン処理に(つまり割り込み発生箇所(と思しきところ)に)戻るかどうかですね。[追記] すみません、念のため、NORTiのおまじない関数の ient_int() と iret_int() も、NORTiのシステムコールともども、コメントアウトしてみて下さい。

    相談されている文面から推測すると、どちらかで期待した動作にならないのではないか、という予感がするのです。

    あと、ちょっと確認なのですが、RX231のNORTi+FITのサンプルプログラムをミスポ様より頂いている、とのことですが、それは、FITでのSCI使用時の受信割り込み処理も含まれているものですか?もし含まれているのなら、それを試しにTB-RX231などで動かしてみると、動作してくれないRX65Nの現象との比較確認対象に出来るかも?と思ったのです。

  • >NoMaYさん

    アドバイスありがとうございます。

    受信と送信のご指摘ありがとうございます。変更しました。

    読みづらい文章を追って下さりありがとうございます。

    お礼が遅くなり申し訳ございません。(息子の小学校の入学式で昨日は休んでおりました)

    まずは、アドバイス通り割込み処理関連を当たります。

    ミスポ様からのサンプルは、「CS+でFITを用いたSCIのコールバック」でした。

    したがって、その構造を参考にしています。(ただ、フォルダ構成がFITを手動で導入されたのか、srcフォルダが無い構成です。この差分は今回の件ではあまり関係がないようですが)

    北斗電子のRX231のボードはありますので、その利用も視野に入れます。(ミスポ様のサンプルはルネサスの評価キット用でした。)

    CS+の件ですが、私が情報交換ができる人間が近くにいないので、全て推測でe2studioに移行しました。

    FITのマニュアルや、(セミナー案内メールのタイトル記載レベルの確認ですが)「RXでe2studioを使ってGUI云々」とあったので「cs+よりもe2の方が優遇されているのでは?」と思い、「はじめてのe2studio」のセミナーも受講した次第です。ただ、最終目的が「動くプログラムを作る」なので、再度IDEに関しては検討します。

    イクリプスベースのIDEが流行しているようですので、それならば「e2studioの方がいいのでは?」等の軽い気持ちもございます。

    今週中は頂いているアドバイスを基に割込み処理を追ってみます。

  • アドバイス通り順次追っていきますと、受信は出来ており、送信完了割り込みでハングアップすることが分かりました。

    かなり原因が絞れたので、追及していきます。

    結果は報告に参ります。

    (freeRTOSではなく、μITORN系なので需要があるかは不明ですが)

  • しんちょろす さん、こんにちは。NoMaYです。

    マイコンからのエコーバックの送信動作時に送信完了割り込みで問題が発生していましたか。そうなると、実は、RX231とRX65Nでマイコンの動作が微妙に異なり、FITの割り込み処理の流れも微妙に異なっていて、気になる点があるのです。

    (A) RX231ではFITはSCIモジュールで直接送信完了割り込みを受けている(送信完了割り込みハンドラはRETIで戻る割り込み関数)

    (B) RX65NではFITはBSPモジュールでグループ割り込みの1要因としてとして送信完了割り込みを受けて、そこから普通の関数呼び出しでSCIモジュールの送信完了割り込みハンドラを呼び出している(送信完了割り込みハンドラはRETで戻る通常関数)

    そのことにより、NORTiのおまじない関数の ient_int() と iret_int() を入れる場所がRX231とRX65Nで違っていなければいけないのではないかなぁ、という予感がするのです。

  • NoMaYさん

    エスパーかと思うほどのアドバイスのピンポイントぶりに

    >相談されている文面から推測すると、どちらかで期待した動作にならないのではないか、という予感がするのです。

    > RX65NではFITはBSPモジュールでグループ割り込みの1要因としてとして送信完了割り込みを受けて・・・

    に本当に感謝しかありません。

    大変厚かましいお願いではございますが、引き続きアドバイスを頂けると幸いです。

    午前中に何か怪しい箇所を探しておりました。

    仰る通り、r_sci_rx_config.h内にも

    #define SCI_CFG_ERI_TEI_PRIORITY (6)     /* (RX64M/RX71M/RX65N/RX72M/RX72N/RX66N ONLY) 1 lowest, 15 highest */

    と言う記述があました。

    また、

    >BSPモジュールでグループ割り込みの1要因としてとして・・・

    とのご指摘の通り、以下の作業までしか追えていませんが、最終的にr_bspのr_bsp_software_interrupt.c内に辿り着きました。(最初の質問に添付している画像の)

    0x446の_$s_bsp_swint_nested_int_status()"に対して使用できるリソースがありません。

    と言う関数もここにありました。

    【以下行った作業】

    ①r_sci_rx65n.c内の996行目からの送信割り込み関数 txi_handlerにブレークポイントを設定

    R_BSP_ATTRIB_STATIC_INTERRUPT void sci2_txi2_isr(void)
    {
        ient_int();    //NORTiおまじない
        txi_handler(&ch2_ctrl);
        iret_int();    //NORTiおまじない
    }

    ②PCのテラタームより受信を行う。上述のブレークポイントにて停止するので、ステップインで順次実行していく。

    ③byte_qのSCIに依存するFITの関数を進みながら、プログラムは進んで行く

    ④無事 NORTiおまじない関数の下段側「iret_int()」まで到着する

    ⑤送信タスク内の

    for (;;) {
        err = R_SCI_Send(Console, (uint8_t *)msg->buf, strlen((char *)msg->buf));
        if (err == SCI_SUCCESS)
            break;
        if (err != SCI_ERR_INSUFFICIENT_SPACE && err != SCI_ERR_XCVR_BUSY)
            break;
        dly_tsk(1);
    }

    if (err == SCI_SUCCESS)側を通り、その下の行

    rel_mpf(ID_ComMpf, msg);

    で、r_bspの関数に飛ぶ。

    具体的にはr_bsp_interrupt.c内の

    R_BSP_ATTRIB_INTERRUPT void undefined_interrupt_source_isr(void)
    {
    /* If user has registered a callback for this exception then call it. */
        R_BSP_InterruptControl(BSP_INT_SRC_UNDEFINED_INTERRUPT, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    }

    ⑥その後ステップイン実行を繰り返すと、以下の同じ個所を回る

    r_cg_hardware_setup.c内のvoid r_undefined_exception(void)

    と⑤のR_BSP_ATTRIB_INTERRUPT void undefined_interrupt_source_isr(void)

    です。

    【愚見】

    rel_mpf(ID_ComMpf, msg);というNORTi(μITORN)関数でハングアップするので、メモリ操作を誤ったかと思いましたが、タスク数も少なく、余裕を以てメモリを確保しています。

    +セクションの分割はミスポ様のRX321+FITと同様に変更済み。

    上述のステップインの実行中に通る関数は

    undefined_interrupt_source_isr

    等の名称があるので、NoMaY様のアドバイス通り、NORTiのおまじない関数の入れる個所が違うのでは?

    を参考にしようと思うのですが、何を当たっていけばいいかの助言を頂けると幸いです。

    FITのbspモジュールとマニュアルと、RX65Nの割込みコントローラーは再度見直します。

    よろしくお願いいたします。

  • しんちょろす さん、こんにちは。NoMaYです。

    以下のr_bspの関数に飛んだということは、もうプログラムが暴走しているのですよ。まず、ひとつの仮説ですけど(かつrel_mpf()のソースを見ていない時点では荒っぽいやり方ですが)、rel_mpf(ID_ComMpf, msg);の前で割り込み禁止にして実行後に割り込み許可に戻す、というコードを追加して、rel_mpf()をステップオーバー実行するとどうなりますでしょうか?rel_mpf()のソースを見ていない時点での荒っぽい予想ですが、ちゃんと戻ってくるのではないかなぁ、と思うのです。(ただ、rel_mpf()内で、常に割り込み許可にする、という処理が入っている可能性もありますが、、、その場合は、NORTiのクリティカルセクションの出入り関数(すみません、名前は分からないです)でrel_mpf(ID_ComMpf, msg);をサンドイッチして、試してみてください、、、)

    結局、どういうことかというと、たまたま何かの割り込み処理がrel_mpf(ID_ComMpf, msg);実行中に発生し、その割り込みが暴走して、くだんのr_bspの関数に飛んだのではないだろうか、という可能性について実験したいのです。

    > if (err == SCI_SUCCESS)側を通り、その下の行
    > rel_mpf(ID_ComMpf, msg);
    > で、r_bspの関数に飛ぶ。
    > 具体的にはr_bsp_interrupt.c内の
    > R_BSP_ATTRIB_INTERRUPT void undefined_interrupt_source_isr(void)
    > {
    > /* If user has registered a callback for this exception then call it. */
    >     R_BSP_InterruptControl(BSP_INT_SRC_UNDEFINED_INTERRUPT, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
    > }

  • しんちょろす さん、こんにちは。NoMaYです。

    > NORTiのおまじない関数の入れる個所が違うのでは?
    > を参考にしようと思うのですが、何を当たっていけばいいかの助言を頂けると幸いです。

    これは、SCIモジュールの送信完了割り込みハンドラの出口にブレークポイントを設定して、Goすれば、いずれそのブレークポイントで止まりますので(筈ですので)、そこからステップ実行を繰り返していけば、どんどん親の関数に戻って行けますよ。

  • しんちょろす さん、こんにちは。NoMaYです。

    あと、このような暴走した場合のデバッグ手法として、デバッガのトレース機能を使う、という手もあります。

    関連リンク

    【CS+】リセット時に再起動させたくない
    japan.renesasrulz.com/cafe_rene/f/forum21/7053/cs/37745#37745
     

  • NoMaYさん

    頂いたアドバイス通り

    clrpsw_i();
    rel_mpf(ID_ComMpf, msg);
    setpsw_i();

    と割り込みを制限してみましたが、同じ結果(R_BSP_InterruptControl)に飛びました。

    が、割込み禁止をする前と比較し挙動が変わりました。

    【挙動が変わった場所】

    ① 送信タスク内の

     err = R_SCI_Send(Console, (uint8_t *)msg->buf, strlen((char *)msg->buf));より前にある

    rcv_mbx(ID_ComMbx + ch, &msg);に一度処理が移ってから暴走

    ②rel_mpf実行時に、デバッガに以下のメッセージが表示されました。

    msgの値がエラーの用です。

    msgはリスト型のバッファです。

    typedef struct t_commsg { /* message packet for communication */
        struct t_commsg *next; /* reserved for OS space */
        B buf[BUFSZ];
    } T_COMMSG;

    /*デバッガのメッセージ*/

    複数のエラーが報告されました。

    1) Failed to execute MI command:
    -var-update 1 var12
    Error message from debugger back end:
    value has been optimized out

    2) Failed to execute MI command:
    -var-update 1 var12
    Error message from debugger back end:
    value has been optimized out

    ということは

    NORTiのクリティカルセクションの出入り関数に・・・

    のご指摘の通りメモリ操作がおかしいということになるのでしょうか。

    (知識不足で恥ずかしい限りですが「NORTiのクリティカルセクションの出入り関数」というのが

    私の理解だとメモリにアクセスする個所か?との認識です

  • ありがとうございます。

    辿っていき、sci_transfer関数の最後にNORTiのおまじない関数を入れてみましたが同じ結果でした。

    もう少し考えてみます。

    (仰る通り、bspモジュールのFITにもグループ割り込みの記述もありましたので)

  • また、メモリプールやメールボックスなどのRTOSの機能を使わずに R_SCI_Send関数を実行しても暴走しています。

  • しんちょろす さん、こんにちは。NoMaYです。

    すみません、私も不注意だったのですが、送信割り込みと送信完了割り込みとを使い分けていた訳では無かったのですね。BSPモジュールで一旦受けているのは、送信割り込みの方ではなくて、送信完了割り込みの方だった、のです。

    それで、送信完了割り込み(および送信割り込み)の確認方法も、受信割り込みの場合と同様です。

    (1) ちゃんとRETI命令まで辿り着いているか

    (2) ちゃんとRETI命令まで辿り着いたら、RETI命令を命令単位ステップ実行して、ちゃんとメイン処理に(つまり割り込み発生箇所(と思しきところ)に)戻るかどうか

    まずは、この2つが意図通り動くかどうかがデバッグ作業の節目かと思います。

    あと、rel_mpf(ID_ComMpf, msg);内で暴走する件(私の予想は、たまたま、rel_mpf()実行中に割り込みが発生し、その割り込みの最中もしくはRETI後に暴走したのでは?というものですが)は、以下のやり方でも目星を付けることが出来るかも知れないという考えが思い浮かびました。以下のように時間稼ぎのループを挿入してやれば、割り込み発生タイミングをループ内にすることが出来るので、これでループ中に暴走するならrel_mpf()はもう気にせずデバッグすれば良いと思うのです。

    for(i = 0; i < 大きな数値; i++)
    {
        /* このループ中に割り込みが発生するように大きな数値の値を調整する */
        nop();
    }
    rel_mpf(ID_ComMpf, msg);


    また、以下については、ごめんなさい、余りにソースが断片的過ぎて、なんのことやらわからないです、、、(ただ、②はe2 studionのウォッチウィンドウで良く見掛けるエラー表示である、というのは分かりますが。)

    【挙動が変わった場所】

    ① 送信タスク内の

     err = R_SCI_Send(Console, (uint8_t *)msg->buf, strlen((char *)msg->buf));より前にある

    rcv_mbx(ID_ComMbx + ch, &msg);に一度処理が移ってから暴走

    ②rel_mpf実行時に、デバッガに以下のメッセージが表示されました。

    msgの値がエラーの用です。

    msgはリスト型のバッファです。

    typedef struct t_commsg { /* message packet for communication */
        struct t_commsg *next; /* reserved for OS space */
        B buf[BUFSZ];
    } T_COMMSG;

    /*デバッガのメッセージ*/

    複数のエラーが報告されました。

    1) Failed to execute MI command:
    -var-update 1 var12
    Error message from debugger back end:
    value has been optimized out

    2) Failed to execute MI command:
    -var-update 1 var12
    Error message from debugger back end:
    value has been optimized out

  • NoMayさん おはようございます。

    お付き合いいただき本当にありがとうございます。

    頭をクールダウンさせ、整理をしました。

    結論から言うと、やはりTEI(送信完了割り込み)が悪さをしているようです。

    私が、途中で用語の勘違いをしていました。

    TXI:送信割り込み

    TEI:送信完了割り込み (RX65Nでグループ割り込みの対象の方)

    という認識であっていますでしょうか。

    FITのマニュアルや、ルネサスセミナー(通信編)での呼称が全て違うのです。

    TXIが「送信”終了”割り込み」と記述されていたり、TEIが「送信バッファエンプティ割り込み」と記述されていたりです。

    見苦しい言い訳ですが、言葉の定義をしっかりとエバーノートに再記載しました。

    その上で、以下の確認を行ったので「TEIが悪さをしているのではいか」との結論に至りました。

    【行った確認】

    ①TEI割り込み記述中の、NORTiおまじない関数をコメント化

    送信は出来ませんでしたが、プログラムは暴走しませんでした。(受信するとLEDの点滅が一定時間止まるプログラムには影響なし)

    ②単純にR_SCI_Send関数のみを試す

    単純に「1文字送信」をすると、暴走しました。

    ※ここでの「暴走」とは昨日と同じR_BSP_ATTRIB_INTERRUPT void undefined_interrupt_source_isr(void)に飛ぶという意味です。

    もう一度BSPモジュールと割り込みコントローラー周りのマニュアル等も含めて確認してみます。