嵌入式重定向串口的几种方法
嵌入式学习、做项目,经常都会用到串口,而用串口最多的时候,就是类似 printf 这种打印输出的时候。比如:打印输出日志信息
打印输出调试信息
查看实时数据等
而 printf 基本都会用到“重定向串口” ,本文结合这个问题,来简单分享一下相关内容。
嵌入式开发重定向串口的几种方法
分享“重定向串口”之前,我们先说说几种常见的 printf 方式。
针对MCU的printf打印输出,常见的方式:
1.UART打印输出
2.仿真打印输出
3.SWO打印输出
4.JLink-RTT打印输出
额外还有一些专有的调试诊断工具,比如:
5.STM Studio打印输出变量
6.STM32CubeMonitor打印输出变量
当然,以上系列教程主要是针对MCU而言,这里说说针对嵌入式开发的一些常见“重定向”串口的方法。
一、C语言中 printf 重定向
在嵌入式C语言中,printf函数通常用于向控制台输出数据。但在没有显示器的嵌入式系统中,可以通过将stdout(标准输出)重定向到串口,实现printf的串口输出。
实现方法:重新定义fputc函数,使其将字符通过串口发送出去。这样,每当printf函数调用时,就会调用重新定义的fputc函数,从而将数据发送到串口。
由于单片机性能相对要弱一点针对单片机,我们一般使用微库(不是标准C库函数)。
大部分集成开发环境(IDE)中都有【使能】微库的选项。
具体重定向代码如下:
int fputc(int ch, FILE *f)
{
USART_SendByte((uint8_t)ch);
return ch;
}
为了方便大家理解,以上提供的是比较简略的代码,还有,不同单片机以及不同环境下,可能略有差异。
二、shell终端重定向
在嵌入式Linux系统中,可以通过修改inittab文件或cmdline参数来将shell终端重定向到指定串口。例子:在嵌入式Linux系统中,将shell终端重定向到ttyGS0串口:
# 修改/etc/inittab文件
vim /etc/inittab
# 找到类似下面的行,并将其修改为指向新的串口
# console::respawn:/sbin/getty -L console 115200 vt100ttyGS0::respawn:/sbin/getty -L
ttyGS0 115200 vt100
在uboot阶段通过cmdline参数指定console到新的串口:
console=ttyGS0,115200n8
三、freopen 重定向标准输出到串口设备文件这种方法在Linux开发中比较常见,通过使用 freopen 函数来重定向标准输出(stdout)到一个串口设备文件。
比如将 stdout 重定向到串口设备文件(例如 /dev/ttyS0):
#include <stdio.h>
#include <stdlib.h>
int main()
{
// 串口设备文件的路径,例如 /dev/ttyS0
const char *serial_port = "/dev/ttyS0";
// 使用 freopen 重定向 stdout 到串口设备文件
FILE *new_stdout = freopen(serial_port, "w", stdout);
if (new_stdout == NULL) { perror("freopen failed");
return EXIT_FAILURE; }
// 测试输出到串口
printf("Hello, serial port!\n");
return EXIT_SUCCESS;}
串口最多的时候,就是类似 printf打印 串口重定向还是基础操作 printf函数通常用于向控制台输出数据 嵌入式学习、做项目,经常都会用到串口 非常有用的文章,重定向串口对于嵌入式开发来说是一个常见需求。能否详细解释一下如何针对不同的MCU进行fputc函数的重定义?
嵌入式系统中重定向串口(将 printf 等标准输出定向到串口)的方法主要有以下几种:
1. 重定义底层函数
原理:覆盖标准库的_write()或fputc()函数,将数据通过串口发送。
示例:在 ARM Cortex-M 中,可重写int _write(int file, char *ptr, int len),内部调用串口发送函数(如HAL_UART_Transmit())。
2. 使用微库(MicroLib)
原理:微库是精简版标准库,对printf等函数进行了优化,可通过配置使其输出到串口。
操作:在 Keil 中勾选 “Use MicroLib”,并实现int fputc(int ch, FILE *f)函数,将ch通过串口发送。
3. 寄存器直接操作
原理:直接访问串口数据寄存器(如 UART_DR),适用于无操作系统的裸机环境。
示例:while(!(USART1->SR & USART_SR_TXE)); USART1->DR = (uint8_t)ch;(STM32)。
4. 中断 / DMA 方式
原理:通过中断或 DMA 传输数据,避免阻塞 CPU。
实现:定义缓冲区,重定向函数将数据存入缓冲区,触发中断 / DMA 发送。
5. 使用 RTOS 的设备驱动
原理:在 RTOS(如 FreeRTOS)中,通过设备驱动框架将串口注册为标准输出设备。
优势:支持多任务并发访问,可实现异步输出。
选择方法时需结合系统资源(如是否使用 RTOS)、性能需求(是否允许阻塞)及开发环境(如是否使用微库)综合考虑。 非常实用的分享!在嵌入式开发中,串口输出是调试和监控的关键。重定向串口输出对于实时监控系统状态非常有帮助。
非常实用的分享!在嵌入式开发中,串口重定向确实是一个常见的需求。你的帖子提供了多种方法,对于我们这些初学者来说,很有帮助。
非常实用的分享,重定向串口对于嵌入式调试来说至关重要。能否再详细解释一下如何根据不同的MCU选择不同的printf方式?
页:
[1]