OpenOCD with Raspberry Pi as a Programmer

OpenOCD with Raspberry Pi as a Programmer

While we are on the topic of how to program the STM in different ways, we might as well show you how to replace the ST-Link (or a cheap Chinese knock-off) with the Raspberry Pi. Who does not have a Raspberry Pi Single-board Computer (SBC) around these days?

OpenOCD (Open On-Chip Debugger) let’s you transport your knowledge and debugging skills from one target to another, without having a bunch of software for specific applications — not even mentioning their bundled application for gdb and so on… it is a suite, offering a telnet, gdb server, OpenOCD server connections while allowing you to just use the command line.

Raspberry Pi as a native Programmer

  • Objective: Program an ST-Microcontroller with a Raspberry Pi
  • Requirements:
    • ST-Microcontroller or similar
    • Raspberry Pi SBC

We are first going to talk a little bit about how OpenOCD works, then present our case study and use the OpenOCD with Raspberry Pi in two different ways: via GPIO and through SPI. Additionally we will tell you what you need to configure to install OpenOCD from source.

Basic OpenOCD knowledge

OpenOCD basically works like this:

  • You specify the dongle that you are using: ST-Link, JLINK, or, in our case, a Raspberry Pi SBC.
  • You specify the target (ie. microcontroller) that you want to program.
  • You may need to specify some extra options: eg. some dongles offers more thanone way to program.

The specification is via OpenOCD tcl commands¹. These commands can be given via:

  • a .cfg script; or/and
  • the -c command line option; or/and
  • the OpenOCD server; or/and
  • gdb connection with the monitor command; or/and
  • via a telnet connection.

The program and the community² already wrote .cfg scripts for almost all commercial targets and dongles, you just have to provide the script name through the command line with the -f option. Moreover, if the script is lacking, you may always copy and modify it to your needs — like we are doing today.

Programming with OpenOCD and Raspberry Pi (GPIO)

Although you can use a multitude of dongles, targets, our case study will be focusing in the following hardware:

  • Target: Nucleo-L452RE, containing a STM32L452RE microcontroller³
  • Raspberry Pi model 3B+

Setting up

We need the OpenOCD executable, some people like to compile it from source, but the aptitude package is sufficient for our case:

apt install openocd

In the /usr/share/openocd/scripts/ folder you can mainly see:

  • interface/: dongle files: ST-Link, ULINK, JTAG… and our Raspberry Pi!
  • target/: microcontrollers, stm32l4x.cfg in our case
  • board/: development board files, combination of interface/ and target/

Take a look at board/stm32l4discovery.cfg to see what I mean:

# tcl
# SPDX-License-Identifier: GPL-2.0-or-later

# Explicity for the STM32L476 discovery board:
# but perfectly for any other STM32L4 board connected via
# an stlink-v2-1 interface.
# This is for STM32L4 boards are connected via stlink-v2-1.

source [find interface/stlink.cfg]

transport select hla_swd

source [find target/stm32l4x.cfg]

reset_config srst_only

As you can see, the interface is an ST-Link programmer and the target is a STM32L4 microcontroller, this is basically the definition of our development board. If you want to go further and see what option each command has, just type in openocd -c "help <command>", or search on the user guide.

OpenOCD already has scripts for the Raspberry Pi, located at /usr/share/openocd/scripts/. Our job is then to connect the GPIOs, target and „additional stuff“ properly. Opening up the raspberrypi-native.cfg we see, for the SWD interface:

  • NRST = GPIO-18 (header pin 12)4
  • SWDIO = GPIO-25 (header pin 22)
  • SWCLK = GPIO-11 (header pin 23)
Raspberry Pi with ST NUCLEO board
Raspberry Pi with ST NUCLEO board (© nubix 2023)

This is the file that we want. Putting this file with our target together:

# File rpi-openocd.cfg
# Author Vinícius Gabriel Linden
# Date 2022-10-12
# Copyright nubix Software-Design GmbH
# Brief Raspberry Pi 3B+ for STM32L452RE OpenOCD specification

