Sunday, February 18, 2018

Debugging with GDB on an mbed STM32 Nucleo

Having a real debugger is incredibly useful, and it turns out it's not too hard to get GDB working on the STM32 Nucleo development boards with Linux. It's also a nice and very fast way to load code onto the Nucleo with no internet connection required.  Here's what I did to get debugging working on my Nucleo.

First, we need to install the compiler, debugger, openOCD, and make:

sudo apt install make gdb-arm-none-eabi gcc-arm-none-eabi openocd

To get the makefile and mbed libraries, I created a new project on the mbed compiler website, right clicked on the project in the tree on the left, and exported the project as "Make_gcc_arm", and unzipped the file.

Next, we need to retrieve the configuration files for the board and its interface.  On my computer, the openOCD script files were stored in /usr/share/openocd/scripts.  The file for the ST-Link is interface/stlink-v2-1.cfg, and the file for the micro itself is board/st_nucleo_f4.cfg.  I copied these two files to my project folder.

The default Makefile doesn't turn on debugging symbols, so it needs to be modified.  In the "Tools and Flags" section of the makefile, I added a '-g' flag after 'arm-none-eabi-gcc' for CC and CPP.  I ran make, which complained about clock-skew, but produced a BUILD folder with bin, elf, hex, and .o files. 

Next, we need to set up the connection between the ST-Link and the computer.  This is done with openOCD (on-chip-debugger).   OpenOCD must be started in the folder where you've copied the .cfg files for the ST-Link and the board.  To start the program, run

sudo openocd -f st_nucleo_f4.cfg -f stlink-v2-1.cfg -c init -c "reset init"

There may be an "already specified hl_layout stlink" error, but this shouldn't cause a problem.  You should see near the end of the output "target state: halted", the 3.3V supply voltage, and a few of the CPU registers.

Next, we need to run gdb with `arm-none-aebi-gdb`.  You should do this in the project folder - the one which has the BUILD folder in it.  To connect to OpenOCD, run `target remote localhost:3333`.  Next, we need to tell gdb which program we are trying to debug by running `file BUILD/project_name.elf`.  It may warn you that there is a program being debugged already, but you should press 'y' to force gdb to load the debugging symbols for the most recent build.  

The next step is to get the microcontroller ready to receive the program.  Sometimes you can get away with skipping these steps.  Run 'monitor reset' then 'monitor halt' to put the micro in a good state.  

Now we can load the firmware onto the microcontroller by running 'load'.  If at any point you change the source, all you need to do is run make, then run 'load' from gdb.  If the nucleo goes into a bad state, you can reset it with the 'monitor reset' command in gdb.

To start running the program, run 'continue'.  Surprisingly, almost every feature of GDB actually works in this setup.  I can view and modify local variables, arguments, and globals, can view registers, can use the hardware breakpoints and watchpoints of the microcontroller, and can pull up the source code for some of the mbed libraries as well.

1 comment:

  1. It is also possible to use Segger firmware with STM boards, see I generally love Segger stuff because it is solid and fast.