Using OpenOCD + RPI Pico + RTT with a STM32

Since I discovered about Segger Real Time Transfer (RTT) years ago I became a fan of it, it has almost no down-points and delivers a fast and resourceful way to interact with the firmware, I’ve been using it at work for years and have nothing but love for it.

Now, after many years, OpenOCD has finally integrated RTT support on its latest version (V0.11.0), allowing us to use RTT with any supported HW interface and independent from any Segger HW or PC SW, this is really exciting and I decided to give it a try, here I describe my experience.

RTT test firmware and target

First, to be able to test it, I created a simple STM32 FW using STM32Cube and included the Segger RTT library, here is the relevant code:

while (1)
  {
	  static int counter = 0;
	  
	  HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin);
	  SEGGER_RTT_printf(0, "RTT counter: %d\n",counter++);
	  HAL_Delay(500);

  }

Then I flashed it on a Nucleo Board (NUCLEO-G071RB), that will be used for testing.

Using it with a ST-Link

I started making it work with Nucleo’s embedded ST-Link, how I am on Linux and the apt repository is still on the old version, I started by compiling and installing OpenOCD V0.11.0 on my machine:

First I solved some dependencies listed on the official documentation and then compiled and installed it with the following sequence of commands:

git clone https://github.com/ntfreak/openocd
cd openocd/
git checkout v0.11.0
./bootstrap
./configure
make
sudo make install

Then I spent some time reading the documentation and created the following config file:

source [find interface/stlink-v2.cfg]
source [find target/stm32g0x.cfg]
init
rtt setup 0x20000000 36684 "SEGGER RTT"
rtt start
rtt server start 9000 0

This config file sets the ST-Link as interface, the STM32G0 as target, and also:

  • Setup the RTT block search to be conducted starting from address 0x20000000 (STM32’s start of SRAM), for 36K bytes (SRAM size), and searching for the “SEGGER RTT” block ID, which is the default ID used by Segger’s library.
  • Start the RTT search
  • Start the RTT TCP server for RTT channel 0 (default one) on local port 9000

Then I started openOCD with the config file:

openocd -f stlink_rtt.cfg

As shown, it found the RTT control block on address 0x200004d0, so we are good, now we should be able to capture RTT packets on the local TCP port, using, for example, netcat:

nc localhost 9000

Bingo, we have RTT using a ST-Link as interface!

Using a Raspberry Pi Pico as CMSIS-DAP SWD interface

After having success using the ST-Link I decided to try using a Rpi Pico as interface, as I saw on Pico’s documentation that they have an official firmware for it, named “Picoprobe”, but after some reading I learned that they implemented their own interface protocol and therefore it requires to use their own OpenOCD’s fork, unfortunately this fork is based on V0.10 and does not support RTT.

Then, searching a bit more, I found that someone (@majbthrd) already ported the CMSIS-DAP interface firmware to the Pico, giving us a ready firmware to be used, so lets try it:

First we need to clone the repository and compile it:

git clone https://github.com/majbthrd/DapperMime
cd DapperMime/
git submodule update --init --recursive
make BOARD=raspberry_pi_pico all

Then, we need to flash the resulting binary into the Pico, this is quite trivial with Pico’s built-in UF2 bootloader, just connect the pico to the PC while holding the boot button and copy the .uf2 binary (found inside build folder) to the Pico’s disk.

Now, we need to make sure that OpenOCD is able to use a CMSIS-DAP as interface, in my case it was not included by default on my last compilation and installation, so I needed to solve some dependencies and recompile it:

The main dependency was the missing HIDAPI lib, so I compiled and installed it:

git clone https://github.com/libusb/hidapi
cd hidapi
./bootstrap
./configure
make
sudo make install

Then I recompiled OpenOCD with CMSIS-DAP support and reinstalled it:

cd ~/openocd
./configure --enable-cmsis-dap
make
sudo make install

Now we create a new config file, similar to the previous one but specifying CMSIS-DAP as interface:

source [find interface/cmsis-dap.cfg]
source [find target/stm32g0x.cfg]
init
rtt setup 0x20000000 36684 "SEGGER RTT"
rtt start
rtt server start 9000 0

Then we connect the Pico board to the target, following the same pinout used by the official Picoprobe fw, Pico GP2 -> SWCLK and Pico GP3 -> SWDIO:

And start again OpenOCD, passing this new config:

Bingo! It works!
Now we can use a Raspberry Pi Pico as a generic CMSIS-DAP SWD interface, for both debugging and collecting RTT data 🙂