Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

RZ/T1で例外処理が発生し悩んでいます。

RZ/T1で例外処理が発生し悩んでいます。

発生のタイミングはランダム。
発生頻度は1日1回程度でなかなか現象を捉えることができません。

デバッガで確認したところ

 1、アボート例外が発生。
 2、プリフェッチ例外が発生
 3、OSのタイマアクセスのための汎用レジスタ(r6)が書き換わり、永久ループの動作となる。

これら3種のうちの何れかの状態になっていることを確認しました。

デバッガのログを追うと、
OSがSWI_Handlerを呼び出し前に汎用レジスタr0に値をロードし、処理完了後、r0のメモリ値にBX命令で分岐する動作なのですが、r0が値が壊れてしまいます。

 

(正常時)

180E0のメモリ値(17F68)をr0にロード。

x3_xefd_qrx:
       IE/A 00017F5C LDR r0,180E0 ;=17F68 _x3_xefd_qrx
       IE/A 00017F60 SVC 0
  7125 507m027.55 [Bra.adr.] PC=00000008(A) AltISA=0 Exc.=SWI Sec.=S
  7126 507m027.55
rzt1.s79: 68: b SWI_Handler
       IE/A 00000008 B 0FF20 SWI_Handler

~中略~

rzt1.s79: 198: bx r0
      IE/A 0000FF4C BX r0
  7131 507m027.68
_x3_xefd_qrx:
      IE/A 00017F68 LDMIA sp!,{r0-r1}

bx r0命令で17F68に分岐。

 

(異常時)

180E0のメモリ値(17F68)をr0にロード。

x3_xefd_qrx:
      IE/A 00017F5C LDR r0,180E0 ;=17F68 _x3_xefd_qrx
      IE/A 00017F60 SVC 0
  40817 508m027.55 [Bra.adr.] PC=00000008(A) AltISA=0 Exc.=SWI Sec.=S
  40818 508m027.58
rzt1.s79: 68: b SWI_Handler
      IE/A 00000008 B 0FF20 SWI_Handler

~中略~

rzt1.s79: 198: bx r0
      IE/A 0000FF4C BX r0
  40823 508m028.48
__RESET:
rzt1.s79: 66: b Reset_Handler
      IE/A 00000000 B 0FE58 Reset_Handler

本来はbx r0命令で17F68に分岐するところ、なぜか0(Reset_Handler)に分岐。
r0の内容が書き換わってしまっている。
デバッガで見る限り、途中でr0にはアクセスしていません。

このときのはr0が0に書き換わっていますが、変化する数値はランダムなようです。
また、r0以外も書き換わってしまうことがあるようです。

参照先のメモリ値が破損していないか、誤動作後にメモリをダンプして調べたところ正常でした。

OSメーカには問い合わせましたが原因はわかりませんでした。

