RL78実行エラー

RF5F100PJにてCS+ for CA、CXとE1を使用してプログラムを組んでいます。

2日前より実行時にソフトウエア・ブレークにより動作が停止しましたと出力されるようになりました。

このエラーが出る前の状態に戻し、少しずつプログラムを追加していくとある段階で症状が出るようになります。

サイズの問題なのか、全く別の問題なのか特定出来ずに困っています。

このような症状はどういった場合に出るのか教えて頂けないでしょうか。

-----------------------------

なお、下記は不具合の出るプログラムのmapファイルです。

78K0R Linker V1.80                            Date:31 Aug 2019 Page:   1

Command:   -yC:\Program Files\Renesas Electronics\CS+\CACX\Device\RL78\D
           evicefile -_msgoff -oDefaultBuild\TWS100_V_M1.lmf -gi00000000
           000000000000h -mi0 -pDefaultBuild\TWS100_V_M1.map DefaultBuil
           d\op.rel DefaultBuild\TWS100_V_M1_K.rel
Para-file:
Out-file:  DefaultBuild\TWS100_V_M1.lmf
Map-file:  DefaultBuild\TWS100_V_M1.map
Direc-file:
Directive:


*** Link information ***

    17 output segment(s)
1A255H byte(s) real data
  3626 symbol(s) defined


*** Memory map ***


  SPACE=REGULAR

  MEMORY=ROM
  BASE ADDRESS=00000H   SIZE=40000H
         OUTPUT   INPUT    INPUT      BASE      SIZE
         SEGMENT  SEGMENT  MODULE     ADDRESS
         TVECT1                       00000H    00002H  CSEG AT
                  TVECT1   TWS100_V_M1_K
                                      00000H    00002H
         ??NMIROM                     00002H    00002H  CSEG
         TVECT2                       00004H    0001AH  CSEG AT
                  TVECT2   TWS100_V_M1_K
                                      00004H    0001AH
         TVECT3                       0001EH    00014H  CSEG AT
                  TVECT3   TWS100_V_M1_K
                                      0001EH    00014H
         TVECT4                       00032H    00014H  CSEG AT
                  TVECT4   TWS100_V_M1_K
                                      00032H    00014H
         TVECT5                       00046H    0002AH  CSEG AT
                  TVECT5   TWS100_V_M1_K
                                      00046H    0002AH
* gap *                               00070H    0000EH
         TVECT6                       0007EH    00002H  CSEG AT
                  TVECT6   TWS100_V_M1_K
                                      0007EH    00002H
* gap *                               00080H    00040H
         XOPTB                        000C0H    00004H  CSEG OPT_BYTE
                  XOPTB    op         000C0H    00004H
         ?CSEGSI                      000C4H    0000AH  CSEG
         ?OCDSTAD                     000CEH    0000AH  CSEG
* gap *                               000D8H    00FE8H
         OPT2                         010C0H    00004H  CSEG AT
                  OPT2     op         010C0H    00004H
* gap *                               010C4H    01F3CH
         XCHRDATA                     03000H    01E04H  CSEG MIRRORP
                  XCHRDATA TWS100_V_M1_K
                                      03000H    01E04H
         XMAIN                        04E04H    181C3H  CSEG
                  XMAIN    TWS100_V_M1_K
                                      04E04H    181C3H
* gap *                               1CFC7H    22E39H
         ??OCDROM                     3FE00H    00200H  CSEG

  MEMORY=RAM
  BASE ADDRESS=FAF00H   SIZE=05100H
         OUTPUT   INPUT    INPUT      BASE      SIZE
         SEGMENT  SEGMENT  MODULE     ADDRESS
         DSTK                         FAF00H    00080H  DSEG BASEP
                  DSTK     TWS100_V_M1_K
                                      FAF00H    00080H
         KADATA                       FAF80H    011B6H  DSEG
                  KADATA   TWS100_V_M1_K
                                      FAF80H    011B6H
* gap *                               FC136H    03CEAH
         DMAIN                        FFE20H    000ADH  DSEG SADDR
                  DMAIN    TWS100_V_M1_K
                                      FFE20H    000ADH
