在 Nucleo STM32 板上设置 SWV printf

Posted

技术标签:

【中文标题】在 Nucleo STM32 板上设置 SWV printf【英文标题】:Setting up SWV printf on a Nucleo STM32 board 【发布时间】:2018-12-07 06:52:33 【问题描述】:

我正在使用 Atollic Truestudio IDE(基本上是 Eclipse)在各种 STM32L4 Nucleo 板上开发固件。到现在为止,我通过 UART 使用 printf,这要归功于 Virtual COM 端口。

我想使用 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-&gt;PORT[0U].u8 = (uint8_t)ch;

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

知道我错过了什么吗? SWV 的核心时钟呢?我不确定它对应的是什么。

【问题讨论】:

【参考方案1】:

我在 Nucleo-F103RB 上遇到了类似的情况。使这项工作起作用的是在 CubeMX 上选择“跟踪异步”调试选项,而不是“串行线”。跟踪异步调试将 PB3 引脚专用为 SWO 引脚。

然后设置调试配置如下: Project debug configuration to enable Serial Wire Viewer (SWV)

另外,我在 main.c 文件本身中定义了 write 函数,更改 syscalls.c 中的定义是行不通的。

最后在调试项目时,在“Serial Wire Viewer settings”下仅启用(检查)ITM Stimulus Ports 上的端口 0,如下所示: Serial Wire Viewer settings in Debug perpective

当我为时间戳和一些跟踪事件启用预分频器时,我注意到一件事,跟踪输出不会显示很多跟踪日志。

【讨论】:

【参考方案2】:

其他人发现这个 - Nucleo 开发板的 Nucleo-32 系列莫名其妙地没有将 SWO 引脚路由到 MCU。 SWO 引脚对于所有 SWV 功能都是必需的,因此它不会按设计工作。更高引脚数的 Nucleo 板似乎已布线。

自己看:

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)

【讨论】:

@GuillaumePetitjean 您是否建议在下面的答案中不连接 SWO 引脚的情况下使 ITM 工作?根据我对 ITM/SWV 的理解,这是不可能的。或者您是在不同的 Nucleo 平台而不是 Nucleo-32 上执行此操作? 我从未使用过 Nucleo-32 板,只使用过 Nucleo-144 板。【参考方案3】:

小型 Nucleo-32 插针板一般不支持 SWO/SWV,但有一个例外:Nucleo-STM32G431KB。截至 2021 年 9 月,这可能是唯一一款小型 Nucleo-32 引脚,非常强大的板,支持 ST-LINK V3 和 SWO。见MB1430 schematic。 尽管我的回答与有关 Nucleo-L4A6ZG(144 针大因子)的原始问题松散相关,但它可能有助于找到此线程的人。

【讨论】:

【参考方案4】:

顺便提一下,ITM printf 在 Keil IDE 上完美运行。没有什么特别的设置,只需实现我第一篇文章中显示的ITM_SendChar 函数并打开调试 printf 窗口。

【讨论】:

以上是关于在 Nucleo STM32 板上设置 SWV printf的主要内容,如果未能解决你的问题,请参考以下文章

stm32wb, nucleo-wb55, 传感器, 硬件

无法在STM32H7上正确设置Cortex M7 ITM

STM32CubeIDE SWV功能使用方法

STM32CubeIDE SWV功能使用方法

STM32F4程序只有在按下复位按钮后才会运行

STM32:STLink 不再通过 SWD 连接