GDB、OpenOCD、arm-none-eabi-gccを使用して、STM32ディスカバリーボードでgdbコンソールにデバッグメッセージを出力するにはどうすればよいですか?


15

OpenOCD、arm-none-eabi-gcc、およびgdbを使用してSTM32 Cortex M0ディスカバリーボード(32F0308DISCOVERY)をプログラミングしています。SWD経由でデバッグメッセージを記録する簡単な方法があるかどうか疑問に思っていました。セミホスティングオプションについて読んだことがありますが、これにはnewlibまたは他の大きなライブラリを取り込む必要があるようです。(64kフラッシュしか利用できません。)SWDを介してテキストを記録するためのより軽量な方法はありますか、またはUARTのみが実用的なオプションですか?


1
セミホスティングオプションを試すことをお勧めします。目安として、M3 / 4用のCooCox(無料のWindows Cortex-M環境)が提供するライブラリは非常にシンプルで、シングルバイト転送は17アセンブリ命令です。セミホスティングと-O0を使用した古い(STM32F4)プロジェクトの再構築により、コードサイズに48バイトが追加されました。
マルクト

リンカで未使用のコードを削除することはできません。代替手段として、stlinkツールを駆動するためのtexaneのgithubリポジトリには、シンプルなメールボックススキームがありますが、まだ試していません。
クリスストラットン

回答:


15

ポインター、マルクト、クリス・ストラットンに感謝します。セミホスティングオプションは非常に簡単であることが判明しました。OpenOCDコンソールにメッセージを送信できるいくつかの簡単なロギングルーチンのソースを見つけることができました。(i)動作させるために何らかの修正が必要であり、(ii)始めたばかりの人にとってこの情報を見つけるのはそれほど簡単ではないと思うので、ここに投稿します。

まず、ここでのDコードは、次のC関数を提供するように簡単に適合されます。

void send_command(int command, void *message)
{
   asm("mov r0, %[cmd];"
       "mov r1, %[msg];"
       "bkpt #0xAB"
         :
         : [cmd] "r" (command), [msg] "r" (message)
         : "r0", "r1", "memory");
}

send_commandを呼び出してOpenOCDコンソールに文字列を書き込む例:

const char s[] = "Hello world\n";
uint32_t m[] = { 2/*stderr*/, (uint32_t)s, sizeof(s)/sizeof(char) - 1 };
send_command(0x05/* some interrupt ID */, m);

2番目に、ここのコメント指定されたputChar関数は正常に機能しますが、0x03の前に「#」を追加する必要がありました。

void put_char(char c)
{
    asm (
    "mov r0, #0x03\n"   /* SYS_WRITEC */
    "mov r1, %[msg]\n"
    "bkpt #0xAB\n"
    :
    : [msg] "r" (&c)
    : "r0", "r1"
    );
}

これらの関数の出力を確認するには、まずOpenOCDを起動してから、次のようにarm-none-eabi-gdbを使用して接続します。

target remote localhost:3333
monitor arm semihosting enable
monitor reset halt
load code.elf
continue

メッセージは、GDBコンソールではなく、OpenOCDプロセスの標準出力に表示されることに注意してください。


1
バグがあります。sizeof()はstrlen()でなければなりません。

1
ユーザー107642に感謝します。実際、 's'がポインターではなく配列の場合、ここでsizeofを使用することができます。そのため、そのように変更しました。
foldl

素晴らしい答えです!次のようputcharに簡単に書くこともできますvoid putchar(char c) { send_command(3,&c); }
mvds

1
「sizeof」は文字列の末尾の\ 0をカウントしますが、strlenはカウントしません。openocdがstdoutとxtermターミナルウィンドウに出力するだけの場合、ターミナルはおそらく無視するため、顕著な違いはおそらくないでしょう。しかし、ファイルに何かを入れることになった場合、それらのゼロがそこにあることに驚くと思います。または、プロトコルは、末尾のターミネータで文字列を送信する必要があることを指定していますか?
user242579

ああ、良い点user242579。末尾の\ 0を考慮するために「-1」を追加しました。
foldl
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.