In this guide, we shall retargeting printf which part of stdio library to debug you code. For example, interrupt handler, variable to be displayed etc.
In this guide, we shall cover the following:
- Serial Wire Output.
- Implementing header file.
- Implementing source code for keil uVision.
- Implementing source code of STM32CubeIDE.
- Setup Serial Wire Viewer in Keil uVison.
- Setup Serial Wire Viewer in STM32CubeIDE.
- Demo.
1. Serial Wire Output:
Serial Wire Output (SWO) alongside Serial Wire Debug (SWD) allows for the CPU to emit real-time trace data. In particular, when used with an Instrumentation Trace Macrocell (ITM), it can be used to form a Serial Wire Viewer (SWV). The ITM ports are provided by the ARM controller. The SWV typically implements a form of printf
style debugging for embedded systems.
2. Implementing header file:
After we created a new header file with name of swo.h, we can implementing the functions such as:
- log_error
- log_info
- log_debug
- log_debug_array
#ifndef __SWO__h #define __SWO__h #include <stdio.h> #include "stm32f4xx.h" // Device header void log_error(char *p); void log_info(char *p); void log_debug(char *p); void log_debug_array(char const * const label, void const *array, uint16_t const len); #endif
3. Implementing source code for keil uVision:
In Keil uVision, the printf function can be retargeted as following:
struct __FILE {int handle;/* Add whatever you need here */}; FILE __stdout; FILE __stdin; int fputc(int ch, FILE *f) { ITM_SendChar(ch); return(ch); }
For the other functions:
void log_error(char *p) { printf("log Error: "); printf((char*)p); printf("\r\n"); } void log_info(char *p) { printf("log info: "); printf((char*)p); printf("\r\n"); } void log_debug(char *p) { printf("log debug: "); printf((char*)p); printf("\r\n"); } void log_debug_array(char const * const label, void const *array, uint16_t const len) { printf("log debug array: "); for (uint16_t i = 0; i < len; i++) { uint8_t val = *((uint8_t *)(array + i)); printf("0x%02X", val); // Add ", " after all elements except the last one. if (i < len - 1) { printf(", "); } } printf("}\n"); }
4. Implementing source code for STM32CubeIDE:
In STM32CubeIDE, the printf functionality can be retargeted as following:
int __io_putchar(int ch) { ITM_SendChar(ch); return ch; }
5. Setup Serial Wire Viewer in Keil uVison:
After you compile the code and enter a debug session:
6. Setup for STM32CubeIDE:
Please check the video from here:
7. Results:
Happy coding 🙂
12 Comments
Is there a reason that when I come to this page I get an automatic download of file “Screen-Recording-2022-03-04-at-7.28.51-AM.mov” ?
Hi,
This is for the video we attached with topic for configuring SWV for CubeIDE.
It is very long to do it in pictures, hence we opt the option to use video instead.
Feel free to add our website to not download automatically specially videos.
Hi,
From now and on, the videos shall be uploaded to youtube for the convenience of the site visitors.
I can’t see the section “Setup Serial Wire Viewer in STM32CubeIDE”
It shall be reuploaded soon.
The older version was triggering auto-download and it was troublesome for visitors.
Keep your eyes on the post and shall be updated soon.
Hi,
I wanted to let you know that STM32CubeIDE setup section has been added.
Hi thanks for this code. I’m trying it but on uVision I’m getting the error message below. Any ideia how to solve it ?
..\source\src\swo.c(89): error: #852: expression must be a pointer to a complete object type
uint8_t val = *((uint8_t *)(array + i));
..\source\src\swo.c: 0 warnings, 1 error
One more thing. At the first line of the C code, there is missing a “S” letter right at the beginning:
truct __FILE {int handle;/* Add whatever you need here */};
Thanks !
Regarding struct, fixed.
Regarding the issue, try ARM compiler v6.
The printf works already in the latest version of stm32
struct __FILE {int handle/* Add whatever you need here */};
in KEIL I get error redefinition of ‘ __FILE ‘
How I can improve it?
Thanks for your posts I came across to this site and this is amazing
Hi,
change the compiler from v6 to v5 or remove __ from __FILE and all the other functions.
I can’t thank you enough. Thanks a lot it helped. The other problem was I tried to debug it through a serial monitor not through Debug printf Viewer. And sorry for off topic in other topics I had an error uploading my massage from the phone and didn’t see it posted. Btw I’m glad I discovered your site you’re a life saver. Hat off to you man
Add Comment