Showing results for 
Search instead for 
Did you mean: 

How to read raw SWO data posted by ST-LINK GDB server to a TCP port



I am trying to route printf-like data streamed from the SWO pin of an STM32L432KB MCU to a Windows command prompt using a STLINK-V3SET/MINI probe. I need to do this while flashing new firmware or debugging. The SWO pin uses UART encoding at 2 MHz and everything is configured in software like this:

// alternate function AF0 for PB3/TRACESWO
GPIOB->MODER    = (GPIOB->MODER & ~0xC0) | 0x80;   
GPIOB->AFR[0]  &= ~0x0000F000;
GPIOB->OSPEEDR |=  0x000000C0;        // maximum speed
GPIOB->PUPDR   &= ~0x000000C0;        // no pull-up/down
// enable the SWO pin in async. mode
// enable DWT and ITM
CoreDebug->DEMCR |=  CoreDebug_DEMCR_TRCENA_Msk;      
TPI->CSPSR =  1;                    // port width = 1 bit
TPI->SPPR  =  2;                    // UART encoding
TPI->ACPR  =  HAL_RCC_GetHCLKFreq()/2000000-1; // clock divider
TPI->FFCR &= ~TPI_FFCR_EnFCont_Msk; // no formatter
ITM->LAR   =  0xC5ACCE55;           // unlock the ITM registers
ITM->TCR   =  ITM_TCR_ITMENA_Msk    // enable the ITM
           |  ITM_TCR_TraceBusID_Msk; // stream identifier
ITM->TPR   =  0b1111;               // enable unprivileged acc.
ITM->TER   =  -1UL;                 // enable all ports

Unfortunately the SWO pin is enabled only after starting a debugger connection (for example by running ST-LINK_gdbserver in the background), otherwise the pin is Hi-Z. I think this has something to do with the C_DEBUGEN bit in CoreDebug->DHCSR register which can be set only by a debugger.

My first question is whether it is possible to stream ITM packets over the SWO pin under MCU control exclusively (no external probe, debugger etc.)?

My second question is how to reliably retrieve raw SWO data. This is what I tried so far:

1. Use STM32_Programmer_CLI in shared mode like this:

STM32_Programmer_CLI -c port=SWD shared -startswv freq=80 portnumber=all

This partially works but there are too many lost packets.

2. Use ST-LINK_gdbserver to publish raw SWO data to a TCP port:

ST-LINK_gdbserver -d --attach -z 3443 -a 80000000 -b 40 –cp...
STMicroelectronics ST-LINK GDB server. Version 7.3.0
Copyright (c) 2023, STMicroelectronics. All rights reserved.
Starting server with the following options:
        Persistent Mode            : Disabled
        Logging Level              : 31
        Listen Port Number         : 61234
        Status Refresh Delay       : 15s
        Verbose Mode               : Disabled
        SWD Debug                  : Enabled
COM frequency = 24000 kHz
Target connection mode: Attach
Reading ROM table for AP 0 @0xe00fffd0
Hardware watchpoint supported by the target
ST-LINK Firmware version : V3J11M3
Device ID: 0x435
PC: 0x79fb70
ST-LINK device status: RUN_MODE
ST-LINK detects target voltage = 3.26 V
ST-LINK device status: RUN_MODE
ST-LINK device initialization OK
Stm32Device, pollAndNotify running...
SwvSrv state change: 0 -> 1
Waiting for connection on port 3443...
Waiting for debugger connection...
Waiting for connection on port 61234...
Accepted connection on port 3443...
SWV collect poll delay set to 34133µs for baudrate 2000000Hz (buffer size 20480b)
SwvSrv state change: 1 -> 2

In another terminal I run orbcat from the Orbuculum project:

orbcat -s localhost:3443 -c 0,"%c"

I can see the connection but no data is exchanged (checked with TCPView). I also tried in shared mode with the same result.

3. Use PyOCD to publish raw SWO data to a TCP port:

pyocd gdb -S -Oenable_swv=1 -Oswv_system_clock=80000000 -Oswv_clock=2000000 -Osemihost_console_type=console -t STM32L432KB

In another terminal I run orbcat like before and I can see the data correctly without any lost packets. The problem with this option is that PyOCD blocks the USB connection with ST-Link and I cannot flash or debug without closing the PyOCD server. Starting and closing PyOCD is very slow so this option is very annoying and not practical at all.

4. Connect SWO to an FTDI serial converter and use Orbuculum to publish raw SWO data to a TCP port:

orbuculum -v 2 --serial-port COM10 --serial-speed 2000000

In another terminal I run orbcat and everything works without any lost packets. I can flash and debug using STM32_Programmer_CLI and ST-LINK_gdbserver at the same time. The problem is that the GDB server must be running in the background in order to have the SWO pin enabled (see the first question) which makes a total of 3 background processes in 3 terminals just to print a log. Another annoyance is the requirement of the serial converter.

The best solution would be the option no. 2 which does not work. So how can I make ST-LINK_gdbserver publish the data like PyOCD and Orbuculum? The documentation says it is possible:

-z <port number>, --swo-port <port number>

Specifies the TCP port number at which the server outputs raw SWO data.



Hello Borcut,

Did you manage to make method 2 work?


Hello On,

I did try with ST-LINK_gdbserver version 7.5.0 with the same result.



Associate II

Hi Borcut,

Were you ever able to get something working that you were happy with?

I would really like to get this working ST-LINK_gdbserver as that would be ideal.  I use CLion as my IDE which launches ST-LINK_gdbserver for flashing/debugging, which all works nicely.  Getting SWO in this scenario would be great.

I am intrigued by your success routing the SWO line to an FTDI converter.  Could you provide some details on how you did that (what FTDI converter, how you connected it, etc.)?  I have a number of different ST-Links from the ST-Link V3Set to the V3-mini, so hopefully I could make something work.