E1エミュレータを使ってRL78/G10をオンチップデバッグ中にプログラム実行を停止するとCPUとの通信が切れてしまいます。
この状態が頻発していて、まともに止まるのは数えるほどしかありません。
エミュレータとCPUは添付した画像の通りにしています。
配線に問題があるのか、それとも他に問題があるのか、教えていただけませんか?
CPU : R5F10Y16ASP
開発環境 : CS+ [CC]
エミュレータ : E1
origamiさん
プログラムが暴走していると、origamiさんのように強制ブレークしても戻ってこないことがあります。
ちなみに、ブレークポイントを設定した場合に正常にブレークできます?
Kirin様
浅学で申し訳ないのですがRL78/G10シリーズはブレークポイントを設定出来なかったと思うのですが、何か方法があるのですか?
横槍失礼します。
スタックはROMではなく、RAMです。
また、ROM使用率がもっと少ない頃は、E1とは常に正常通信していたのでしょうか?
Yesなら、main()をほぼ空にすれば正常にブレークするのではないでしょうか?
ビシ様
現在のRAMは168Byteまで使用しています。(CPU:R5F10Y16ASP)
ROM使用率が少ない初期の頃は停止できていました。
main()はあまり使用していません。ほぼ割り込みで処理しています。
チョコです。
>現在のRAMは168Byteまで使用しています
RAMは256Byteあるので、スタック(64Btye)を含めてもオーバはしていないと
考えられますが、スタックそのものがオーバしている可能性があります。
メモリ・ウィンドゥでどの程度消費されているか確認するのがいいでしょう。
>ROM使用率が少ない初期の頃は停止できていました
プログラムが大きくなると、変数も増加していきます。Cのプログラムで暴走
するのは、スタックがあふれるか、ベクタを定義していない割り込みが発生
している可能性が高いと考えられます。
通常、ローカル変数はスタック領域に確保されるので、これも注意です。
R5F10Y16は割り込みのソースは少ないので、残りのすべての割り込みに
ダミーのベクタを設定して、ベクタのとび先には、空の割り込み関数を置いて
みるのも方法かもしれません。
中途半端でごめんなさい。
先ずは、WDTを有効にしているか、否かですが、
仮に、無効にできるのであれば、WDTは無効状態でブレーク実行されてみてはいかがでしょうか?
Jinです。
>ROM使用率が少ない初期の頃は停止できていました。
と、言う事は、WDTは関係なさそうですね・・・・・
チョコさんの書き込みに補足です。
私はCallWalkerを使ってます。
①CS+のビルド・ツールのプロパティのリンクオプションタブのその他のスタック情報ファイルを出力するをはい。
②RenesasElectronicsCS+のユーティリティーのCallWalkerを起動。
③CallWalkerのFileのImportStackFileでスタック情報ファイル(プロジェクトディレクトリ内のDefaultBuild内のxxx.sni)を読み込む。
モダンなプログラマはローカル変数をたくさん使うのでROM使用率97.56%はかなりきわどくRAMもきっちりと検証しないとかなり危険だと私も思います。ヒープは使っていないんですよね。
チョコ様
>R5F10Y16は割り込みのソースは少ないので、残りのすべての割り込みにダミーのベクタを設定して、ベクタのとび先には、空の割り込み関数を置いてみるのも方法かもしれません。
上記を試したころ、1/2の確率で停止できるようになりました。
しかし、停止してからプログラムを再開するとプログラムが止まってしまいます。
Jin様
>仮に、無効にできるのであれば、WDTは無効状態でブレーク実行されてみてはいかがでしょうか?
WDTの割り込みを禁止してみたのですが、やはり停止に失敗してしまいます。
>origamiさん
皆さんが仰る通り、スタック不足の様な気がします。。。
一案ですが、OKだった初期の頃を例えば1年前とすると、6ヶ月前の状態に戻すとどうなりますか?
もしOKなら、半年間で追加したプログラムのいずれかに原因がある、と思います。
最終的には、少しずつプログラムを削り、切り分けするしかないかもしれません。
勿論、kijoさん仰せの通り、CallWalkerでの確認の方が先決です。(簡単ですから...)
CallWalkerでスタックを確認してみました。
左側に表示されているMAX以外の数値を加算していったところ、350になりました。
単位がByteならスタックの容量(64Byte)をはるかに越えてますよね・・・
>左側に表示されているMAX以外の数値を加算していったところ、350になりました。
すみません、勘が悪くて何をされたのか察しがつきませんが、重要なのは、左上の(Max:xxxx)です。
このサイズ(単位はバイト)と、
を加算してRAM容量を超えていたら、その時点でNGです。
※CallWalker-Viewメニューの、RequiredとUsedで算出されるサイズが異なります。
スタックはそのファンクションが終了すれば解放されます。私の場合は、R8CやSHですが、多重割り込みを無くして割り込み処理をなるべく小さくしているので、割り込み専用のスタックエリアはなかったはずなので、mainと最大の割り込み処理を足した分でサイズは十分になります。通常はmain(yyy)のサイズがそのままxxx.cal(MAX:yyy)に反映します。
関数のポインタ呼び出しや多重割り込みや再帰呼び出しを使っているときは要注意です。込み入った話になるのでここでは触れない方が良さそうです。C言語で階層化設計されているのでしょうから、最適化をかけてしまってはいかがでしょうか?ローカル変数がメモリー上に無かったり、処理が無くてブレークポイントが設定できないなどデバックは大変になりますが、なんとかなると思います。思惑が外れてブレークポイントが設定できない場合はバクの可能性大です。
不出来な質問者で申し訳ありません・・・
スタックはMax56になっています。
現在のRAM使用量が168Byteなのでスタックと加算して224Byteになります。
RAM容量の256Byteを超えていないのでNGではないようです。
スタック見積もりツールは再帰呼び出しがあると正しくスタック使用量を見積もれないようですが該当はしないでしょうか?
int tarai(int x, int y, int z) { return (x <= y) ? y : tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y)); } void main(void) { tarai(12, 6, 0); }
グローバル変数領域とスタック領域を足して、256Byteを超えるかで判断されて
いるようですが、それだけでは問題があります。スタックは、スタートアップ・
ルーチンで指定している領域しか確保されていないので、領域の配置によっては
おかしくなります。とりあえず、スタートアップ・ルーチンのスタック領域の
サイズを大きくしてみてはどうでしょう。(とりあえず、16Byte増やして、
0x50(80Byte)辺りにしてはいかがでしょう。
>とりあえず、スタートアップ・ルーチンのスタック領域のサイズを大きくしてみてはどうでしょう。(とりあえず、16Byte増やして、0x50(80Byte)辺りにしてはいかがでしょう。
試してみたところ、停止できるようになりました。ありがとうございます。
ただ、停止後に実行しようとすると、失敗する時があります。
(CPUリセット後スタートをすると失敗しない)
> 試してみたところ、停止できるようになりました。
とりあえずは、おめでとうございます。
> ただ、停止後に実行しようとすると、失敗する時があります。
デバッガがスタックを使用したために、おかしくなっている可能性があります。
(最初の頃に書いたように、デバッガが数Byteスタックを使うのでその分の影響)
今のところは、もう少しスタック領域を広げてみるしか思いつきません。
2016/1/7 3:29と0:02のorigamiさんの書き込みからmainよりも割り込みのサイズが大きいと予想してます。多重割り込みは無しで、_mainと最大の割り込みのサイズの和は80以下ですか?
余計なことかもしれませんが、必要スタックサイズは明確に求められるのだから、しっかりと把握して設定した方が良いです。適当にスタックサイズを再設定して結果オーライだと将来的に困ると思います。
コストや時間を考慮すると、以前に書いたとうり、メモリー優先の最適化が最有力の対応でしょ!
>メモリー優先の最適化が最有力の対応でしょ!
最適化を行うと、デバッグ用のシンボルが出なくなるところがあります。
そうなると、ブレークポイントが設定できなくなることがあります。
乱暴ですが、まずは、R5F10Y17(ROM4kByte、RAM512Byte)で
デバッグを進めて、その後にR5F10Y16という手もあります。
cstart.asm の
;-------------------------------------------------- ; ROM data copy ;--------------------------------------------------
の直前辺りに
$IF (__RENESAS_VERSION__ >= 0x01010000) MOVW HL,#LOWW(__STACK_ADDR_END) MOVW AX,#LOWW(__STACK_ADDR_START) $ELSE ; for CC-RL V1.00 MOVW HL,#LOWW(_stackend) MOVW AX,#LOWW(_stacktop) $ENDIF MOVW BC,#0xADDE MOVW DE,#0xEFBE BR $.L2_STACK .L1_STACK: XCHW AX,DE XCHW AX,BC MOVW [HL],AX XCHW AX,DE INCW HL INCW HL .L2_STACK: CMPW AX,HL BNZ $.L1_STACK
を加えると main() が実行される前にスタック領域の全てが 0xDE, 0xAD, 0xBE, 0xEF で初期化されます。デバッガでスタック領域がどこまで使われたかの一助になるかと思います。