I’m currently working on an STM32 port of some networking software and to make things easier I have the STM32 board wired into a core switch away from the laptop I develop on. I’ve setup remote programming and debugging for this board and this is how I did it.

Hardware Setup

The board I’m using here is an EasyMX Pro v7 with an STM32F407 MPU mezzanine board. But I’ve done this with Nucleo board too.

I’ve connected the onboard STLINK (called “mikroProg” on this board) to a Linux server I have next to the network switch and also the USB UART to that machine to capture printf() output.

Software Setup

On the server you need two things, first of all a tool called OpenOCD to talk to the STLINK, my server is running Ubuntu so this is just a simple case of sudo apt install openocd. You also need the GNU Arm toolchain installed for the debugging. This is the “Linux x86_64 Tarball” available from https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads. I’ve extracted this to ~/stm32/ on my server.

Next up you need copy a few configuration scripts to wherever you want to program from on the Linux server. My board has STLINK v2 so:

cp /usr/share/openocd/scripts/interface/stlink-v2.cfg .

Note that v2 and v2.1 are distinct versions and there is an interface file for each. My Nucleo boards use v2.1.

Now you need a target file, there is one for pretty much every STM MPU type, for my F407:

cp /usr/share/openocd/scripts/target/stm32f4x.cfg .

Finally you need to create a config file that ties the two together, there are a few canned ones in the /usr/share/openocd/scripts/boards/ directory, but it is easy to write one. I created east_mx_f4.cfg as follows:

source [find stlink-v2.cfg]

transport select hla_swd

source [find stm32f4x.cfg]

reset_config srst_only

Programming

Whenever I want to flash some new firmware I compile it on my laptop, use scp to copy the .elf file to my server, then on the server run:

sudo openocd -f easy_mx_f4.cfg -c "program myprog.elf verify reset exit"

The output will look a little like this:

Debugging

To debug we need two terminal windows. The first to run OpenOCD, which creates a TCP port for GDB to connect to. I could also open this port up so my laptop can remotely attach GDB to it. But for now both are running from the server. To start the OpenOCD side:

sudo openocd -f easy_mx_f4.cfg

This will sit waiting for you and has opened port 3333. You can now run the debugger in another terminal:

~/stm32/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gdb ~/prog/myprog.elf

And you can attach this to the STM32 by typing this into the GDB console:

target remote localhost:3333

Then hit c to continue execution. Here is the output of me doing that, breaking execution and running a backtrace:

When you quit GDB it will detach from the STM32 hardware and you can use Ctrl-C to end the OpenOCD session in your other terminal. This can all be scripted as needed and remote debugging can be a very powerful tool.