CC-RL/CC-RX/CC-RHでVisual Studioの__debugbreak()機能のようなものを作って試してみようと思います

こんにちは。NoMaYです。

昔、Windowsアプリケーションを作っていた頃、WindowsのDebugBreak()というAPIでブレークポイントを(諸般の事情で)手作業でソースに書いていたことがありました。別スレッドの案件でちょっとそのことを思い出しましたので試してみることにしました。

Google検索: Windows OR VisualStudio DebugBreak OR __debugbreak
www.google.com/search?q=Windows+OR+VisualStudio+DebugBreak+OR+__debugbreak&num=50
 

  • こんにちは。NoMaYです。

    まずCC-RLで試してみました。以下のインラインアセンブラ関数で実現することが出来ました。ただ、CS+とVSCode、実機とルネサスRL78シミュレータで試してみましたが、残念ながら、実機でしか意図通りには動作しませんでした。

    #pragma inline_asm __debugbreak
    static void __debugbreak(void)
    {
        .db 0xff
    }

     
    top > コンパイラ編 > コンパイラ言語仕様 > 拡張言語仕様 > 拡張言語仕様の使用方法 >
    アセンブラ命令の記述(#pragma inline_asm)
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.09.00/CS+.chm/Compiler-CCRL.chm/Output/ccrl04c0206y0012.html
     
    以下、CS+とVSCodeの画面コピーです。

    実機+CS+


    実機+VSCode


    ルネサスRL78シミュレータ+CS+ (GUI上はRun中のまま、ただしStopボタンを押すと想定した位置で止まる)



    ルネサスRL78シミュレータ+VSCode (GUI上はRun中のまま、さらにStopボタンを押すと想定外の位置で止まる)


     

  • こんにちは。NoMaYです。

    次はCC-RXで試してみました。RL78のブレークポイントの命令コードが0xffだったのに対して、RXのブレークポイントの命令コードは0x01ですので、CC-RLとCC-RXでインラインアセンブラの仕様が同じだったのであれば、それに置き換えるだけのことだったのですけれども、CC-RLでは使えた.byte擬似命令がCC-RXでは使えませんでしたので、苦肉の策を取ることにしました。今回は以下のインラインアセンブラ関数で実現してみました。

    実は、数年前にがじぇルネのブログ投稿欄にGR-CITRUSについて投稿したものが幾つかあって、そこに一度作ったものがあったのですけれども、その時のインラインアセンブラ関数ではCC-RXがワーニングを表示してしまっていましたので、それとは違うインラインアセンブラ関数にしてみました。ただ、.byte擬似命令がCC-RXで使えないことに対する小細工としてのインラインアセンブラコードが、当時のものでは2バイトだったのに対して、今回のものでは6バイトになっていますので、#if 1/0で切り替えられるようにしてあります。ちなみに、そのワーニングは-nomessageや-no_warningの抑止対象範囲外のものとなっていますので、残念ながら当時のものに対してワーニングを抑止することは出来ません。

    なお、CS+とVSCode、実機とルネサスRXシミュレータで試してみましたが、RXシミュレータでは命令コードの0x01は不正命令として扱われることになっているようで、プログラムの不正命令例外ハンドラが実行されるようになっています。もしかすると、実機でもデバッガを繋いでいない場合には、そういう動作になっているかも知れません。

    #pragma inline_asm __debugbreak
    static void __debugbreak(void)
    {
    #if 1 // 1 or 0

    // This code is longer than the latter but the code does not cause any warnings.
    mov.l #3, r1
    bra.l r1
    add #0,r1 // .byte 0x62, 0x01
    // 0x62 is 1st code of add #0,r1
    // 0x01 is 2nd code of add #0,r1 and is the debug exception code of RX such as 0xCC (int 03h) of x86
    // If you want to start from the next instruction, you need to change PC by yourself or to make a CS+'s Python script.

    #else

    // This code is shorter than the former but the code causes `W0551001:Destination address may be changed` warning.
    ?: bra.b ?- + 1 // .byte 0x2E, 0x01
    // 0x2E is 1st code of bra.b PC + 1
    // 0x01 is 2nd code of bra.b PC + 1 and is the debug exception code of RX such as 0xCC (int 03h) of x86
    // If you want to start from the next instruction, you need to change PC by yourself or to make a CS+'s Python script.

    #endif
    }

     
    GR-CITRUSでCS+のRXシリアルデバッガを使えるようにしてみた(IDE for GR編)
    community-ja.renesas.com/gr_user_forum_japanese/b/weblog2/posts/gr_2d00_citrus_5f00_rx_2d00_serial_2d00_debugger_2d00_ide4gr

    GR-CITRUSでCS+のRXシリアルデバッガを使えるようにしてみた(CC-RX&CS+編)
    community-ja.renesas.com/gr_user_forum_japanese/b/weblog2/posts/gr_2d00_citrus_5f00_rx_2d00_serial_2d00_debugger_2d00_cc-rx

    GR-CITRUSでCS+のRXシリアルデバッガを使えるようにしてみた(実装編)
    community-ja.renesas.com/gr_user_forum_japanese/b/weblog2/posts/gr_2d00_citrus_5f00_rx_2d00_serial_2d00_debugger_2d00_impl

    (5-5) r_usb_PMSC_apl.cの先頭のbebugbreak()というインラインアセンブラ関数

    #if defined(RXSDBG) // for RX Serial Debugger
    #pragma inline_asm debugbreak
    static void debugbreak(void) { ?: bra.b ?- + 01h ; .byte 0x2E, 0x01 }
    // 0x2E is 1st code of bra.b PC + 01h
    // 0x01 is 2nd code of bra.b PC + 01h and is the debug exception code of RX such as 0xCC (int 03h) of x86
    // If you want to start from PC + 02h, you need to change PC by yourself or to make a CS+'s Python script
    #endif



    top コンパイラ編 コンパイラ言語仕様 拡張言語仕様 拡張仕様の使用方法
    4.2.4 拡張仕様の使用方法
    (5) アセンブラ記述関数インライン展開
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.09.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0204y.html#96980

    以下、CS+とVSCodeの画面コピーです。

    実機+CS+


    実機+VSCode


    ルネサスRXシミュレータ+CS+ (プログラムの不正命令例外ハンドラへ飛ぶ)


    ルネサスRXシミュレータ+VSCode (プログラムの不正命令例外ハンドラへ飛ぶ)

     

  • こんにちは。NoMaYです。

    あとCC-RHでも試してみました。(といっても、実機を持っていないのと、これまでのことからルネサスシミュレータの場合であっても実機とは相応の動作の違いがあることが分かっていますので、どちらも動作させることはしていなくて、単にビルドしてみただけです。すみません。)

    CC-RHの特別な点(というかRH850の特別な点)としては、ブレークポイントの命令コードが命令セットの1つの命令としてニーモニック記述出来ることです。(ちなみに、脱線しますけれども、RH850の他の興味深い点として、トレースデータ出力ポートにデータを出力する機能が命令セットレベルで存在していることです。関連リンクの最後にCS+のオンラインヘルプへのリンクを書きました。) 最初に書いた理由により動作を試すことまではしていないのですけれども、以下のインラインアセンブラ関数をビルドすることが出来たことと、以下のエミュレータのユーザーズマニュアルの記載から考えても、たぶん実機で動作するのではないだろうかと思います。

    #pragma inline_asm __debugbreak
    static void __debugbreak(void)
    {
        dbtrap
    }

     
    E1/E20エミュレータ,E2エミュレータ ユーザーズマニュアル別冊 (RH850/F1KH,RH850/F1KMグループ接続時の注意事項)
    www.renesas.com/jp/ja/document/mat/e1e20-emulator-e2-emulator-additional-document-users-manual-notes-connection-rh850f1kh-and-rh850f1km#page=23

    4.1 実デバイス動作とE1/E20/E2エミュレータ接続時動作の相違に関する注意

    No.1 DBTRAP命令

    DBTRAP命令はソフトウェアブレーク機能に使用するため、プログラムには使用できません。


    ちなみに、この注意事項はRH850の別のマイコンでは記載されていませんでした。同じ命令だとは思うのですけれども。

    E2エミュレータ、IE850A ユーザーズマニュアル別冊 (RH850/E2xシリーズ接続時の注意事項)
    www.renesas.com/jp/ja/document/mat/e2-emulator-ie850a-additional-document-users-manual-notes-connection-rh850e2x-series#page=28

    5.3 実デバイス動作とエミュレータ接続時動作の相違に関する注意事項


    [関連リンク]

    エミュレータのユーザーズマニュアルやCS+のオンラインヘルプに「RH850G3M/G3MH/G3K/G3KH ユーザーズマニュアル デバッグ命令編」というものが存在するような記載があったのですけれども、残念ながら、見付けられませんでした。そこで、RH850では無くV850のドキュメントですけれども、DBTRAP命令のページを探してみました。

    V850ES 32ビット・マイクロプロセッサ・コア アーキテクチャ編
    資料番号 U15943JJ4V1UM00 (第4版) 発行年月 March 2010 NS
    (C) NEC Electronics Corporation 2002
    www.renesas.com/jp/ja/document/mat/v850es-architecture#page=146

    6. 2. 3 ディバグ・トラップ
    ディバグ・トラップは,DBTRAP命令の実行,またはディバグ機能のトラップにより発生する常時受け付けが可能な例外です。
    ディバグ・トラップが発生した場合,CPUは次の処理を行います。


    V850E2 32ビット・マイクロプロセッサ・コア アーキテクチャ編
    資料番号 U17135JJ1V1UM00 (第1版) 発行年月 June 2004 NS CP(K)
    (C) NEC Electronics Corporation 2004
    www.renesas.com/jp/ja/document/mat/v850e2-architecture-preliminary#page=198

    6. 2. 3 ディバグ・トラップ,ディバグ・ブレーク
    ディバグ・トラップ,ディバグ・ブレークは常時受け付けが可能な例外です。
    ディバグ・トラップは,DBTRAP 命令の実行により発生します。
    ディバグ・トラップ,ディバグ・ブレークが発生した場合,CPU は次の処理を行いディバグ・モニタ・ルーチンへ制御を移し,ディバグ・モードに移行します。


    RH850の他の興味深い点の、トレースデータ出力ポートにデータを出力する命令、に関しては以下に記載があります。

    top > RH850 > デバッグ・ツール編 > 機能 > 実行履歴の収集 > デバッグ命令を埋め込んで情報を出力する
    2.14.10 デバッグ命令を埋め込んで情報を出力する
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V8.09.00/CS+.chm/DebugTool-RH850.chm/Output/db_kinou_func28.html
     

  • こんにちは。NoMaYです。

    ちょっと脱線しますけれども、RXマイコンもRH850マイコンのように、トレースデータ出力ポートにデータを出力する、もしくは、内蔵トレースメモリにデータを蓄積する、といったことが可能です。他方では、RH850マイコンとは違ってRXマイコンでは、そのような機能が命令セットレベルで用意されているというわけでは無く一般的なデータクオリファイトレース機能を頓知的に使って同様なことをすることになります。以前にやってみたことは以下に投稿していました。(なお、e2 studioの不具合と思われる挙動にかなり振り回されていましたので、話が分かり難くなっていたりします。)

    FIT R_SCI_RXモジュールでprintfをfrom inside interrupt routine内から行えるかどうか考えてみるスレッド
    community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/9610/fit-r_sci_rx-printf-from-inside-interrupt-routine/47583#47583

    昔(大昔?)はちょっと触ってもまともには動いていない感じがして、トレース機能を必要とするようなデバッグはCS+に移ってやるようにしていたので、今までは気付きませんでした。(今回、GNURXを使う案件で、自分以外の人が使うかも知れない案件があったので、たまたま試してみて、ようやく気付きました。)

    community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/9610/fit-r_sci_rx-printf-from-inside-interrupt-routine/47588#47588

    脱線ついでのその4ですけれども、先ほどの件でemWin(及び関連ドライバ)が動き出すところより前の筈のところでやってみても再現するのであれば、(リンクサイズ制限の事情で)emWinを外してCC-RXでビルドしたら再現するのか試してみました。結果は、e2 studioでは再現しましたが、同じabsファイルでもCS+では再現しませんでしたね。

    community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/9610/fit-r_sci_rx-printf-from-inside-interrupt-routine/47596#47596

    脱線ついでのその6ですけれども、e2 studioでトレースデータの時間表示のモードを差分表示から積算表示にしてみたところ、期待値と異なる値が表示されている箇所はトレース機能の時間カウンタがラップアラウンドする箇所っぽいです。どうも時間カウンタは20ビット幅ではないかと推測されるのですが、そうだと仮定して手元で手計算してみると、以下の通り、期待値と同じ値が得られました。私はe2 studioの計算ミス不具合のような気がします。