* gap *                               FFECDH    00033H
* gap (Not Free Area) *               FFF00H    00100H


 Target chip : R5F100PJ
 Device file : V1.14

  • > RF5F100PJにてCS+ for CA、CXとE1を使用してプログラムを組んでいます。

    「RF5F100PJ」で検索
    https://www.renesas.com/jp/ja/search/keyword-search.html#q=RF5F100PJ

    「R5F100PJ」で検索
    https://www.renesas.com/jp/ja/search/keyword-search.html#q=R5F100PJ

     

    RL78/G13 のフラッシュメモリの容量が 256kB の R5F100PJ が正しいものという前提では

    > 下記は不具合の出るプログラムのmapファイルです。

    map ファイルの各領域の数字には問題なく、容量的にも余裕があると思いますが

    >         XMAIN                        04E04H    181C3H  CSEG
    >                   XMAIN    TWS100_V_M1_K
    >                                      04E04H    181C3H

    コードがこんなにでかいわけはそうそうないと思うのでデータも含んでるんだろうと思いますが、mirror 領域を通してアクセスされるべきデータが 03000H~0AEFFH 内に正しく配置されてるかは確認されるべきと思います。

  • > 2日前より実行時にソフトウエア・ブレークにより動作が停止しましたと出力されるようになりました。

    ステップ実行で問題が出る場所の当たりを付けるとかはされてないんでしょうか?
  • KOBAさん、こんにちは。NoMaYと申します。

    CA78K0R(およびCC-RL)であれば、リンカでワーニングやエラーが出ていなければ「サイズの問題」は以下の4点かな、と私は思います。マップファイルを見る限り、今回は、(3)と(4)は非該当、(2)は問題無し、と思いますが、(1)はマップファイルからでは分からないですね。

    (1) スタックオーバーフロー
    (2) プロジェクトでのデバイス選択ミス
    (3) フラッシュライブラリの予約領域の確保ミス
    (4) Boot/Flashの分割ミス

    それで、「実行時にソフトウエア・ブレークにより動作が停止」というのは、コードが無い場所でプログラムが停止した(停止した場所のフラッシュメモリのコードは0xFFですよね)、ということでは無いでしょうか?そうであれば、「E1を外すと動かない」「突然リセットが掛かる」と並んで(RL78のオンチップデバッグでは)難しいトラブルかな、と私は思います。

    とりあえず、以下、その前提でリプライすることにしますが、コンパイラが信用出来るなら、そのような症状が発生する原因は、以下の可能性が高いと私は思います。

    (1) スタック上の戻り番地の値が不正になった
    (1-1) スタックオーバーフローによりスタックがRAMの無い領域に突き抜けてしまった
    (1-2) スタックオーバーフローによりスタックとグローバル/スタティックの変数の領域が重なってしまった
    (1-3) プログラムの不具合によりスタック上の戻り番地の値を壊してしまった

    (2) 関数ポインタの値が不正になった
    (2-1) 上の(1-1)と同様にスタックがRAMの無い領域に突き抜けて(スタック上の)関数ポインタの値が壊れた
    (2-2) 上の(1-2)と同様にスタックとグローバル/スタティックの変数の領域が重なって(何れかの)関数ポインタの値が壊れた
    (2-3) プログラムの不具合により関数ポインタの値を壊してしまった

    (3) 割り込みベクタの指定忘れ

    次に考えることは、以下のことかな、と私は思います。

    (1-1) SPの値を確認すれば分かる
    (1-2) 同上 および追加確認として
    (1-2') SPの指すメモリの下側(ret/reti/retb後だから)のデータがブレークしたアドレスであれば本可能性が高い
    (1-3) 同上((1-2')のこと)

    (2-1) AX,BC,DE,HLの何れかのレジスタの値がブレークしたアドレスであれば本可能性が高い
    (2-2) 同上
    (2-3) 同上

    (3) 割り込み回りのソースを確認する

    (4) 上記の何れでもなければ本切り口でのデバッグは諦めて別の切り口を考える

    その次に考えることは、以下のことかな、と私は思います。

    (1-1) スタックオーバーフローしないようにスタック領域の設定を変更する
    (1-2) 同上
    (1-3) 配列の添え字やポインタの範囲チェックを行うassert()を挿入する

    (2-1) 関数ポインタで関数呼び出ししているソース箇所を捜してassert()を挿入する *1
    (2-2) 同上
    (2-3) 同上
    (2-1) スタックオーバーフローしないようにスタック領域の設定を変更する
    (2-2) 同上 および追加確認として
    (2-2') SPの指すメモリの上側(call rp後だから)のデータが関数ポインタを使った関数呼び出し元アドレスかどうか確認する
    (2-3) 同上((2-2')のこと)

    *1: 例えば、簡易には、フラッシュメモリ範囲内であること、など。

    ちなみに、CA78K0Rの話ではないのですが、CC-RLのProfessional版であればコンパイラに、スタック破壊検出機能というものや、不正な間接関数呼び出し検出機能というものが、あります。

    -stack_protector/-stack_protector_all 【Professional版のみ】 【V1.02以降】
    スタック破壊検出コードを生成します。
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.02.00/CS+.chm/Compiler-CCRL.chm/Output/ccrl02c0501y1208.html

    -control_flow_integrity【Professional版のみ】【V1.06以降】
    不正な間接関数呼び出しを検出するコードを生成します。
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.02.00/CS+.chm/Compiler-CCRL.chm/Output/ccrl02c0501y1209.html
     

  • KOBAさん、こんにちは。NoMaYです。

    あと、関数ポインタを使われているか分かりませんが、もし使われているのであれば、far関数アドレスをnear関数ポインタもしくは16bit変数に代入していないか、気になります。(素朴に関数アドレスを関数ポインタに代入していればコンパイラやリンカでワーニング等出るかと思うのですが、明示的にキャストしていると出ないですので。)

  • おはようございます。kobaです。
    hujita nozomuさま
    NoMaYさま
    ご返信いただきありがとうございます。

    NoMaYさま
    「実行時にソフトウエア・ブレークにより動作が停止」というのは、コードが無い場所でプログラムが停止した(停止した場所のフラッシュメモリのコードは0xFFですよね)、ということでは無いでしょうか?

    その通りです。ステップ実行していくと定義のない割り込み(0XFF)に飛んで停止しています。



    far関数アドレスをnear関数ポインタもしくは16bit変数に代入していないか、気になります。

    アセンブラで組んでいるため、関数等の定義のことは良くわかりませんが、サイズ違いのデータのアクセスということでしょうか。勉強不足で申し訳ありません。



    hujita nozomuさま
    コードがこんなにでかいわけはそうそうないと思うのでデータも含んでるんだろうと思いますが、mirror 領域を通してアクセスされるべきデータが 03000H~0AEFFH 内に正しく配置されてるかは確認されるべきと思います。

    ご判断された通り、かなりのデータを配置しているためコードが大きくなってしまいました。


    製品の製作を行っていまして、ほとんど完成段階での今回のトラブルです。
    今回ご教授頂いた内容を詰めていきたいと思います。
  • KOBAさん、こんにちは。NoMaYです。

    アセンブラで組んでおられたのですね。ということは、変な箇所へ飛んでいってしまう、という命令は以下の何れかですよね?(アセンブラやリンカでワーニング無しであれば、CALL先 or BR先 をラベルで書いていて、そうなってしまうのなら、アセンブラやリンカのバグであろう、と思いましたので、、、) ならば、全然違う理由の可能性も高い、です。以下の(1)と(3)であれば、CSレジスタの考慮漏れ、の可能性が高いですし、(2)であれば、(追加コード(アセンブラ)に新規CALLT命令があってペアとなる)CALLTベクタの設定忘れ、の可能性が高いです、、、なお、(4)に関しては、私の前のリプライの内容の可能性は高いです、、、

    (1) CALL rp
    (2) CALLT [addr5]
    (3) BR AX
    (4) RET/RETI/RETB

    ちなみに、以下の0xFFというのは(フラッシュメモリ上のコードではなく)アドレス(つまり0x000FF番地)ですか?

    > ステップ実行していくと定義のない割り込み(0XFF)に飛んで停止

  • > その通りです。ステップ実行していくと定義のない割り込み(0XFF)に飛んで停止しています。

    RL78/G13は割り込みベクタとして用意されている領域が00000H〜0007FHであり、「定義のない割り込み(0XFF)」の意味は解りかねますが、ステップ実行中に訳わからん場所に飛ぶということであれば割り込み処理で暴走している可能性が高いと思います。
    RL78は割り込み処理のエントリは00000H〜0FFFFHの範囲に配置する決まりがありますがそれが守られているかどうか確認されることをお勧めします。
  • KOBAさん、こんにちは。NoMaYです。

    私は、まだ何か勘違いしていそうです、、、 ステップ実行で「ソフトウエア・ブレークにより動作が停止しましたと出力される」のですか? ひょっとして、ステップオーバー実行でしょうか?そうであれば、アセンブラで組んでおられるということですので、追加したコードのPUSH/POPの間違いによるRET/RETI/RETBの誤動作、もっと単純にはレジスタの使用ミス(例えばCS:BCにサブルーチンアドレスをセットしたのにCALL AXしてしまった)、等、原因の可能性はもっと幅広くなりますね、、、

    あと、もしアセンブラやリンカでワーニングが出ているなら内容を確認してみて下さい。そして、取り除いてみて下さい。(意味不明のワーニングで対処出来なければ、それを質問してみて下さい、、、)

  • おはようございます。
    hujita nozomuさま、NoMaYさま ありがとうございます。

    今週に入っていろいろ試してみています。

    push、popは私も社内の者にも確認して貰いましたが、間違ってはいませんでした。

    CSレジスタは使用しておらずCALL !!addres20にて呼び出しをかけています。
    試しに、プログラムの一番最初にあるCALL !!addres20をCSレジスタ & CALL AXに変更したり、連続で書いていたコードを64kの境でcsegアドレス指定(下位バイトが割り込みと一致しないアドレスを指定)してみたところ、どちらも動作することは確認できました。ただし、CSレジスタをセットする方に関しては別の場所でハングアップしてしまう結果となったため、現段階ではアドレス指定しただけの状態です。
    なぜ動くのか納得出来ないため、もっと別の方向からも原因追究をしなければと考えています。
  • KOBAさん、こんにちは。NoMaYです。

    その後、どうでしょうか?「なぜ動くのか納得出来ない」変更で動くようになった点は、因果関係が分かるようになりましたでしょうか?