RL78/l1Aでマイコンリセットしてしまいます

R5F107AEで意図しないタイミングでソフトリセットが発生します。
RESFレジスタによりリセット要因を調査すると、「WDT」や「パリティエラー」や「不正命令」など、
色々な要因でリセットしていますが、「不正メモリアクセス」でリセットすることが多いです。
・PCとUART通信を1sec毎に行っていて、リセット発生頻度は連続通電で1日に1回程度です。
・リセットタイミングは、送信転送完了割り込み処理を終了し次の1バイトを送信時にリセットしています。
・CS+のスタックメモリ見積ツールを使用し、スタック領域破壊は無いことを確認しました。
・リンクディレクティブファイルに問題ないことはメーカーに確認しました。
・今のところE2Liteを接続してのオンチップデバッグではリセットしていません。
・EEPROMエミュレーション・ライブラリPack01 パッケージVer2.1.0を使用しています。

コードとコード生成ツールを確認した限りでは変な割り込みはなさそうですが(再度調査します)
何かマイコンリセットしてしまう要因は何か考えられますでしょうか。アドバイスいただけたらと思います。

Parents
  • RL78のこの手のエラーに泣かされた時の経験です(仕様やオプションの取り方で変わるカモ)。

    【RAMパリティ】書かれていないRAMをいきなり読むと発生する。RAMパリティ割込はデバッガ環境中では出てこないから始末が悪い

    1)V1.07以前は自動生成のcstart.asmでスタック領域の0フィルがデフォルトではない。コメントアウトを取るか、V1.07以降のでプロジェクト作り直す

    2)発生事例
     ローカル変数の宣言時、明示的な初期値書込みされないので、二回一致とかのロジックで捨て読みとかすると出ることがある。
     ポインタ書き込み先引数を実引数に書き間違えた時、例えば、func_xx( &arg )をfunc_xx( arg )みたいな間違いしたとき。
     構造体のパディングの隙間も注意。パディングになっているところは変数初期化に関わらない模様。その構造体をメモリブロックとしてリードアクセスした場合、未定義変数にあたるパディング用域でパリティ踏む恐れあり

    3)気にすべきこと
     cstart.asmがV1.07以前のコンパイラで生成されていないか(_stkinitがコメントアウトされている)
     型のウォーニングを軽視してはいけない
     多重比較読み出しとかのアルゴリズム注意(二度読みするからって未初期化変数をリードをしてはいけない)
     ウォーニングで未定義変数アクセス出ているものは確実に消しておくこと
     構造体の使い方に注意。パディングの可否/アクセスのされ方等。(コード見てるだけでは発見できない内容)
    発生時のトラブルシューティング
     RAMパリティ機能禁止(RPERDIS=1)で起こらなくなるか確認

    【不正メモリアクセス】

     const指定された変数に対してポインタ参照させ、そのポインタにライトアクセスとかしていないでしょうか?

    【#pragma xx系の問題】

    1)#pragma interrupt 割込み関数名(割込みベクタ)って宣言するんだけど、割込み関数名が誤っててもエラー出さずに謎の動作になる

    2)#pragma address (変数名=配置アドレス)って宣言するんだけど、変数名が誤っててもエラー出さない。よってあるべきアドレスに変数が配置されない

    【コードフラッシュ上の内容のアクセス】

    例えば、コードフラッシュ上の値をuint16_t の実アドレス変数作って、それをポインタ扱いにキャストして使ってるとこないでしょうか?_far修飾とかしないと意図しない領域見てたりします。

    ・FAQ 1011546:すべてのROM領域を読み出す方法
    https://ja-support.renesas.com/knowledgeBase/17796625

Reply
  • RL78のこの手のエラーに泣かされた時の経験です(仕様やオプションの取り方で変わるカモ)。

    【RAMパリティ】書かれていないRAMをいきなり読むと発生する。RAMパリティ割込はデバッガ環境中では出てこないから始末が悪い

    1)V1.07以前は自動生成のcstart.asmでスタック領域の0フィルがデフォルトではない。コメントアウトを取るか、V1.07以降のでプロジェクト作り直す

    2)発生事例
     ローカル変数の宣言時、明示的な初期値書込みされないので、二回一致とかのロジックで捨て読みとかすると出ることがある。
     ポインタ書き込み先引数を実引数に書き間違えた時、例えば、func_xx( &arg )をfunc_xx( arg )みたいな間違いしたとき。
     構造体のパディングの隙間も注意。パディングになっているところは変数初期化に関わらない模様。その構造体をメモリブロックとしてリードアクセスした場合、未定義変数にあたるパディング用域でパリティ踏む恐れあり

    3)気にすべきこと
     cstart.asmがV1.07以前のコンパイラで生成されていないか(_stkinitがコメントアウトされている)
     型のウォーニングを軽視してはいけない
     多重比較読み出しとかのアルゴリズム注意(二度読みするからって未初期化変数をリードをしてはいけない)
     ウォーニングで未定義変数アクセス出ているものは確実に消しておくこと
     構造体の使い方に注意。パディングの可否/アクセスのされ方等。(コード見てるだけでは発見できない内容)
    発生時のトラブルシューティング
     RAMパリティ機能禁止(RPERDIS=1)で起こらなくなるか確認

    【不正メモリアクセス】

     const指定された変数に対してポインタ参照させ、そのポインタにライトアクセスとかしていないでしょうか?

    【#pragma xx系の問題】

    1)#pragma interrupt 割込み関数名(割込みベクタ)って宣言するんだけど、割込み関数名が誤っててもエラー出さずに謎の動作になる

    2)#pragma address (変数名=配置アドレス)って宣言するんだけど、変数名が誤っててもエラー出さない。よってあるべきアドレスに変数が配置されない

    【コードフラッシュ上の内容のアクセス】

    例えば、コードフラッシュ上の値をuint16_t の実アドレス変数作って、それをポインタ扱いにキャストして使ってるとこないでしょうか?_far修飾とかしないと意図しない領域見てたりします。

    ・FAQ 1011546:すべてのROM領域を読み出す方法
    https://ja-support.renesas.com/knowledgeBase/17796625

Children
  • 詳しくコメントいただきありがとうございます!

    コードを確認しつつ、とりあえず最適化無しにして駆動させてみたところそれ以来1度もリセットが発生しておらず、このまま終わらせていいのか悩んでいたところです。

    アドバイスいただいた点も確認していこうと思います。

  • 現状のプログラム、最適化をオンにしてまだ問題が起こる場合、自動変数(静的確保じゃなくてスタックフレームに存在する変数)の参照関係が最適化で本来必要なタイミングより前に解放されてしまってるようなこともあるかもしれません。

    SH2のコンパイラではそういうのが結構起こってました。その時の経験からポインタ渡しの関数には要注意だなと感じました。おそらく、ルネサス純正コンパイラには似たような最適化の手法が使われていると思います。volatile指定してもダメだったり・・・場合によっては(void)を使って明示的に参照範囲をコンパイラに教えてやるのがいいです。

    int x = 12345;

    func(&x);

    (void)x;

    こうすると(void)x;のところまでxは有効です。値渡しなら関数funcは正しく値を受け取れますが、ポインタ渡しだと(void)x;を書かないでおくと最適化でxのポインタ値をfuncに渡してスタックフレームからxが解放されてfunc関数の中でxの値が参照できなくなるということです。