在嵌入式系统开发中,ARM Linux平台的串口通信是设备调试、数据传输和人机交互的重要手段,正确配置串口参数、确保数据传输的稳定性和可靠性,是开发过程中的关键环节,本文将详细介绍ARM Linux串口设置的完整流程,包括硬件连接、驱动加载、参数配置及常见问题排查,帮助开发者快速掌握串口调试技能。

串口硬件基础与连接
ARM Linux串口通常基于UART(Universal Asynchronous Receiver/Transmitter)硬件外设,常见的有UART0、UART1等,硬件连接时,需注意交叉连接原则:发送端(TXD)连接接收端(RXD),接收端(RXD)连接发送端(TXD),地线(GND)共地,对于RS-232标准,还需使用电平转换芯片(如MAX3232)实现TTL电平与RS-232电平的转换;而RS-485标准则需要支持半双工通信的收发器芯片。
在开发板上,串口接口通常为4针(TX、RX、GND、VCC)或9针DB9连接器,连接时需确认电压等级(3.3V或5V),避免电平不匹配导致硬件损坏,部分开发板(如树莓派)提供多个串口,其中UART0常用于系统调试输出,而其他串口可用于自定义通信。
设备树与驱动加载
ARM Linux的串口配置始于设备树(Device Tree),设备树源文件(.dts)中定义了串口控制器的寄存器地址、中断号、时钟频率等属性,以树莓派4B的串口配置为例,在bcm2711-rpi-4-b.dts文件中,UART1的定义如下:
uart1: serial@7d001000 {
compatible = "brcm,bcm2835-aux-uart";
reg = <0x7d001000 0x20>;
interrupts = <2 1>;
clocks = <&clocks AUXUART>;
status = "okay";
}; 编译设备树并加载到内核后,可通过ls /dev/命令查看串口设备节点(如/dev/ttyS1、/dev/ttyAMA0),若串口未自动识别,需检查设备树中status属性是否为"okay",并确认内核配置中启用对应驱动(CONFIG_SERIAL_AMBA_PL011=y)。
串口参数配置
串口通信的核心参数包括波特率、数据位、停止位、校验位和流控,这些参数可通过stty命令动态配置,也可通过termios结构在编程中设置,以下是常用配置示例:

使用stty命令配置
# 设置波特率为115200,8位数据位,无校验,1位停止位,无流控 stty -F /dev/ttyS1 115200 cs8 -cstopb -parenb -crtscts # 查看当前配置 stty -F /dev/ttyS1 -a
通过termios编程配置(C语言示例)
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
int init_serial(const char *dev, int baud) {
int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) return -1;
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, baud);
cfsetospeed(&options, baud);
options.c_cflag &= ~PARENB; // 无校验
options.c_cflag &= ~CSTOPB; // 1位停止位
options.c_cflag &= ~CSIZE; // 清除数据位设置
options.c_cflag |= CS8; // 8位数据位
options.c_cflag &= ~CRTSCTS; // 无流控
options.c_cflag |= (CLOCAL | CREAD); // 忽略调制解调器控制,启用接收
tcsetattr(fd, TCSANOW, &options);
return fd;
} 常用串口参数对照表
| 参数 | 可选值 | 说明 |
|---|---|---|
| 波特率 | 9600, 19200, 38400, 57600, 115200 | 通信速率 |
| 数据位 | 5, 6, 7, 8 | 通常为8位 |
| 校验位 | N(无), E(偶校验), O(奇校验) | 错误检测 |
| 停止位 | 1, 2 | 通常为1位 |
| 流控 | none, hardware(RTS/CTS) | 防止数据溢出 |
串口数据收发与调试
配置完成后,可通过minicom、screen或cat等工具进行串口调试,使用minicom连接串口:
minicom -D /dev/ttyS1 -b 115200
在编程中,使用read()和write()函数进行数据收发,需注意串口是阻塞设备,可通过O_NONBLOCK标志或select()/poll()实现非阻塞读取。
char buf[1024];
int n = read(fd, buf, sizeof(buf));
if (n > 0) {
printf("Received: %.*sn", n, buf);
} 常见问题排查
- 串口无法识别:检查设备树配置、内核驱动是否启用,以及设备节点是否存在(
ls /dev/tty*)。 - 数据乱码:确认波特率、数据位等参数两端一致,检查电平匹配和硬件连接。
- 数据丢失:启用硬件流控(RTS/CTS)或降低波特率,调整缓冲区大小。
- 权限问题:确保用户在
dialout组中(sudo usermod -aG dialout $USER)。
高级配置与应用
多串口优先级
在设备树中,通过assigned-clocks和assigned-clock-rates调整串口时钟优先级,避免高优先级设备占用过多资源。
系统启动信息重定向
修改cmdline.txt(如树莓派)将内核输出重定向到串口:
console=serial0,115200 串口透传与网络
使用ser2net工具将串口数据转换为TCP流,实现远程调试:

ser2net {
connection: #001:raw:600:/dev/ttyS1:115200 8DATABITS NONE 1STOPBIT banner
} FAQs
Q1: 如何在ARM Linux中实现串口数据的实时监听?
A1: 可使用cat /dev/ttyS1 &后台监听,或通过socat工具实现更灵活的监听,
socat -d -d pty,raw,echo=0 pty,raw,echo=0
创建两个伪终端对,分别连接到物理串口和网络端口,实现数据转发,可编写Python脚本结合pyserial库,实现数据解析与实时显示。
Q2: 串口通信中偶发数据丢失的原因及解决方法?
A2: 常见原因包括:
- 缓冲区溢出:增大
termios中的c_cc[VMIN]和c_cc[VTIME],或启用非阻塞模式及时读取数据。 - 电磁干扰:使用屏蔽双绞线,远离高频电路,或改用RS-485等抗干扰接口。
- 流控未启用:在
c_cflag中启用硬件流控(CRTSCTS)或软件流控(IXON/IXOFF)。 - 驱动性能不足:调整内核串口驱动缓冲区大小(
uart.tx_busy_timeout参数)。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复