1. 前言

在嵌入式开发中,对于一些特殊场合我们可能需要对串口就行重定向,最常见的方式就行修改uboot的cmdline 指定console 到对应的串口。

但是还有一种特殊的场景,如果虚拟串口驱动是在操作系统起来才加载的,那么就需要在应用端进行重定向。

当我们需要在应用层将串口进行重定向时,需要以下操作:


printf重定向:应用程序的printf重定向到指定串口,而非默认cmdline指定的shell 终端重定向:shell 终端登录时,重定向到指定串口


2. 为什么要进行重定向?

一个典型的应用场景,当进行usb设备端开发时,无需将串口单独引出来,直接通过USB线,将设备模拟成一个USB 串口的复合设备,即可完成串口的调试作用。


内核及之前:默认串口打印 

系统起来后:USB串口打印


3. 如何重定向?

3.1 printf 串口重定向

首先需要将应用程序的printf重定向到指定串口:

实际操作就是将标准输入、标准输出、标准错误,从默认串口重定向到指定的虚拟串口。

此方法是在应用层操作,只作用于当前进程。如果串口在内核里面就已经加载好,直接在uboot cmdline就行

static void USB_UART_Init()                              
{
int fd = -1;
fflush(stdout);
setvbuf(stdout, NULL, _IONBF, 0);
fd = open("/dev/ttyGS0", O_RDWR); /* 需要在虚拟串口生成后调用 */
if (fd < 0) {
printf("open /dev/ttyGS0 failed\n");
return;
}

dup2(fd, 0); /* 重定向到标准输入 */
dup2(fd, 1); /* 重定向到标准输出 */
dup2(fd, 2); /* 重定向到标准错误 */
close(fd);
}

3.2. shell 终端重定向串口

其次,我们需要在虚拟串口进行终端登录、输入和显示:

修改rootfs配置:

vim /etc/inittab
#console::respawn:/sbin/getty -L console 115200 vt100 # GENERIC_SERIAL
ttyGS0::respawn:/sbin/getty -L ttyGS0 115200 vt100 # GENERIC_SERIAL

  • ttyGS0:要重定向的串口节点。比如ls /dev/ttyS1。默认console=ttyS1
  • respawn:/sbin/getty:重复启动进程getty,直到成功
  • getty -L ttyGS0 115200:终端初始化操作。

说明:系统上电后会不停的启动getty 进程,当usb 串口或者其他虚拟串口节点生成后,将指定串口重定向到指定虚拟串口

此时完成了shell 终端的重定向,即可在虚拟串口输入shell命令了。

4. 总结

本文简单介绍了,串口重定向的使用方法。读者朋友相信已经看出来了,关键就是我们的虚拟串口何时生成。如果在内核就已经加载,那么就可以通过uboot 传参修改。应用层无需添加代码。