似たよう現象をご存知であれば教えていただけると助かります。


 CPU
  RZ/T1 ルネサス 型式:R7S91006CBG
 開発環境
  IAR Embedded Workbench 

 

  • まついさん、こんにちは。NoMaYと申します。

    RZ/T1未経験、かつARMコア/Cortexコア/Cortex-Rコアとかにも詳しくないのですが、これほどまでにぐちゃぐちゃになるということなら、スタックオーバーフローが気になりますが、スタックは足りていますでしょうか?(2は暴走しているのですよね。1も暴走である可能性がありますよね。レジスタの値が意図せず変わってしまうのだから、何が起きても不思議はないというか、、、)

    > このときのはr0が0に書き換わっていますが、変化する数値はランダムなようです。
    > また、r0以外も書き換わってしまうことがあるようです。

    > 1、アボート例外が発生。
    > 2、プリフェッチ例外が発生
    (3はともかく)

  • わわいです
    むっちゃよくあるあるなはなしです。

    ・原因はソフトウエア
    まず疑うのはスタックを食いつぶしていないか。
    不要な割り込みが有効になってしまっていないか
    配列のアクセスで範囲外になっていないか。
    特にジャンプテーブルなどを使ってる場合に特定のタイミングで範囲外のアクセスしていないか

    ・原因はハードウエア
    ターゲットボードはどのような素性のものでしょうか。
    メモリアクセスのタイミングはきちんと考慮されているか
    バスラインを不用意に伸ばしていないか
    デバッガの接続ラインを不用意に伸ばしていないか

    ということで、おそらくその原因はあなたのプログラム、あるいはハードウエアにあるので、他人に聞いても無駄かと思われます
  • まついさん、こんにちは。NoMaYです。

    デバッガのログの左端の7125,7126,7131とか40817,40818,40823とかの数値は実際にトレースされたトレースデータ毎にインクリメントされていくフレーム番号の数値ですね?(うっかり秒の数値かと勘違いしてしまいました。さすがに、この勘違いは、我ながら恥ずかしいです、、、)

    ということは、中略と書かれている部分は、せいぜい数十命令~百命令程ですね。正常時と異常時のそれぞれで略されている部分込みのデータをzipファイルに固めて添付して頂くことは出来ますか?多分、略された部分の命令列にr0の値を変更するような命令は無かった、ということなのだと思われますが、自分の目で見ておきたいです。(といっても、命令表とにらめっこしないといけませんが。)

  • In reply to わわい:

    わわいさん、ご回答ありがとうございます。

    デバッガでとらえたのがハードウェアが誤動作した結果である可能性はあります。
    ハードウェア不具合も疑ってはいるのですが、例外が発生するのは状況から見てソフトウェアに依存しているようです。
    周辺ペリフェラル(外部メモリバスアクセス、EtherNet、シリアル通信など)を使用しない状態、ノイズのがない卓上、複数の基板でテストしてみたのですが同じく例外が発生していて問題の切り分けができていない状況です。

    現在、わかっているのがOSのバージョンに依存している可能性があることです。
    古いバージョンではいまのところ一度も発生しておらず、OSメーカには問い合わせているのですが問題の解決にはいたっていません。なんからの証拠を掴まないとメーカに対しては難しいところです。
  • In reply to NoMaY:

    NoMaYさん、ご回答ありがとうございます。

    症状が発生したとき、まずはスタックを疑いまして確認しました。
    開発当初はサンプルプログラムをベースに作成していたため、スタックが最適な配置、サイズではないことがわかり、並びを変えて十分なスタック量を確保しました。
    また、実際にスタックを食いつぶしていないかスタックメモリ値を確認しました。
    その後、しばらく安定したのですが、ふたたび例外発生してしまい、解決には至りませんでした。いまのところスタックが直接の原因ではないと考えいます(例外発生時にスタック破損は確認できず)。

    7125 507m027.55

    ログ情報はCPUプログラム動作とは無関係に、トレース出力バッファに保存したものを、デバッガが任意のタイミングでトレース信号線より吸い出します。
    “7125”はデバッガが付加したトレース番号になります。通常は+1加算ですが、分岐命令のときは必ず+2されています。理由についてはデバッガメーカに問い合わせ中です。
    後ろの数値" 507m027.55"はデバッガがトレースデータのパケット受けたったときの時間になります。したがってCPU内部の時間とは無関係です。
    ただし、ログをみるとr0破損時にはデバッガがずっとまたされているようで異様に時間がかかっています。

    BX命令分岐時 
     正常時 507m027.63 → 507m027.68 0.05mS間
     異常時 508m027.58 → 508m028.48 0.90mS間

    内部レジスタが破損したときは時間が伸びるようで、この間になんからの動きがありそうです。
  • まついさん、こんにちは。NoMaYです。

    異常発生時でも、r0へロードしたロード元メモリの値が正常なことは確認されたとのことですが、TCM上のプログラムが壊れていないか、TCMのウェイトの設定は合っているか、の2点はどうですか?

    [追記]

    補足なのですが、トレースが分岐トレースの場合、分岐と分岐の間の命令列はデバッガが補完して表示していますが、ダウンロードした(デバッグ情報付きの)ファイルのプログラム部分の命令列をデバッガ内部にキャッシュしておいて、そのキャッシュされた命令列を元に補完している可能性もあって、TCM上のプログラムが壊れていても(プログラムの一部が書き変わってしまっていても)、トレースデータから判読することが出来ない可能性もあり、TCM上のプログラムが壊れていないか、気になりました。

  • まついさん、こんにちは。NoMaYです。

    あと、CPU実行が長い時間待たされる可能性として思い浮かんだのは、大きいサイズでのブロック転送モードのDMA転送ですね。(ただし、試しに、RZ/T1のハードウェアマニュアルを、優先順位、優先度、プライオリティ、で検索してみたのですが、CPUアクセスとDMAアクセスの間の優先順位に関する具体的な記述が無かったです。優先順位判定が行われ、優先順位の高い順にアクセスを行います、としか書かれていなかったですね。)

    >ただし、ログをみるとr0破損時にはデバッガがずっとまたされているようで異様に時間がかかっています。
    。。。
    >内部レジスタが破損したときは時間が伸びるようで、この間になんからの動きがありそうです。

    ちなみに、トレースデータの取得方法ですが、TRACECLK同期での垂れ流しとデバッガがJTAG/SWDで読み出すのと2種類ありますが、トレースデータの時間タグの分解能が10ns表示になっているので、TRACECLK同期での垂れ流し方式だったりしないでしょうか?

  • > 本来はbx r0命令で17F68に分岐するところ、なぜか0(Reset_Handler)に分岐。
    > r0の内容が書き換わってしまっている。

    スタックに積まれた r0 の値を配列アクセスの不備かなんかで破壊して r0 復帰の際に 0 になってるんでは?
    それか、他の割り込み処理でレジスタ内容を破壊してるんではないかと思います。
  • In reply to NoMaY:

    NoMayさん、調査とご回答ありがとうございます。

    基本的な部分を理解していなかったのですが、RZ/T1のトレース情報は分岐時のアドレス情報を取得しているだけで中身のデータ値までは知ることはできません(プログラムのオブジェクトからデバッガが生成する)。ご指摘のとおりメモリ上のプログラムが破損していたとしても、正しい動きであるか判別することができません。

    割り込み処理中に上位の割り込みが入らないように割り込み禁止処理をしているのですが、どうやら採用したOSのほうで割り込みを許可に戻しているようで、それが原因である可能性がでてきました。
    暫定処理として全ての割り込みの優先順位を同じにしたところ、(いまのところ)止まっていません。
  • In reply to fujita nozomu:

    fujita nozomuさん、ご回答ありがとうございます。

    NoMayさんに回答をしましたが、割り込み処理の問題である可能性が高そうです。
  • まついさん、こんにちは。NoMaYです。

    それ(だけ)では、辻褄が合わないな、と思っているのが、最初の投稿の話の、トレースデータ上はr0レジスタの値を変更する命令が無いのにr0レジスタの値が変わっていた、という話はどうなったのだろう?という点です。(こういう設定が出来るかどうか分からないのですが)トレースの設定が、割り込み処理内をトレースしないという設定になっていて、割り込み処理がトレースされなかったので、トレースデータ上にそういう命令が無かった、ということならば話は分かるのですが、そういうことだったのでしょうか?

  • In reply to NoMaY:

    NoMayさん、こんにちは。まついです。

    すみません。出張のため返信が遅れました。
    実はお恥ずかしながらエラッタを一部見逃していまして、トレースの最大クロックが150MHz→75MHzに修正されていました。前回のログもまったく嘘ではないですが、ゴミをひろっている可能性があります(Resetハンドラーがあちこちに出ていました。ログも数GBあるので...)。
    やはりスタックがどこかで破壊されている可能性が高いのですが、スタックオーバーフローはしておらず、多重割り込みによるレジスタ破壊なども直接の証拠が掴めていない状況です。
    現在、OSの割り込み周期を10倍にして発生頻度をあげて確認中です。IARの解析ツール(C-RUN)の購入も検討しています。なんとか尻尾をつかみたいと思います。

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page