I have converted a SDK project "hello_word" to MaaXBoard-RT and extended it to demonstrate how to use the ITM Trace as "ITM_Print" (with SWO Viewer in IDE).
The demo project is here:
GitHub - tjaekel/MaaXBoard-RT_ITM_Print: MaaXBoard-RT with SWO Viewer (ITM_Print)
You could also use my "big" (and actual) project which uses also ITM_Print (via command "test"):
GitHub - tjaekel/MaaXBoard-RT_SPIder: MaaXBoard-RT SPIder framework
What is ITM_Print?
ITM_Print uses the "SWO Viewer" (provided by the IDE, when running in Debug mode).
You can print messages via a Debugger channel (ITM Trace), using the SWO signal. You can see messages, when enabled (!), in SWO_Viewer window.
You can also input characters and receive it in your running FW (e.g. waiting for an interaction, take a value before keep going...).
It works like a UART (in and out, bi-directional), with these benefits:
- you can keep code for ITM_Print in your project: the overhead ("runtime penalty" is very small
if you do not enable in IDE - your project runs in almost full-speed as possible - Even you enable SWO_Viewer in IDE: the overhead is still very small:
such an ITM_Print does not take huge amount of code, does not have a decrease on performance (speed) - All the messages go via a "Debug Channel", like a UART, but it is not an UART (not so slow, not so much code)
- You have still the user UART available (like a second debug log channel)
ITM_Print is much faster as any real UART debug log (e.g. LPUART1 with 115200 baud rate).
How to enable ITM_Print?
You should take a file "retarget_ITM.c" to your project: get it from SDK repository or from the project(s) above.
It provides functions calls as:
int _write(int iFileHandle, char *pcBuffer, int iLength);
int _read(int iFileHandle, char *pcBuffer, int iLength);
You can also use from "cmsis_cm7.h":
__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch);
__STATIC_INLINE int32_t ITM_ReceiveChar (void);
Add in "pin_mux.c":
You have to add the config for the SWO signal (so that it comes out).
Add in file "pin_mux.c" these lines of code:
IOMUXC_SetPinMux(
IOMUXC_GPIO_LPSR_11_ARM_TRACE_SWO, /* GPIO_LPSR_11 is configured as ARM_TRACE_SWO */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_LPSR_11_ARM_TRACE_SWO, /* GPIO_LPSR_11 PAD functional properties : */
0x02U); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: high driver
Pull / Keep Select Field: Pull Disable
Pull Up / Down Config. Field: Weak pull down
Open Drain LPSR Field: Disabled
Domain write protection: Both cores are allowed
Domain write protection lock: Neither of DWP bits is locked */
The clock configuration should be already done (in file "clock_config.c"), as:
/* Configure CSTRACE using SYS_PLL2_CLK */
rootCfg.mux = kCLOCK_CSTRACE_ClockRoot_MuxSysPll2Out;
rootCfg.div = 4;
CLOCK_SetRootClock(kCLOCK_Root_Cstrace, &rootCfg);
Remember, which clock will it generate for the ITM (SWO): in most of the cases, where the MCU clock is set to 996 MHz, it should be 132 MHz (remember both values).
How to enable and use "SWO_Viewer"?
When you start a debug session, open the "Perspective" for "SWO ITM Console" (and also "SWO Trace Config" : which can be invoked from the other one).
You have to configure ITM Trace first: in "SWO Trace Config" and "Configuration" click on "Change":
Provide as parameters:
Core Clock Speed (Hz) : 996000000 (or use "Detect": the clock speed is changed during startup!)
Trace Clock Speed (Hz) : 132000000 (related to the CSTRACE clock speed config above)

Start the SWO_Viewer (the "run" icon needs to be pressed).
Now, you should see all ITM_prints and you are able to use the "terminal" (Console) also for inputs (your FW waiting for something received).


--> Don't forget to press on the "run" icon (the green arrow)
Very helpful feature and very fast log message without to compromise your performance in FW.
A second debug channel and no need to use a slow UART to watch your FW.