You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nucleo-64开发板ITM端口无输出问题求助

STM32 ITM FIFO通过SWD无输出问题排查与解决

问题描述

刚接触STM32,尝试将ITM FIFO数据通过SWD输出以验证功能,项目可正常编译调试,但开启Trace后端口0始终无输出,已检查调试配置、代码逻辑及端口选择,问题未解决。

现有代码

main.c

#include <stdint.h>

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

#include <stdio.h>

int main(void)
{
    printf("hello world\n");
    /* Loop forever */
    for(;;);
}

syscalls.c

#define DEMCR                   *((volatile uint32_t*) 0xE000EDFCU )

/* ITM register addresses */
#define ITM_STIMULUS_PORT0      *((volatile uint32_t*) 0xE0000000 )
#define ITM_TRACE_EN            *((volatile uint32_t*) 0xE0000E00 )

void ITM_SendChar(uint8_t ch)
{

    //Enable TRCENA
    DEMCR |= ( 1 << 24);

    //enable stimulus port 0
    ITM_TRACE_EN |= ( 1 << 0);

    // read FIFO status in bit [0]:
    while(!(ITM_STIMULUS_PORT0 & 1));

    //Write to ITM stimulus port0
    ITM_STIMULUS_PORT0 = ch;
}

__attribute__((weak)) int _write(int file, char *ptr, int len)
{
  (void)file;
  int DataIdx;

  for (DataIdx = 0; DataIdx < len; DataIdx++)
  {
    //__io_putchar(*ptr++);
      ITM_SendChar(*ptr++);
  }
  return len;
}

问题根源与解决步骤

1. 修正ITM寄存器地址定义

现有代码中ITM_TRACE_EN指向的0xE0000E00是ITM锁存访问寄存器(ITM_LAR),而非端口使能寄存器,导致端口0无法被正确使能。需修正寄存器定义:

#define DEMCR                   (*((volatile uint32_t*) 0xE000EDFCU ))
#define ITM_LAR                 (*((volatile uint32_t*) 0xE0000E00U ))  // ITM解锁寄存器
#define ITM_TCR                 (*((volatile uint32_t*) 0xE0000E80U ))  // ITM控制寄存器
#define ITM_ENA                 (*((volatile uint32_t*) 0xE0000E04U ))  // ITM端口使能寄存器
#define ITM_STIMULUS_PORT0      (*((volatile uint32_t*) 0xE0000000U ))

2. 补充ITM解锁与全局使能逻辑

ITM寄存器默认处于锁定状态,需先写入解锁码才能配置;同时需使能ITM全局跟踪功能。修正ITM_SendChar函数:

void ITM_SendChar(uint8_t ch)
{
    // 解锁ITM寄存器(必须步骤,否则无法修改ITM配置)
    ITM_LAR = 0xC5ACCE55;
    
    // 使能CoreDebug的TRCENA位
    DEMCR |= (1 << 24);
    
    // 使能ITM全局跟踪功能
    ITM_TCR |= (1 << 0);
    
    // 使能ITM端口0
    ITM_ENA |= (1 << 0);

    // 等待端口0 FIFO就绪(bit0为1表示可写入)
    while(!(ITM_STIMULUS_PORT0 & 0x1));
    
    // 写入字符到端口0
    ITM_STIMULUS_PORT0 = ch;
}

3. 完善调试器配置

  • 确保调试工具(如Keil、STM32CubeIDE)中已开启Trace Enable,并设置正确的SWO时钟(建议设为CPU时钟的1/6~1/8,需匹配硬件实际时钟);
  • 在调试工具的ITM控制台中,开启对端口0的监听;
  • 部分调试器需在连接目标板后,手动启动SWO跟踪功能。

4. 确保printf重定向生效

去掉_write函数的__attribute__((weak))修饰符,避免被其他弱实现覆盖,确保printf调用的是自定义的_write函数。

内容的提问来源于stack exchange,提问作者jdsus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:45:57