ST-Link Part 1

Nov. 21, 2020

Yesterday, my ST-Link v2 programmers arrived. These cheap Banggood clones come in at less than $5 per programmer, so I bought a few to use with my ARM development. I wanted to replace my Segger J-Link Mini EDU (which I got as part of an educational kit) with something less restrictive, so I can run OpenOCD and FOSS other development tools. I read online that you can even flash the Black Magic Probe firmware on them, which I plan to try - but that’s a topic for my next article. (For those who don’t know, BMP is an open debug firmware that is very flexible and powerful, most notibly because it runs an OpenOCD server on the debug probe itself - so you don’t have to run that on your development machine).

Taking a look at the programmers, they have a USB port on one side, and dupont headers on the other, for wiring up to the JTAG or SWD on the ARM development board. Having these as dupont headers rather than a JTAG port is convenient, as the STM32 Black Pill board I use for most of my development only has dupont SWD headers, and it saves having to use an expansion board to expand the JTAG port to dupont.

Anyway, I plugged the programmer into my desktop and ran lsusb:

$ lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
...
*Bus 001 Device 027: ID 0483:3748 STMicroelectronics ST-LINK/V2*

Okay, so far so good. At least the board is recognized. Now, we can try wiring it up to the development board. In my case, with the black pill, it was just a matter of using the provided dupont cables to wire up the 4 pin SWD interface on the Black Pill (SWCLK, SWDIO, 3V3, GND) to the respective pins on the programmer. Plugging the programmer back into USB, the development board should power up.

Now, let’s program something on the board. I’m using a simple Hello-World blink program written with libopencm3. You can find it here. To interface with the programmer, I’m using stlink, which is an “Open source version of the STMicroelectronics STlink Tools”. On Arch Linux it is available in the official community repository as stlink, depending on what OS you are using installation may be different.

$ cd /path/to/libopencm3-pio-hello-world
$ st-flash --reset write .pio/build/blackpill_f401ce/firmware.bin 0x08000000
2020-11-21T17:59:11 INFO common.c: F4xx (Dynamic Efficency): 96 KiB SRAM, 512 KiB flash in at least 16 KiB pages.
file .pio/build/blackpill_f401ce/firmware.bin md5 checksum: d63713a817a4ba280404974a6111883, stlink checksum: 0x000240f3
2020-11-21T17:59:11 INFO common.c: Attempting to write 1840 (0x730) bytes to stm32 address: 134217728 (0x8000000)
EraseFlash - Sector:0x0 Size:0x4000 2020-11-21T17:59:12 INFO common.c: Flash page at addr: 0x08000000 erased
2020-11-21T17:59:12 INFO common.c: Finished erasing 1 pages of 16384 (0x4000) bytes
2020-11-21T17:59:12 INFO common.c: Starting Flash write for F2/F4/L4
2020-11-21T17:59:12 INFO flash_loader.c: Successfully loaded flash loader in sram
enabling 32-bit flash writes
size: 1840
2020-11-21T17:59:12 INFO common.c: Starting verification of write complete
2020-11-21T17:59:12 INFO common.c: Flash written and verified! jolly good!
$

Well, that actually went pretty smoothly. There are a lot of other things you can do with the st-link tool, including debugging. I’m not going into go into detail on everything that can be done, since my goal is to move on to using OpenOCD next. However, let’s try out GDB functionality.

$ # Start the st-link GDB server
$ st-link
st-util
2020-11-21T18:04:42 INFO common.c: F4xx (Dynamic Efficency): 96 KiB SRAM, 512 KiB flash in at least 16 KiB pages.
2020-11-21T18:04:42 INFO gdb-server.c: Listening at *:4242...
$ # In another terminal, run arm-none-eabi-gdb and connect to the GDB server
$ arm-none-eabi-gdb .pio/build/blackpill_f401ce/firmware.elf
...
Reading symbols from .pio/build/blackpill_f401ce/firmware.elf...
(gdb) target extended localhost:4242

Then you can use regular GDB commands to debug. I believe the ST-Link hardware has 6 hardware breakpoints, which is something to keep in mind. (Although I am yet to come across a point where I need more than 6 breakpoints anyway).