arm/Core/Src/retarget.c

112 lines
2.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
* @file retarget.c
* @brief Printf 重定向实现(支持 Ozone SWO/ITM 调试)
* @note 提供多种 printf 输出方式
******************************************************************************
*/
#include "stm32f4xx.h"
#include <stdio.h>
/* 配置选择:根据需求选择一种方式 */
#define USE_ITM_SWO 1 // 使用 ITM/SWO (Ozone Terminal 查看)
#define USE_UART 0 // 使用 UART 串口
#define USE_SEMIHOSTING 0 // 使用半主机模式
/* ========== 方案1: ITM/SWO 输出Ozone 原生支持)========== */
#if USE_ITM_SWO
/**
* @brief 初始化 ITM必须在 main 开始时调用)
* @note 在 main() 函数的 USER CODE BEGIN 2 中调用此函数
*/
void ITM_Init(void)
{
// 1. 启用 TRCENA (Trace Enable)
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
// 2. 解锁 ITM 访问
ITM->LAR = 0xC5ACCE55;
// 3. 启用 ITM
ITM->TCR = ITM_TCR_ITMENA_Msk;
// 4. 启用 ITM 端口0用于 printf
ITM->TER = 0x01;
// 5. 设置 ITM 的 Trace Privilege
ITM->TPR = 0x00;
}
/**
* @brief 通过 ITM 端口0 发送字符
* @note Ozone 中需要配置Tools -> Terminal -> Enable SWO
*/
int __io_putchar(int ch)
{
// 直接发送,不检查(因为已经初始化过了)
while (ITM->PORT[0].u32 == 0UL)
{
__NOP(); // 等待端口就绪
}
ITM->PORT[0].u8 = (uint8_t)ch;
return ch;
}
#endif // USE_ITM_SWO
/* ========== 方案2: UART 串口输出 ========== */
#if USE_UART
#include "usart.h" // 根据你的项目调整头文件
/**
* @brief 通过 UART 发送字符
* @note 需要先在 CubeMX 中配置好 UART
*/
int __io_putchar(int ch)
{
// 假设使用 UART1根据实际情况修改
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
#endif // USE_UART
/* ========== 方案3: 半主机模式Semihosting========== */
#if USE_SEMIHOSTING
/**
* @brief 半主机模式输出
* @note 需要在链接选项中添加 --specs=rdimon.specs
* 并在 main 函数前调用 initialise_monitor_handles();
*/
// 半主机模式使用系统默认实现,无需额外代码
// 但需要在 main() 中调用:
// extern void initialise_monitor_handles(void);
// initialise_monitor_handles();
#endif // USE_SEMIHOSTING
/* ========== getchar 实现(可选)========== */
#if USE_ITM_SWO || USE_UART
int __io_getchar(void)
{
// 简单实现:返回 EOF
return EOF;
/* 如果需要从 UART 读取,可以这样实现:
uint8_t ch;
HAL_UART_Receive(&huart1, &ch, 1, HAL_MAX_DELAY);
return ch;
*/
}
#endif