Setting up SWV printf on a Nucleo STM32 board
Asked Answered
J

4

5

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.

Jessikajessup answered 28/6, 2018 at 8:55 Comment(1)
electronics.stackexchange.com/questions/206113/… this explains how to set it up.Vorticella
Y
6

I faced a similar situation on my Nucleo-F103RB. What got this working was selecting "Trace Asynchronous" debug option on CubeMX and not "Serial Wire". The trace asynchronous debug dedicates the PB3 pin as a SWO pin.

Then setup the debug configuration as follows:

Project debug configuration to enable Serial Wire Viewer (SWV)

Also, I'd defined the write function inside of the main.c file itself, changing the definition in the syscalls.c wouldn't work.

And finally when debugging the project, under the "Serial Wire Viewer settings" only enable (check) port 0 on ITM Stimulus Ports, like so:

Serial Wire Viewer settings in Debug perspective

One thing I noted when I had enabled the prescaler for timestamps and some trace events, the trace output would not show quite a few trace logs.

Yezd answered 10/2, 2019 at 8:0 Comment(1)
Hi! I am using STM32H723ZG nucleo board, but cannot make it work. I followed every instruction in this answer, removed SB26 as doc says, ITM_SendChar is invoked but never get any data to SWV.Usurer
R
3

Anyone else finding this - The Nucleo-32 line of Nucleo development boards inexplicably DO NOT have the SWO pin routed to the MCU. The SWO pin is necessary for all the SWV features, so it will not work by design. The higher pin-count Nucleo boards seem to have it routed.

See for yourself:

https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf (Nucleo-32)

https://www.st.com/resource/en/user_manual/dm00105823-stm32-nucleo-64-boards-mb1136-stmicroelectronics.pdf (Nucleo-64)

Reflect answered 15/7, 2020 at 4:2 Comment(2)
@GuillaumePetitjean Are you suggesting that you were able to make ITM work without the SWO pin being connected in your answer below? From my understanding of ITM/SWV that's impossible. Or were you doing this on a different Nucleo platform, not Nucleo-32?Reflect
I've never used a Nucleo-32 board, only Nucleo-144 boards.Jessikajessup
C
1

Small-factor Nucleo-32 pin boards generally do not support SWO/SWV but there is one exception: Nucleo-STM32G431KB. As of September 2021 this is probably the only small-factor Nucleo-32 pin, quite powerful board supporting ST-LINK V3 and SWO. See MB1430 schematic.
Although my response is loosely related to the original question pertaining to the Nucleo-L4A6ZG (144 pin large-factor), it may help someone finding this thread.

Chow answered 18/9, 2021 at 18:27 Comment(0)
J
0

Just to mention that the ITM printf works perfectly on Keil IDE. Nothing particular to setup, just implement the ITM_SendChar function as showed in my first post and open the debug printf window.

Jessikajessup answered 16/7, 2020 at 6:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.