こんにちは。
タイトルの通り、「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を押すと、値は入っています。(添付画像)
アドバイスを頂けると幸いです。
よろしくお願いいたします。
ありがとうございます。
辿っていき、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 var12Error message from debugger back end:value has been optimized out2) Failed to execute MI command:-var-update 1 var12Error 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モジュールと割り込みコントローラー周りのマニュアル等も含めて確認してみます。
しんちょろす さん、こんにちは。NoMaYです。その後、どうでしょう?なお、RTOSでFITを使用する場合、以下の注意点があります。RX Driver Package V1.27でもケアされていなかったと思いますので、御自身でFITを改造する必要があると思うのです。e2 studio v7.5.0のFreeRTOS ProjectでVisual Expression+Renesas RX Simulator/TB-RX65Nで試せるSample Programを作ってみたjapan.renesasrulz.com/cafe_rene/f/forum21/5970/e2-studio-v7-5-0-freertos-project-visual-expression-renesas-rx-simulator-tb-rx65n-sample-program/34046#34046「RTOS未使用時は大丈夫だけれどもRTOS使用時は拙い排他制御のやり方(通常処理側と割り込み処理側の排他制御)・個別の割り込みマスクフラグを使用して割り込み一旦禁止と割り込み再度許可を行う理由・RTOSによるタスク切り替えが上記による割り込み禁止期間中に発生すると禁止期間がミリ秒オーダーになってしまう(タスク切り替えにより暫くの間は他タスクに行ってしまうから)対応・RTOS側で用意されているクリティカルセクションへの出入り関数(FreeRTOSならtaskENTER_CRITICAL()とtaskEXIT_CRITICAL()など)を使用するように手を加える」
NoMayさん
こんにちは。気にかけて下さりありがとうございます。
生産の仕事が入っており、先週からあまり触れていなかったのですが
頂いたアドバイス通り、やはりグループ割り込みの問題に帰着しそうです。
NORTi側の割込み退避・復帰関数を、r_bspのマニュアルやコードを見ながら、様々な個所に入れましたが
やはり、本質を理解できていない「トライ&エラー」では解決しておりません。
上記に頂きましたリンク先も今週末か来週の頭には熟読致します。
【進捗】
(恥ずかしながら問題個所は特定できたので)ミスポ様にも聞いてみた所、ミスポ様側からの回答としては
「FITでのグループ割込みでなく、NORTiでの割り込みをグループ割込みに対応した修正」を頂きました。
そもそも、「NORTiは割込み処理をOSに管理させる場合は、RAM上に割り込みを設定する」
「FITはROM上にベクターテーブルがあることが前提」とのことで、「相性が悪いのか?」と勝手に考えています。
ただ、FITにこだわる理由としては、以前にRTOSを使わないRX231でのプログラムでも、私レベルでもE2フラッシュや、USBマスストレージクラスが半日程度で、簡単なプログラムも作成できるほどでしたので、FITを利用したいと考えています。
また、私の知識不足で恥ずかしい限りなのですが
>RTOSでFITを使用する場合、以下の注意点があります。RX Driver Package V1.27でもケアされていなかったと思いますので、御自身でFITを改造する必要があると思うのです。
ということやリンク先の情報からも
「freeRTOSでも、同じ問題が発生する可能性が高い」ということなのでしょうか。
→RTOSでの割込みは(NORTi等のμITORNのOSに関わらず、freeRTOSを含むすべてが)RAM上に割込みを記述が前提なので、FITとの割込み処理の接続には、一定の操作が必ず必要。
世間の趨勢も考え、freeRTOSが主流になるのであれば、(NORTiが勿体ないですが)freeRTOSの導入も視野に入れております。(合間に触れるように65N Cloud kitは注文はしました)
(現在どちらのOSも知識がゼロですので、ちょうど良い機会ではあります)
しんちょろす さん、こんにちは。NoMaYです。> リンク先の情報からも 「freeRTOSでも、同じ問題が発生する可能性が高い」ということなのでしょうか。そうです。こういった落とし穴は、RTOS非対応で開発が始まったライブラリには何かしら存在する、のでは無いかと思うのです。最初からRTOS対応であるRenesas Synergyのようなものであれば存在しない、だろうとは思いますが。> →RTOSでの割込みは(NORTi等のμITORNのOSに関わらず、freeRTOSを含むすべてが)RAM上に割込みを記述が前提なので、FITとの割込み処理の接続には、一定の操作が必ず必要。私はFreeRTOSに関してトライアル中ですが、他のRTOSに関してはもっと知識不足ですけど、どこまでがそのRTOS仕様から来ているもので、どこからが素朴に実装上の事情(または単に将来的な利便性への備え)なのか、なかなか判断が付かないですね。FreeRTOSでは、割り込み記述をフラッシュメモリ上に置いて全然問題が無い、ですね。もちろん、プログラムでファームウェアを書き換える場合など、FreeRTOSの仕様/実装とは関係無しに、一時的に処理(や場合によってはベクタも)RAM上に移さないといけない(場合もある)、といったことはあります。また、FreeRTOSでは、RX(やCortexやPIC32など)の場合、既存の割り込みコードにおまじないを追加する必要は無い、ですよ。(ただ、代償として、そうしない実装よりも数十CPUクロック程度のオーバーヘッドが発生しますけれども。) そのあたりに関しては、以下のスレッドにちょっと説明(というかヒントぐらいかも)があります。RL78 FreeRTOS APIを特別なおまじない記述無しで割り込みルーチンから呼び出せるようにしてみた(CC-RL/GNURL78)japan.renesasrulz.com/cafe_rene/f/forum21/5845/rl78-freertos-api-cc-rl-gnurl78[追記]ただ、以下のスレッドのサンプルプログラムでは、ある利便性を実現するために、結局、別のおまじないを導入するように方針を変更しています。FreeRTOSのRL78のsample programを作成していこうかと思います(RL78/G13,G14の他にRL78/G23もやろうかと思います)japan.renesasrulz.com/cafe_rene/f/forum18/7083/freertos-rl78-sample-program-rl78-g13-g14-rl78-g23
毎度のことながら詳しく教えて頂きありがとうございます。
本当に勉強になります。
「H8S2368 での既存システムの更新」が目的ですので、
>数十CPUクロック程度のオーバーヘッド
は許容範囲かと考えています。(元システムがH8S2368+NROTiで、10[ms]のラウンドロビンで余裕があると聞いているので)
>FreeRTOSでは、RX(やCortexやPIC32など)の場合、既存の割り込みコードにおまじないを追加する必要は無い。
午前中にルネサス様にもダメ元で2点質問しました。
1.グループ割込みについて、r_bspで分岐している個所(レジスタ退避・復帰のNORTiのおまじない関数)の候補のヒントを貰えないか。
2.「おまじない関数」の処理はfreeRTOSでは不要か?
の「2」の回答を今NoMay様より頂けました。
【今後の方針】
FreeROTSの導入をメインに考えます。
ただ、現状のNORTiグループ割込みのバグも、頂いたアドバイスからコードを見て排他制御の構造を見直す。
(現システムがNORTi + H8S2368ですので、NORTiも使えれば嬉しいので)
来週を目途に、一度進捗を報告に参ります。
(FreeRTOSに完全に移行を決定し、NORTiは諦めたのか等も含めて)
しんちょろす さん、こんにちは。NoMaYです。> 【今後の方針】> FreeROTSの導入をメインに考えます。私が思ったのは、今回の業務案件(H8S2368+NROTi⇒RX65N+何かしらのRTOS)ではRTOSを変更するのは得策では無い、ような気がするなぁ、ということです。RTOSを変更するとなると、変更元と変更先の両方のRTOSのある程度の知識は必要になると思いますので、なかなか大変になると思うのです。(両方のRTOS(μITRON⇔非μITRON)でAPIが1対1の関係になっているのならさほど苦労無く置き換え出来ると思いますが、大抵そうなっていませんので苦労するのでは無いかと思うのです。)> 現状のNORTiグループ割込みのバグも、頂いたアドバイスからコードを見て排他制御の構造を見直す。あと、これは、NORTiバグというよりは、しんちょろすさんのスキル不足の要因が大きいような気がしますけれど、、、(さらに、何かその後に用事でもあって、その前に急いでリプライしたからかも知れませんが、グループ割り込みの話と排他制御の構造の話は全くの別物ですが、文章がごちゃまぜになっちゃっていると思うのです、、、)なお、ちょっと気になったのでウェブで検索してNORTiのUMを探して読んでみたのですが、私が予想していたような割り込みハンドラの記述ノウハウは、ちゃんと書かれていました、、、([追記] もっとも、RTOSを初めて使うような人が、これを読んで理解出来るだろうか?、と考えてみると、ちょっと無理ですよねぇ、とは思います、、、)www.mispo.co.jp/document/no4guid.pdf画面コピー(3枚)