Linux的串口是系统中用于实现串行通信的硬件接口对应的软件抽象,它遵循串行通信协议,通过逐位传输数据的方式和外部设备完成信息交互,是Linux系统连接外设、实现底层硬件通信的重要通道。

Linux串口的核心定义
串口即串行接口,和并行接口不同,它采用单条传输线逐位发送和接收数据,抗干扰能力强、传输距离远,适合长距离或者低速率的数据传输场景。在Linux系统中,串口被抽象为tty设备,所有串口相关的操作都可以通过对应的设备文件来完成,不需要直接操作硬件寄存器。
Linux串口的设备文件命名规则
Linux下的串口设备文件通常存放在/dev目录下,不同类型的串口命名规则有所区别:
- 传统物理串口一般命名为ttyS0、ttyS1等,ttyS0对应第一个物理串口,依次类推
- USB转串口设备通常命名为ttyUSB0、ttyUSB1等,插入顺序不同编号会变化
- 虚拟串口或者某些嵌入式平台的串口可能命名为ttyAMA0、ttymxc0等,和具体硬件平台相关
如何查看Linux系统中的串口信息
可以通过系统自带的命令快速查看当前可用的串口设备:
1. 查看所有串口设备
执行以下命令可以列出系统中所有的tty设备,其中包含串口设备:
# 列出/dev目录下所有tty开头的设备 ls /dev/tty* # 查看串口驱动加载情况 dmesg | grep tty
2. 查看串口参数
可以使用stty命令查看指定串口的当前配置参数,比如波特率、数据位、停止位等:
# 查看ttyUSB0的串口参数,波特率、数据位等信息都会显示 stty -F /dev/ttyUSB0 -a
Linux串口的基础配置与通信示例
Linux下操作串口通常需要配置termios结构体来设置串口参数,下面以C语言为例展示基础的串口打开和配置流程:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
int set_serial(int fd, int baud_rate) {
struct termios options;
// 获取当前串口参数
if (tcgetattr(fd, &options) != 0) {
perror("tcgetattr failed");
return -1;
}
// 设置波特率
switch (baud_rate) {
case 9600:
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
break;
case 115200:
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
break;
default:
printf("不支持的波特率n");
return -1;
}
// 设置数据位为8位
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// 无奇偶校验
options.c_cflag &= ~PARENB;
// 1位停止位
options.c_cflag &= ~CSTOPB;
// 关闭硬件流控
options.c_cflag &= ~CRTSCTS;
// 开启接收
options.c_cflag |= CREAD | CLOCAL;
// 设置等待时间和最小接收字符
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
// 清空串口缓冲区
tcflush(fd, TCIFLUSH);
// 应用配置
if (tcsetattr(fd, TCSANOW, &options) != 0) {
perror("tcsetattr failed");
return -1;
}
return 0;
}
int main() {
int fd;
char send_buf[] = "hello serialn";
char recv_buf[1024];
int nread;
// 打开串口设备,替换为实际的串口路径
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0) {
perror("open serial failed");
return -1;
}
// 配置串口波特率为115200
if (set_serial(fd, 115200) != 0) {
close(fd);
return -1;
}
// 发送数据
write(fd, send_buf, strlen(send_buf));
// 接收数据
nread = read(fd, recv_buf, sizeof(recv_buf) - 1);
if (nread > 0) {
recv_buf[nread] = ' ';
printf("接收到数据: %sn", recv_buf);
}
close(fd);
return 0;
}
Linux串口的常见应用场景
Linux串口在实际开发中有很多常见用途:
- 嵌入式开发中作为调试控制台,输出系统启动日志和调试信息
- 连接传感器、PLC、工业控制器等外部设备,采集数据或者下发控制指令
- 作为设备之间的通信通道,实现两个Linux设备或者Linux和其他系统之间的数据传输
- 老旧设备的对接,很多传统工业设备只支持串口通信,需要通过Linux串口完成交互
操作Linux串口的注意事项
操作Linux串口时需要注意几个问题:
- 普通用户默认没有串口设备的读写权限,需要把用户加入dialout用户组,或者用sudo执行操作
- 串口参数需要和外部连接设备的参数完全一致,否则会出现乱码或者无法通信的问题
- 拔插USB转串口设备后,设备编号可能会变化,建议通过udev规则绑定固定的设备别名
- 操作完串口后要及时关闭文件描述符,避免资源泄露