串口重定向的基本概念

串口重定向是将标准输入输出(如printfscanf)通过串口(UART)进行数据传输的技术,常用于嵌入式系统中调试或与外部设备通信。核心是重写_writefputc等底层函数。


实现步骤(以STM32为例)

硬件配置

确保串口硬件已初始化(如波特率、数据位、停止位等)。例如使用STM32 HAL库初始化UART:

UART_HandleTypeDef huart1;
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
HAL_UART_Init(&huart1);
重定向_write函数

syscalls.c或用户文件中重写_write函数(针对ARM GCC工具链):

#include <unistd.h>
int _write(int fd, char *ptr, int len) {
    HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY);
    return len;
}
重定向fputc(可选)

部分平台需重写fputc

int fputc(int ch, FILE *f) {
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    return ch;
}
启用MicroLib(Keil用户)

在Keil MDK中勾选Use MicroLib以优化标准库体积:

  1. 打开Options for Target → Target选项卡。
  2. 勾选Use MicroLib

验证重定向

通过printf输出测试数据:

printf("Hello, UART!\r\n");

用串口调试工具(如PuTTY)查看是否收到数据。


常见问题解决

输出乱码
  • 检查波特率是否匹配硬件配置。
  • 确保时钟源和分频系数正确。
无输出
  • 确认串口引脚(TX/RX)连接正确。
  • 验证HAL_UART_Transmit是否返回HAL_OK
内存占用过大
  • 使用-specs=nano.specs链接选项(GCC工具链)缩减库体积。
  • 避免浮点数打印(如printf("%f")),改用整数格式。

其他平台适配

Arduino

直接使用Serial对象:

Serial.begin(9600);
Serial.println("Hello");
ESP32

通过uart_driver_install初始化后,重定向stdout

setvbuf(stdout, NULL, _IONBF, 0);
esp_vfs_dev_uart_use_driver(0);

性能优化建议

  • 使用DMA传输减少CPU占用。
  • 避免高频小数据包发送,改用缓冲或批量输出。
  • 关闭不必要的中断以提高实时性。
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