Using nemiver for remote debugging on ARM microcontrollers

This is just a tip for those of you who also think Eclipse is too fat and slow and want to use another editor, but need a proper debugger. You may want to try Nemiver.

You will need an ARM bare metal cross-compiler, some time ago I’ve written a small HOWTO to compile one yourself and a German Tutorial to get started with STM32 development on Linux.

Go to your program that you want to debug, compile it and flash it to the chip:

[chris@thinkpad usart]$ make clean
[chris@thinkpad usart]$ make
[chris@thinkpad usart]$ make flash
  FLASH   usart.hex
[chris@thinkpad usart]$

In another terminal run openocd -f debug.cfg to start a gdb server.

[chris@thinkpad usart]$ openocd -f debug.cfg
Open On-Chip Debugger 0.6.0-dev-00425-g631b80f-dirty (2012-02-24-13:22)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
1000 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
cortex_m3 reset_config sysresetreq
Info : clock speed 1000 kHz
Info : JTAG tap: stm32f1x.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
Info : JTAG tap: stm32f1x.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints

My debug.cfg looks like this:

#daemon configuration
telnet_port 4444
gdb_port 3333
source [find interface/olimex-jtag-tiny.cfg]
source [find target/stm32f1x.cfg]

Now in the first terminal run:

[chris@thinkpad usart]$ arm-none-eabi-gdb --batch --command=run.gdb usart.elf
0x00000000 in ?? ()
requesting target halt and executing a soft reset
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08000324 msp: 0x20005000
Hardware assisted breakpoint 1 at 0x8000284: file usart.c, line 96.
Temporary breakpoint 1, main () at usart.c:96
96      {
[chris@thinkpad usart]$

run.gdb looks like:

target remote localhost:3333
monitor soft_reset_halt
thbreak main
continue

Now we can run Nemiver:

[chris@thinkpad usart]$ nemiver --remote=localhost:3333 --gdb-binary=/home/chris/tools/summon-arm-toolchain/bin/arm-none-eabi-gdb usart.elf

And the obligatory screenshot:

Screenshot Settings

I’ve put everything in a bash script, so everything I have to do to flash the chip and start a new debug session is to to run debug.sh:

#!/bin/bash
make
make flash
xterm -e openocd -f debug.cfg &
sleep 2
arm-none-eabi-gdb --batch --command=run.gdb usart.elf
nemiver --remote=localhost:3333 --gdb-binary=/home/chris/tools/summon-arm-toolchain/bin/arm-none-eabi-gdb usart.elf
Screenshot Settings

Update 2012-08-14: Here is a newer version, which is integrated in the microcli-stm32f0-discovery Makefile:

#!/bin/bash

# location of OpenOCD Board .cfg files
OPENOCD_BOARD_DIR=/usr/share/openocd/scripts/board

# start xterm with openocd in the background
xterm -e openocd -f $OPENOCD_BOARD_DIR/stm32f0discovery.cfg -f extra/stm32f0-openocd.cfg -f extra/debug.cfg &

# save the PID of the background process
XTERM_PID=$!

# wait a bit to be sure the hardware is ready
sleep 2

# execute some initialisation commands via gdb
arm-none-eabi-gdb --batch --command=extra/run.gdb main.elf

# start the gdb gui
nemiver --remote=localhost:3333 --gdb-binary="$(which arm-none-eabi-gdb)" main.elf

# close xterm when the user has exited nemiver
kill $XTERM_PID