こんにちは。
タイトルの通り、「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を押すと、値は入っています。(添付画像)
アドバイスを頂けると幸いです。
よろしくお願いいたします。
明日は所用で一日おりませんので、明日以降にも再度プログラムを見直しますが、アドバイスを頂けると幸いです。
しんちょろす さん、こんにちは。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
頂いたアドバイス通り
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 var12Error message from debugger back end:value has been optimized out
2) Failed to execute MI command:-var-update 1 var12Error message from debugger back end:value has been optimized out
ということは
NORTiのクリティカルセクションの出入り関数に・・・
のご指摘の通りメモリ操作がおかしいということになるのでしょうか。
(知識不足で恥ずかしい限りですが「NORTiのクリティカルセクションの出入り関数」というのが
私の理解だとメモリにアクセスする個所か?との認識です)
ありがとうございます。
辿っていき、sci_transfer関数の最後にNORTiのおまじない関数を入れてみましたが同じ結果でした。
もう少し考えてみます。
(仰る通り、bspモジュールのFITにもグループ割り込みの記述もありましたので)
また、メモリプールやメールボックスなどのRTOSの機能を使わずに R_SCI_Send関数を実行しても暴走しています。