source [find interface/raspberrypi-native.cfg]
transport select swd
source [find target/stm32l4x.cfg]

proc write { file } {
    # program file for STM32L452RE
    program $file 0x08000000 verify reset exit

init; # we need to initialize device in order to halt it
targets; # display target information

Note the transport select swd, telling OpenOCD/Raspberry Pi to use SWD instead of JTAG. Now we can finally run:

openocd -f rpi-openocd.cfg # simply create a tcl, telnet and gdb server
openocd -f rpi-openocd.cfg -c "write <file>.bin" # program with <file>.bin


We are testing with our very simple program from our last blog post, which just spits out the compilation time via UART. As you can see, it works without a problem:
OpenOCD output (© nubix 2023)

We can also use gdb to debug the target:

OpenOCD – debugging with gdb (© nubix 2023)

Compiling OpenOCD on Raspberry Pi: GPIO

apt install libtool libusb
git clone openocd
cd openocd
./configure --enable-sysfsgpio --enable-bcm2835gpio

The last option would be better named --enable-raspberrypi because it is not specific for BCM2835 (not even for the Raspberry Pi itself). The --enable-sysfsgpio option allows OpenOCD to use the sysfs file system for GPIO access. Specify it if you want to use the slower sysfs option, otherwise you may compile it without. Try using sysgpio-raspberrypi.cfg for that. Continuing with the usual…

make && sudo make install

Compiling OpenOCD takes a while, because it is a big project. When compiling from source, tcl ar located at /usr/local/share/openocd/scripts/ by default.

Programming with OpenOCD and Raspberry Pi: SPI

You can also use the Raspberry Pi’s SPI interface for programming. SPI is much faster than regular GPIO, because of the dedicated hardware behind the pins and because the SPI kernel module. To use the SPI for programming, you have to compile it from source:

git clone
cd openocd-spi
./configure --enable-bcm2835spi
make && sudo make install

Note the --enable-bcm2835spi instead of --enable-bcm2835gpio. The OpenOCD script is very similar to the previous one.

# File rpi-openocd-spi.cfg
# Author Vinícius Gabriel Linden
# Date 2022-10-12
# Copyright nubix Software-Design GmbH
# Brief Raspberry Pi 3B+ for STM32L452RE OpenOCD specification

interface bcm2835spi
bcm2835spi_speed 31200
source [find target/stm32l4x.cfg]

proc write { file } {
    # program file for STM32L452RE
    program $file 0x08000000 verify reset exit

init; # we need to initialize device in order to halt it
targets; # display target information

You have to enable SPI for this script to work, but you don’t have to install libtool and libusb like we previously did. You also habe to change the pins to the SPI ones:

  • NRST is not connected
  • SWDIO = GPIO-10 (header pin 19)
  • SWCLK = GPIO-11 (header pin 23)

Note that the only difference in this script the interface specification — the rest remains the same. Using the same test program:

OpenOCD-SPI output BCM2835 SPI SWD driver (© nubix, 2023)

We may equally use gdb with this configuration:

Debugging with gdb through SPI (© nubix, 2023)

Note on compiling OpenOCD-SPI from source

With commit hash 63b60de38d0e86d18bc013a39c8d72e9f4dbf068 and GCC 10, I had to edit the Makefile to include the

# Makefile
CFLAGS = -g -02 -Wno-maybe-uninitialized


¹ You can think of OpenOCD an an extension of Jim-Tcl.

² OpenOCD, like the name suggests, is open source and has a helpful community behind it.

³ To bypass the integrated ST-Link, remove SB2 and SB12. SWDIO is available at PA13; while SWCLK at PA14. Remember to power the device on the 3V3 pin directly. Don’t forget the ground connection!

4 Reset is necessary because stm32l4x.cfg file requires it. Otherwise it will program but throw an error on reset.

5 GCC10 was not recognizing the pointer logic (optimizer).


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert