Skip to main content
Amigo
Associate II
May 23, 2022
Solved

Nucleo Board ST-Link SWV

According to my experiences, STM32CubeIDE (1.9.0) does not support SWV message via ITM when using ST-Link GDB server, but it does so via OpenOCD. However, Keil µVision 5 does support ITM tracing, even bidirectional, via the 'Debug (printf) Viewer', when selecting the ST-Link option. What driver is Keil using that STM32CubeIDE isn't?

This topic has been closed for replies.
Bastien LSBest answer
Associate III
May 23, 2022

Hi Amigo,

The SWV prints via ITM using ST-Link (GDB Server) on STM32CubeIDE 1.9.0 with the NUCLEO-U575ZI-Q works on my computer.

There is an example in the section "4.3.5 SWV ITM Data Console and printf redirection" of the user guide:

https://www.st.com/resource/en/user_manual/um2609-stm32cubeide-user-guide-stmicroelectronics.pdf

I hope it helps.

6 replies

Bastien LSBest answer
Associate III
May 23, 2022

Hi Amigo,

The SWV prints via ITM using ST-Link (GDB Server) on STM32CubeIDE 1.9.0 with the NUCLEO-U575ZI-Q works on my computer.

There is an example in the section "4.3.5 SWV ITM Data Console and printf redirection" of the user guide:

https://www.st.com/resource/en/user_manual/um2609-stm32cubeide-user-guide-stmicroelectronics.pdf

I hope it helps.

Amigo
AmigoAuthor
Associate II
May 23, 2022

Thanks a lot for that. Upon reading those instructions, I managed to get the ITM_SendChar() working.

I have three different ways of using the ITM:

1. Simple use of ITM_SendChar():

ITM_SendChar((uint32_t)'A');

or defining my own function to output strings:

void SWO_print_string(const char *s)
{
 while (*s) ITM_SendChar(*s++);
}

On an STM32F401RE at 84MHz, the first takes 600ns, the second times that roughly by the number of characters to be sent.

2. Using printf(), but with the caveat that the output buffer—i.e. ITM—is not flushed until a '\n' is sent, which annoyed me a great deal in the past:

printf("A\n");

On an STM32F401RE at 84MHz, the printing of the first character takes 5.2µs, with 2µs added for each extra character. Formatted strings with extra arguments will take longer.

3. Or, defining my own version of printf() , myprintf(), which flushes the buffer automatically:

// redirect the _write() to the ITM
int _write(int file, char *ptr, int len)
{
 int i=0;
 
 for(i=0 ; i<len ; i++)
 {
 ITM_SendChar(*ptr++);
 }
 return len;
}
 
// dummy redirect of _read() to avoid linker error on other Cortex-M compilers
int _read(int file, char *ptr, int len)
{
 return len;
}
 
// myprintf() function which flushes the buffer
__attribute__ ((__format__ (__printf__, 1, 2))) int myprintf(const char *__restrict format, ...)
{
 va_list args;
 int return_value;
 
 va_start(args, format);
 
 return_value = vprintf(format, args);
 fflush(stdout);
 
 va_end(args);
 return return_value;
}

On an STM32F401RE at 84MHz, the first character takes 8.5µs to print, with every extra character taking between 1µs and 2µs. The following code will take 30µs:

myprintf("%lu\n", current_tick);

I prefer to use the simple ITM_SendChar() for its short CPU time, with actual numbers, which Keil can display in Hex. Keil can also provide characters to the microcontroller, which can be read via ITM_ReceiveChar(), through typing keys on the keyboard, and the ASCII codes are sent to the ITM. Unfortunately, such a feature is not available in STM32CubeIDE, unless I am mistaken?

Associate III
May 24, 2022

I cannot answer your question as I never used this feature.

If you wish to learn more about the features of SWV on STM32CubeIDE, I recommend watching this e-learning on the subject:

STM32CubeIDE Advanced Debug Features

Learning Plan Detail Standard

Tesla DeLorean
Guru
May 23, 2022

With SWV it is important for the interface clocking, and part clocking (core frequency) be correctly established so the baud rates are correct and the data can be interpreted.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..