* nucleo で gdb デバッグ [#kfe13307]

STmicro の STM32 マイコン基板の nucleo F401RE で gdb を使ってリモートデバッグすることができました.

#af_amazon(B00RCALR58)

** 環境 [#bd458e39]

:SDK|mbed もしくは STM32CubeMX
:ターゲットボード|nucleo F401RE
:PC|debian streatch (testing)
:openocd|0.9.0

** 構成 [#z90b5a1f]

nucleo の USB ポートには
- ファームウェア書き込み用の USB ストレージデバイス
- シリアルデバイス
- STLink V2-1 のデバッグインターフェース

が出ています.

この STLink V2-1 プロトコルのデバッグインターフェースのエンドポイントに openocd で接続し,TCP/IP ソケットで gdb に接続します.
図にするとこんな感じかな.

 nucleo <--(USB)--> openocd <--(TCP/IP)--> gdb

** 手順 [#q3dc6bd1]

*** ファームウェアのビルド [#t4b242e6]

mbed の場合は,オンライン IDE からソースコードをダウンロードして,ローカルでビルドします.
でないと,ソースコードツリーとデバッグシンボル付きの elf ファイルが手元に無いので,ソースコードレベルでのデバッグができません.

STM32CubeMX の場合は,ピン設定の画面で SYS - Debug で SWD を有効にし,ファームウェアバイナリをビルドします.

*** ファームウェアの書き込み [#tcebf9b4]

nucleo のマスストレージデバイスに,ファームウェアバイナリファイルを書き込みます.

*** openocd の起動 [#p995d3a9]

Linux PC 上のターミナルエミュレータ上で openocd を起動します.

 $ openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfgOpen On-Chip Debugger 0.9.0 (2015-05-28-17:08)
 $ openocd -f /usr/share/openocd/scripts/board/st_nucleo_f4.cfg
 Open On-Chip Debugger 0.9.0 (2015-05-28-17:08)
 Licensed under GNU GPL v2
 For bug reports, read
 	http://openocd.org/doc/doxygen/bugs.html
 Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
 adapter speed: 2000 kHz
 adapter_nsrst_delay: 100
 none separate
 srst_only separate srst_nogate srst_open_drain connect_deassert_srst
 Info : Unable to match requested speed 2000 kHz, using 1800 kHz
 Info : Unable to match requested speed 2000 kHz, using 1800 kHz
 Info : clock speed 1800 kHz
 Info : STLINK v2 JTAG v24 API v2 SWIM v11 VID 0x0483 PID 0x374B
 Info : using stlink api v2
 Info : Target voltage: 3.254104
 Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints

ここで nucleo 基板の LD1 LED (USB コネクタの横)が赤緑に交互に点滅します.

 gdb_port 3333

と入力し,TCP ポート 3333 番で gdb の接続を待つよう指示します.

*** gdb の起動 [#ad883fad]

Linux PC 上で別のターミナルエミュレータを開き,ソースコードツリーのトップに移動します.
STM32CubeMX の場合は
 $ arm-none-eabi-gdb main.out

と,elf ファイルを指定して gdb を起動します.

mbed の場合は
 $ arm-none-eabi-gdb foo.elf    # foo の部分はプロジェクト名

ですね.

gdb が起動したら

 (gdb) target remote localhost:3333

で待ち合わせていたポートを指定し,openocd と接続します.

あとは,こんな感じでリモートデバッグすることができます.

 $ arm-none-eabi-gdb mbed_blinky.elf 
 GNU gdb (7.10-1+9) 7.10
 Copyright (C) 2015 Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
 and "show warranty" for details.
 This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
 Type "show configuration" for configuration details.
 For bug reporting instructions, please see:
 <http://www.gnu.org/software/gdb/bugs/>.
 Find the GDB manual and other documentation resources online at:
 <http://www.gnu.org/software/gdb/documentation/>.
 For help, type "help".
 Type "apropos word" to search for commands related to "word"...
 Reading symbols from mbed_blinky.elf...done.
 (gdb) target remote localhost:3333
 Remote debugging using localhost:3333
 0x00000000 in ?? ()
 (gdb) c
 Continuing.
 WARNING! The target is already running. All changes GDB did to registers will be
  discarded! Waiting for target to halt.
 ^C
 Program received signal SIGINT, Interrupt.
 0x080019e6 in us_ticker_read ()
 (gdb) up
 #1  0x08001756 in wait_us ()
 (gdb) up
 #2  0x080002be in main () at main.cpp:10
 10	        wait(0.2);
 (gdb) n
 Single stepping until exit from function us_ticker_read,
 which has no line number information.
 0x08001756 in wait_us ()
 (gdb) n
 Single stepping until exit from function wait_us,
 which has no line number information.
 main () at main.cpp:5
 5	int main() {
 (gdb) 
 7	        myled = 1;
 (gdb) 
 8	        wait(0.4);
 (gdb) 
 7	        myled = 1;
 (gdb) 
 8	        wait(0.4);
 (gdb) 
 Note: automatically using hardware breakpoints for read-only addresses.
 9	        myled = 0;
 (gdb) 
 10	        wait(0.2);
 (gdb) 
 9	        myled = 0;
 (gdb) 

*** 注意 [#rf237185]

STM32 の場合,フラッシュ ROM 上のプログラムを CPU が直接フェッチして実行しているので,ブレークポイントはハードウェアブレークポイントを使用することになります.
ハードウェアブレークポイントの数には限りがあるので,調子に乗ってあちこちにブレークポイントを設定すると,数が足りなくなるかもしれません.



トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS