on
2024-10-16
5:00 AM
- edited on
2025-08-04
2:10 AM
by
Laurids_PETERSE
This article provides a step-by-step guide on how to use the Instrumentation Trace Macrocell (ITM) console to redirect print statements and LWIP debug messages in STM32CubeIDE. These tools are valuable for debugging and optimizing your applications involving LWIP middleware. Moreover, networking applications such as Ethernet based applications.
You may already have an application where you need to enhance its debuggability and trace your potential issues. If you're trying to test this from scratch, we provide you with a quick and useful tutorial. You can find the working example with all the modifications on GitHub here: GitHub: stm32-hotspot.
Hardware:
Software:
1. Open your project in STM32CubeIDE.
2. Open main.c and include the following headers:
#include <stdio.h>
3. Redirect printf to ITM by adding the following function:
int _write(int file, char *ptr, int len) {
for (int i = 0; i < len; i++) {
ITM_SendChar((*ptr++));
}
return len;
}After these steps, you should be able to view printfs in your ITM console. This can be done by adding a printf call in your while(1) loop to test this feature.
6. After the debug section is opened, open the SWV ITM Data Console by accessing [Window] -> [Show View] -> [Other] -> [SWV] -> [SWV ITM Data].
7. Check the configuration as seen in the image below, and start the process by clicking the red dot on the top-right corner.
Assuming the steps in section 2 are applied, we can enable the debug capabilities.
lwipopts.h and add the following macro:#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
define ETHARP_DEBUG LWIP_DBG_ON
/*----- Default Value for NETIF_DEBUG: LWIP_DBG_OFF ---*/
#define NETIF_DEBUG LWIP_DBG_ON
/*----- Default Value for PBUF_DEBUG: LWIP_DBG_OFF ---*/
#define PBUF_DEBUG LWIP_DBG_ON
/*----- Default Value for API_LIB_DEBUG: LWIP_DBG_OFF ---*/
#define API_LIB_DEBUG LWIP_DBG_ON
/*----- Default Value for API_MSG_DEBUG: LWIP_DBG_OFF ---*/
#define API_MSG_DEBUG LWIP_DBG_ON
/*----- Default Value for SOCKETS_DEBUG: LWIP_DBG_OFF ---*/
#define SOCKETS_DEBUG LWIP_DBG_ON
/*----- Default Value for ICMP_DEBUG: LWIP_DBG_OFF ---*/
#define ICMP_DEBUG LWIP_DBG_ON
/*----- Default Value for IGMP_DEBUG: LWIP_DBG_OFF ---*/
#define IGMP_DEBUG LWIP_DBG_ON
/*----- Default Value for INET_DEBUG: LWIP_DBG_OFF ---*/
#define INET_DEBUG LWIP_DBG_ON
/*----- Default Value for IP_DEBUG: LWIP_DBG_OFF ---*/
#define IP_DEBUG LWIP_DBG_ON
/*----- Default Value for IP_REASS_DEBUG: LWIP_DBG_OFF ---*/
#define IP_REASS_DEBUG LWIP_DBG_ON
/*----- Default Value for RAW_DEBUG: LWIP_DBG_OFF ---*/
#define RAW_DEBUG LWIP_DBG_ON
/*----- Default Value for MEM_DEBUG: LWIP_DBG_OFF ---*/
#define MEM_DEBUG LWIP_DBG_ON
/*----- Default Value for MEMP_DEBUG: LWIP_DBG_OFF ---*/
#define MEMP_DEBUG LWIP_DBG_ON
/*----- Default Value for SYS_DEBUG: LWIP_DBG_OFF ---*/
#define SYS_DEBUG LWIP_DBG_ON
/*----- Default Value for TIMERS_DEBUG: LWIP_DBG_OFF ---*/
#define TIMERS_DEBUG LWIP_DBG_ON
/*----- Default Value for TCP_DEBUG: LWIP_DBG_OFF ---*/
#define TCP_DEBUG LWIP_DBG_ON
You can select one of the elements that you want to see it is debug message, and you can select which level of debug you want to visualize:
The element of the LWIP stack from which you want to get returns can be selected in the STM32CubeMX debug menu config of LWIP:
Make sure that the right call of printf is redirected with the LWIP_PLATFORM_DIAG macro in the arch.h file.
/** Platform specific diagnostic output.\n
* Note the default implementation pulls in printf, which may
* in turn pull in a lot of standard libary code. In resource-constrained
* systems, this should be defined to something less resource-consuming.
*/
#ifndef LWIP_PLATFORM_DIAG
#define LWIP_PLATFORM_DIAG(x) do {printf x;fflush(0);} while(0)
#include <stdio.h>
#include <stdlib.h>
After this, you can see debug messages of the LWIP stack in your ITM console.
You can also extract them from the SWV export folder in your project for further investigation and analysis if needed.
The combination of this tool with FreeRTOS™ can help immensely in the debugging process.
You can refer to the following article showing a how to of FreeRTOS™ debugging: How to enable FreeRTOS™ Run Time and Stack Usage view
By following these steps, you can effectively use the ITM console to redirect print statements and LWIP debug messages. These tools help you gain deeper insights into your applications behavior and facilitate efficient debugging and optimization.
Hi All,
I am using STM32F303RE board. Initially, SWV console was not printing printf() message. Fort this, I had to write the below code.
/* USER CODE BEGIN PFP */
int __io_putchar(int ch)
{
ITM_SendChar(ch);
return ch;
}
/* USER CODE END PFP */
Enabled SWV in debug configuration and also enbaled port 0 in SWV ITM Dat console settings.
It did not work. After debugging, I figured out ITM->TCE and ITM->TER bits were not set in core_cm4.h file.
I set this in my main() code after invoking HAL_Init() function as below:
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
ITM->TCR |= (1U << ITM_TCR_ITMENA_Pos);
ITM->TER |= (1U << 0);
/* USER CODE END Init */
Once this is done, it starting printing junk characters.
I did debug and figured out the root cause if sysclk freequency.
For me HSI_RC was 8MHz and this was PreDiv by 1 and PLLMul was 9. So that SYSCLK was 36MHz. This was causing junk characters printing.. Hence, I did PreDiv by 2 and SYCLK became 18Mhz.
With this clock configuration, everything stared working.
* I did noted down that the clock was configured to 36MHz even in Debug configuration and Core clock in SWV ITM Data console setting. But this 18Mhz was matching with Clock Prescaler*