みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

STM32F103 minimum(BluePill)上のNuttXをOpenOCD(とブラウザ)でデバッグ

BluePill + NuttXの続き。

OpenOCDでデバッグ

フラッシュを128K使うために、OpenOCDを使用してイメージを書き込んだ。 せっかくOpenOCDを使用しているのでデバッグもできるはず。

デバッグ用のイメージを作成するとnuttx.binのサイズが最低でも70K程度になってしまうので、128Kの環境をベースに作業する。

コンフィギュレーション

ベースの環境はNSHで作業する。

$ cd nuttx
$ tools/configure.sh -l configs/stm32f103-minimum/nsh

メニューコンフィグ

make menuconfigで次の項目を有効化する。

CONFIG_DEBUG_NOOPT

Build Setup
  -> Optimization Level
    -> Suppress Optimization

CONFIG_DEBUG_SYMBOLS

Build Setup
  -> Debug Options
    -> Generate Debug Symbols

GDBでイメージを書き込む

前にOpenOCDでイメージを書き込んだ時は、telnetでOpenOCDに接続したが、 実はGDBでもイメージの書き込みを行なうことができる。

$ openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2.cfg -f /usr/local/share/openocd/scripts/target/stm32f103c8t6.cfg

別のシェルを開き、nuttx.binがあるディレクトリで次のコマンドを実行する。

$ arm-none-eabi-gdb nuttx

これで次のようにgdbのプロンプトが出てくる。

...(snip)...

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nuttx...
(gdb)

この状態で次のコマンドを実行する。

(gdb) target remote localhost:3333

これでGDBがOpenOCDと接続されターゲットを操作できるようになる。つまりターゲットと接続される。

(gdb) mon reset halt
(gdb) mon flash write_image erase /home/mickey/work/nuttx/nuttx/nuttx.bin 0x08000000
(gdb) mon reset run
(gdb) quit

やっていることはtelnetでしたことと全く同じ。 localhostの3333ポートに接続して、イメージを書き込むだけ。

gdbではmon(monitor)コマンドを使う必要があるが、それ以降の構文は全く同じ。

mon reset runのあとで、シリアルコンソールでnshが問題なく動作すればOK

ここの例では書き込み後、一度GDBを終了しているが継続して作業することもできる。

デバッグ開始

GDBが実行されていない状態からの手順を示す。

書き込みの時と同様に、OpenOCDが実行中のものとは違うシェルでGDBを起動する。

$ arm-none-eabi-gdb nuttx

ターゲットと接続後、実行中のプログラムを停止し、プログラムをロードする。

(gdb) target remote localhost:3333
(gdb) mon reset halt
(gdb) load

この状態からステップやブレークなどのデバッグが可能となる。

初期化ファイル

GDB起動からloadまでのコマンドは毎回同じなので手動で実行するのは手間となる。

初期化ファイルを作成し自動的に実行されるようにする。

nuttx.gdbinitを次の内容で作成する。

target remote localhost:3333
mon reset halt
load

GDBを起動するときに指定する。

$ arm-none-eabi-gdb  nuttx -x nuttx.gdbinit

gdbgui

gdbguiというプログラムを使用すると、ブラウザ上のGUIデバッグすることができる。

インストール

pipコマンドでインストールする。

$ sudo pip install gdbgui --upgrade

gdbguiの起動

次のコマンドでgdbguiをarm-none-eabi-gdbのフロントエンドとして起動する。

$ gdbgui -g arm-none-eabi-gdb 

ブラウザ上にデバッグ画面が表示され、デバッグ可能となる。

初期化ファイルの指定

gdbguiで初期化ファイルを指定する場合は次のようにする。

$ gdbgui -g arm-none-eabi-gdb --gdb-args "-x nuttx.gdbinit" nuttx

GUIで直感的にデバッグができるのですごく便利。

f:id:mickey_happygolucky:20190130221244p:plain
gdbguiの実行画面