
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 caseboard/
: development board files, combination ofinterface/
andtarget/
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: # http://www.st.com/web/en/catalog/tools/PF261635 # 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)

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 halt 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
Results

We can also use gdb to debug the target:

Compiling OpenOCD on Raspberry Pi: GPIO
apt install libtool libusb git clone https://git.code.sf.net/p/openocd/code openocd cd openocd ./bootstrap ./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 https://github.com/lupyuen/openocd-spi cd openocd-spi ./bootstrap ./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 halt 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:

We may equally use gdb with this configuration:

Note on compiling OpenOCD-SPI from source
With commit hash 63b60de38d0e86d18bc013a39c8d72e9f4dbf068
and GCC 10, I had to edit the Makefile
to include the
-Wno-maybe-uninitialized
5.
# Makefile CFLAGS = -g -02 -Wno-maybe-uninitialized
Remarks
¹ 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).