Print using SWD
Attention
ITM SWV Console
does not work using our duplicate ST-Link V2
adapter. So using bluepill
, USB
is used for printf
in our case.
Warning
SWV
does not work in STM32F407VG-DISC1 board if you use PB3
pin because it is connected to SWO
pin of ST-Link.
1. Introduction
SWD also can be used to print data. But we cannot get them normally. We need speacial program to see which is Serial Wire Viewer (SWV)
. STM32CubeProgrammer
has SWV. Download it from installation.
In order to trace information, Instrumentation Trace Macrocell (ITM) is used in ARM processors. It uses SWO pin for tracing.
2. Overwrite Definition of printf
Important
ITM uses SWO, so select Debug
option as Trace Asynchronous SW
in STM32CubeMX.

Create a new file
printf_conf.c
inCore/Src
folder.Add the following code to the file:
printf_conf.c1#include "stm32f4xx_hal.h" // for stm32f4 2 3 int _write(int file, char *data, int len) 4 { 5 for (int i = 0; i < len; ++i) 6 { 7 ITM_SendChar(data[i]); 8 } 9 return len; 10 }
3. Update Makefile or CMakeLists.txt
Add
printf_config.c
to source.C_SOURCES = \ ... \ ... \ Core/Src/printf_conf.c
# Add sources to executable target_sources(${CMAKE_PROJECT_NAME} PRIVATE # Add user sources here Core/Src/printf_conf.c )
Add
-u _printf_float
flag.Add to
LDFLAGS
.LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections LDFLAGS += -u _printf_float
Create target_link_options at the bottom.
# Add compiler flags target_link_options(${CMAKE_PROJECT_NAME} PRIVATE -u _printf_float )
4. Update main.c
Open
Core > Src > main.c
. Addstdio.h
header./* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */
Update
main
function to print “Hello World” over SWD./* USER CODE BEGIN 2 */ uint32_t n = 0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { printf ("Hello World! %lu\n", n++); HAL_Delay(100); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
Build and flash.
5. Open SWV on STM32CubeProgrammer
5.1. Using STM32CubeProgrammer GUI
Open
STM32CubeProgrammer
.Connect your microcontroller to your PC using USB cable through
ST-Link
. If you use externaldebugger
likeJLink
orST-Link
adapter, connect it as:SWCLK
of microcontroller toSWCLK
of debugger.SWDIO
of microcontroller toSWDIO
of debugger.SWO
of microcontroller toSWO
of debugger.NRST
of microcontroller toNRST
of debugger. (Optional, only if you want to hard reset microcontroller using debugger)GND
of microcontroller toGND
of debugger.3V3
of microcontroller to3V3
of debugger.
Click on
Connect
.Click on
SWV
.Set
Core Clock
to the microcontroller clock frequency configured inSTM32CubeMx
. It is168MHz
in this case.Click on
Start
.
You can see the message “Hello World” on the SWV
continously.

Do not be confused that I used 80MHz in clock frequency. I used different device at the time of this demo. Use your own.
5.2. Using STM32CubeProgrammer CLI
Use the following command to open SWV:
# STM32_Programmer_CLI -c port=swd -swv freq=<HCLK_freq_in_MHz> portnumber=0 STM32_Programmer_CLI -c port=swd -swv freq=168 portnumber=0
Then press
R
toreset
andstart
. You can see the message “Hello World” on the terminal continously.Press
S
to stop andE
to exit.Add
STM32_Programmer_CLI
command at the bottom ofMakefile
orCMakeLists.txt
.1# Open SWV 2swv: 3 STM32_Programmer_CLI -c port=swd -swv freq=168 portnumber=0
# Open SWV add_custom_target(swv COMMAND STM32_Programmer_CLI -c port=swd -swv freq=168 portnumber=0 )