I am developping a Firmware on various STM32L4 Nucleo boards with Atollic Truestudio IDE (basically Eclipse). Until now I was using printf through UART, thanks to the Virtual COM port.
I want to migrate to printf using STM32 ITM.
More precisely I work on Nucleo-L4A6ZG. Debug is through a gdb server.
On Atollic I modified my Debug Configuration to enable SWV with a core clock of 80MHz. I've modified my startup script as described in STM32L4 reference manual as follows. I'm not sure it is necessary since TrueStudio/Eclipse allows to setup SWV from the GUI but seems easier this way:
# Set character encoding
set host-charset CP1252
set target-charset CP1252
# Reset to known state
monitor reset
# Load the program executable
load
# Reset the chip to get to a known state. Remove "monitor reset" command
# if the code is not located at default address and does not run by reset.
monitor reset
# Enable Debug connection in low power modes (DBGMCU->CR) + TPIU for SWV
set *0xE0042004 = (*0xE0042004) | 0x67
# Write 0xC5ACCE55 to the ITM Lock Access Register to unlock the write access to the ITM registers
set *0xE0000FB0 =0xC5ACCE55
# Write 0x00010005 to the ITM Trace Control Register to enable the ITM with Synchronous enabled and an ATB ID different from 0x00
set *0xE0000E80= 0x00010005
# Write 0x1 to the ITM Trace Enable Register to enable the Stimulus Port 0
set *0xE0000E00= (*0xE0000E00) | 0x1
#write 1 to ITM trace privilege register to unmask Stimulus ports 7:0
set *0xE0000E40= (*0xE0000E40) | 0x1
# Set a breakpoint at main().
tbreak main
# Run to the breakpoint.
continue
I've modified my _write function as follows:
static inline unsigned long ITM_SendChar (unsigned long ch)
{
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
{
while (ITM->PORT[0U].u32 == 0UL)
{
__asm("nop");
}
ITM->PORT[0U].u8 = (uint8_t)ch;
}
return (ch);
}
int _write(int file, char *ptr, int len)
{
//return usart_write(platform_get_console(), (u8 *)ptr, len);
int i=0;
for(i=0 ; i<len ; i++)
ITM_SendChar((*ptr++));
return len;
}
Debugging step by step I see that I get at line ITM->PORT[0U].u8 = (uint8_t)ch;
Finally I start the trace in the SWV console in the IDE but I get no output.
Any idea what I am missing ? What about the core clock of the SWV ? I'm not sure what it corresponds to.