Getting Started with Instrumentation Trace Macrocell in STM32CubeIDE

For ARM Cortex M3 and M4 based MCUs

G Bharathraj
4 min readApr 16, 2020

Step 0: Basic requirements:

  • The ITM feature is only available for ARM Cortex M3 or M4 based microcontroller.
  • In order to achieve this feature, the Serial Wire Output (SWO) pin of MCU has to be connected to the ST-LINK.
  • Refer to the schematics of the development board to know whether the connection is available.

A basic schematic for the SWO pin between MCU and Debugger:

SWO Pin connected to the ST-LINK Debugger

Step I: Creating an Embedded C project:

Follow the exact procedure shown in this article to continue with current article.

Link for the article: Embedded C project with STM32CubeIDE

NOTE: After following with the above article, if you ended up using OpenOCD gdbserver, then you can’t proceed further since it doesn’t support SWV

Step II: Inclusion of ITM code snippets

Enabling the ITM Functionality:

In order to enable functionality of the ITM, we need to include few lines of code in the syscalls.c file of your project. The below mentioned lines of code are to be included in the top of the syscalls.c file.

//Debug Exception and Monitor Control Register base address
#define DEMCR *((volatile uint32_t*) 0xE000EDFCU )

/* ITM register addresses */
#define ITM_STIMULUS_PORT0 *((volatile uint32_t*) 0xE0000000 )
#define ITM_TRACE_EN *((volatile uint32_t*) 0xE0000E00 )

void ITM_SendChar(uint8_t ch)
{
//Enable TRCENA
DEMCR |= ( 1 << 24);

//enable stimulus port 0
ITM_TRACE_EN |= ( 1 << 0);

// read FIFO status in bit [0]:
while(!(ITM_STIMULUS_PORT0 & 1));

//Write to ITM stimulus port0
ITM_STIMULUS_PORT0 = ch;
}

Also, we need to modify the _write function on the same syscalls.c file, which will be called by the standard printf function.

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
int DataIdx;

for (DataIdx = 0; DataIdx < len; DataIdx++)
{
//__io_putchar(*ptr++);
ITM_SendChar(*ptr++);
}
return len;
}

Using the feature on the application layer:

You can experiment it with a simple printf statement from the main() function.

Most importantly, make sure to include the “\n\r” at the end of each line to make ITM to understand the completion of each line.

Compile the code and make sure it is error free, and now we can start the debug process.

Step III: Debug configuration changes:

If you have created an empty project, then the core clock configuration of the MCU will be at its default configuration, and here is the list of default core clock frequency for different STM32 series of MCUs,

Cheat Sheet

Once we know the core clock frequency, now it’s time for setting up debug configuration. Navigate to the menu as shown below, and enable the SWV mode, also enter the proper core clock frequency.

Now, you can start the debugging process!!

Step 4: Enabling ITM Console in debug perspective

Once you started debugging, you will automatically moved to the debug perspective. Now, navigate to the SWV ITM Data Console menu as shown below.

Once you click it, a tab “SWV ITM Data Console” will get displayed at the bottom of workspace, now click configure trace.

A new panel will open, in that, check the port 0 checkbox and click OK.

At last, start the trace by click the red 🔴 button.

Great! You are done with all the configuration. Now you can start debugging.

You can see that the “Hello World” is getting printed at the ITM Console Port 0 window.

Appendix A1:

How to find the default core clock frequency of MCU ?

First, you require the datasheet of the MCU, you can get it by googling the board name: You will end up in manufacturer’s page.

On the page, you can clearly identify the MCU model number and it’s datasheet.

For F series MCU:

The HSI (High Speed Internal) is going to be the default clock for the core, so the core clock frequency will be the HSI frequency. eg., For STM32F446RE it is 16 MHz.

For L Series MCU:

The MSI (multi-speed internal) is going to be the default clock for the core, and since the MSI has wide range it is mandatory to refer the Reference Manual (RCC Section) to know the default range. For L4x series it is found to be 4MHz.

--

--