在Nucleo STM32开发板上设置SWV printf

5
我正在使用Atollic Truestudio IDE(基于Eclipse)开发各种STM32L4 Nucleo板上的固件。迄今为止,我一直通过虚拟COM端口使用UART进行printf。
我想迁移到使用STM32 ITM进行printf。
更具体地说,我正在处理Nucleo-L4A6ZG。调试通过gdb服务器进行。
在Atollic中,我修改了我的调试配置以启用80MHz的核心时钟的SWV。我根据STM32L4参考手册如下修改了我的启动脚本。我不确定这是否必要,因为TrueStudio / Eclipse允许从GUI设置SWV,但这种方式似乎更容易:
# 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

我已经修改了我的_write函数,如下所示:
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;
}

逐步调试后,我发现代码执行到了这一行:ITM->PORT[0U].u8 = (uint8_t)ch;

最后我在IDE的SWV控制台中启动跟踪,但没有输出。

你有什么想法吗?SWV的核心时钟是什么?我不确定它对应什么。


这篇文章解释了如何设置并使用printf函数在STM32上。 - user50619
4个回答

6
我在Nucleo-F103RB上遇到了类似的情况。选择"Trace Asynchronous"调试选项而不是"Serial Wire"可以使其正常工作。追踪异步调试将PB3引脚专用为SWO引脚。
然后按照以下方式设置调试配置: 项目调试配置以启用Serial Wire Viewer (SWV) 此外,我在main.c文件中定义了写入函数,更改syscalls.c中的定义无效。
最后,在调试项目时,在“Serial Wire Viewer设置”下,只启用(勾选)ITM Stimulus Ports上的0号端口,如下所示: 调试视图中的Serial Wire Viewer设置 当我启用了时间戳和一些跟踪事件的分频器时,我注意到一个问题,即跟踪输出将不会显示相当多的跟踪日志。

3

@GuillaumePetitjean,您是在下面的回答中暗示您能够使ITM工作而无需连接SWO引脚吗?根据我对ITM / SWV的理解,这是不可能的。或者,您是在不同的Nucleo平台上进行操作,而不是Nucleo-32? - dellagd
我从来没有使用过Nucleo-32板,只用过Nucleo-144板。 - Guillaume Petitjean

1

小尺寸的Nucleo-32引脚板通常不支持SWO/SWV,但有一个例外:Nucleo-STM32G431KB。截至2021年9月,这可能是唯一支持ST-LINK V3和SWO的小尺寸Nucleo-32引脚板,非常强大。请参见MB1430原理图
虽然我的回答与原问题关于Nucleo-L4A6ZG(144针大尺寸)松散相关,但它可能会帮助到某些查找此线程的人。


0

只是提一下,在Keil IDE上,ITM printf可以完美地工作。无需特别设置,只需按照我第一篇帖子中所示实现ITM_SendChar函数并打开调试printf窗口即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接