在 Ubuntu 中测试串口通信:详细指南与实践
目录
- 1. 什么是串口通信?
- 2. 准备工作
- 2.1 检查串口设备
- 2.2 配置用户权限
- 2.3 安装必要工具
- 3. 使用工具测试串口通信
- 3.1 使用 minicom 测试
- 步骤
- 3.2 使用 socat 创建虚拟串口对
- 4. 使用 C 程序测试串口通信
- 4.1 编译测试程序
- 4.2 运行测试程序
- 4.3 代码分析
- 5. 故障排查
- 5.1 设备未找到
- 5.2 权限问题
- 5.3 接收乱码
- 5.4 接收超时
- 6. 高级测试:使用 strace 监控
- 7. 总结
串口通信在嵌入式开发、硬件调试和工控设备交互中扮演着重要角色。无论是连接 Arduino、PLC、传感器,还是调试工业设备,掌握在 Ubuntu 上测试串口通信的方法都至关重要。本文将详细介绍如何在 Ubuntu 中测试串口通信,涵盖环境准备、工具使用、代码测试和故障排查,提供清晰的步骤和详细的输出示例,帮助开发者快速上手并高效调试。
1. 什么是串口通信?
串口通信(Serial Communication)是一种通过单条通信线路逐位传输数据的通信方式,因其简单可靠,广泛应用于嵌入式系统、微控制器和工业设备。串口通信的关键参数包括:
- 波特率:数据传输速度,如 9600、115200 比特/秒。
- 数据位:每个字符的位数,通常为 7 或 8。
- 停止位:标记字符传输结束,通常为 1 或 2。
- 校验位:用于错误检测,可选无、奇校验或偶校验。
- 流控制:硬件或软件流控制,管理数据传输。
在 Linux(如 Ubuntu)中,串口设备表现为设备文件,如 /dev/ttyS0
(硬件串口)或 /dev/ttyUSB0
(USB 转串口)。
2. 准备工作
在 Ubuntu 中测试串口通信前,需要完成以下准备工作:
2.1 检查串口设备
首先,确认系统是否识别到串口设备。运行以下命令查看可用串口:
sudo dmesg | grep tty
示例输出:
[ 0.117304] printk: console [tty0] enabled
[ 0.793135] 0000:00:16.3: ttyS4 at I/O 0x3060 (irq = 19, base_baud = 115200) is a 16550A
[ 4.136977] usb 3-6.3.2: FTDI USB Serial Device converter now attached to ttyUSB0
ttyS0
、ttyS4
表示硬件串口,ttyUSB0
表示 USB 转串口设备。- 如果使用 USB 转串口适配器(如 FTDI 或 CP2102 芯片),通常会看到
ttyUSB*
或ttyACM*
。
确认设备文件:
ls -l /dev/ttyS* /dev/ttyUSB* /dev/ttyACM*
示例输出:
crw-rw---- 1 root dialout 4, 64 Aug 9 10:00 /dev/ttyS0
crw-rw---- 1 root dialout 188, 0 Aug 9 10:00 /dev/ttyUSB0
设备文件权限归属 dialout
组,普通用户需加入该组。
2.2 配置用户权限
普通用户需要加入 dialout
组以访问串口设备:
sudo usermod -a -G dialout $USER
验证是否成功:
groups
示例输出:
user adm cdrom sudo dip plugdev lpadmin sambashare dialout
- 确认
dialout
在列表中。 - 可能需要注销或重启使权限生效:
sudo reboot
2.3 安装必要工具
测试串口通信需要以下工具:
- minicom:终端仿真器,适合交互式测试。
- setserial:查看和配置串口参数。
- socat:创建虚拟串口对,便于测试。
安装命令:
sudo apt update
sudo apt install minicom setserial socat
验证安装:
minicom --version
setserial -V
socat -V
示例输出:
minicom version 2.8 (compiled Jan 29, 2021)
setserial version 2.17
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
3. 使用工具测试串口通信
以下介绍两种常用方法:使用 minicom
进行交互式测试,以及使用 C 程序进行自动化测试。
3.1 使用 minicom 测试
minicom
是一个强大的串口终端工具,支持配置波特率、查看数据和发送命令。
步骤
-
启动 minicom:
minicom -D /dev/ttyUSB0 -b 115200
-D /dev/ttyUSB0
:指定串口设备。-b 115200
:设置波特率。- 如果遇到权限问题,使用
sudo minicom ...
。
-
查看数据:
- 连接设备后,minicom 会显示从串口接收的数据。
- 输入字符会发送到设备(需设备支持回显或回复)。
-
退出 minicom:
- 按
Ctrl+A
,然后按X
,选择Yes
退出。
- 按
示例输出(假设连接到 Arduino,运行回显程序):
Welcome to minicom 2.8
PORT /dev/ttyUSB0, 10:15:23
Press CTRL-A Z for help on special keys
Hello, Serial!
- 输入
test
,设备回显test
(需设备支持)。
注意:
- 确保波特率与设备一致,否则可能接收到乱码。
- 如果 minicom 无法启动,检查设备路径或权限。
3.2 使用 socat 创建虚拟串口对
如果没有物理串口设备,可以使用 socat
创建虚拟串口对进行测试:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
示例输出:
2025/08/09 10:20:45 socat[12345] N PTY is /dev/pts/1
2025/08/09 10:20:45 socat[12345] N PTY is /dev/pts/2
- 打开两个终端:
- 终端 1:
minicom -D /dev/pts/1 -b 115200
- 终端 2:
echo "test" > /dev/pts/2
或cat < /dev/pts/2
- 终端 1:
- 在终端 1 的 minicom 中应看到
test
。
4. 使用 C 程序测试串口通信
为了更灵活地测试串口通信,可以使用之前提供的 serial_module.h
和 serial_module.c
,结合测试用例 serial_test.c
。以下是关键步骤和完整输出。
4.1 编译测试程序
假设你有以下文件:
serial_module.h
:串口模块头文件。serial_module.c
:串口模块实现。serial_test.c
:测试用例。
编译命令:
gcc -o serial_test serial_module.c serial_test.c
4.2 运行测试程序
运行测试程序,假设串口设备为 /dev/ttyUSB0
:
./serial_test
示例输出(假设连接到支持回显的设备):
测试1: 初始化串口设备 /dev/ttyUSB0...
初始化成功,打开状态: 1
测试2: 发送消息 'Hello, Serial!'...
发送成功,发送字节数: 14
测试3: 接收数据(最大 128 字节)...
接收成功,接收字节数: 14,数据: Hello, Serial!
测试4: 接收指定长度数据(期望 10 字节)...
接收成功,接收字节数: 10,数据: 48 65 6c 6c 6f 2c 20 53 65 72
测试5: 测试接收超时...
接收超时,如预期: 超时 (errno: 0)
测试6: 测试无效参数...
无效参数检测成功: 参数无效 (errno: 0)
测试7: 测试切换波特率到9600...
重新初始化成功,打开状态: 1
清理: 去初始化串口...
测试完成!
无设备时的输出(测试3和测试4可能超时):
测试1: 初始化串口设备 /dev/ttyUSB0...
初始化成功,打开状态: 1
测试2: 发送消息 'Hello, Serial!'...
发送成功,发送字节数: 14
测试3: 接收数据(最大 128 字节)...
接收失败: 超时 (errno: 0)
测试4: 接收指定长度数据(期望 10 字节)...
接收失败: 超时 (errno: 0)
测试5: 测试接收超时...
接收超时,如预期: 超时 (errno: 0)
测试6: 测试无效参数...
无效参数检测成功: 参数无效 (errno: 0)
测试7: 测试切换波特率到9600...
重新初始化成功,打开状态: 1
清理: 去初始化串口...
测试完成!
4.3 代码分析
- 初始化:
serial_init
配置波特率(115200)、8N1,验证设备打开。 - 发送/接收:
serial_send
和serial_recv
使用write
和read
,结合select
实现超时。 - 指定长度接收:
serial_recv_all
确保接收 10 字节,适合固定长度协议。 - 错误处理:测试无效参数和超时,验证模块鲁棒性。
- 配置切换:重新初始化为 9600 波特率,验证灵活性。
5. 故障排查
以下是常见问题及解决方法:
5.1 设备未找到
- 问题:
dmesg | grep tty
无输出,或设备文件不存在。 - 解决:
- 确认 USB 转串口适配器已连接:
lsusb
查看 USB 设备。 - 检查驱动:FTDI 芯片需
ftdi_sio
,CP2102 需cp210x
。 - 重新插拔设备,查看
dmesg
输出。
- 确认 USB 转串口适配器已连接:
5.2 权限问题
- 问题:
Permission denied
或 minicom 无法打开设备。 - 解决:
- 确认用户在
dialout
组:groups
。 - 临时提升权限:
sudo chmod 666 /dev/ttyUSB0
。 - 永久加入
dialout
组并重启。
- 确认用户在
5.3 接收乱码
- 问题:接收数据为乱码或无意义字符。
- 解决:
- 确认波特率匹配:设备和程序(如 minicom 或 C 代码)需一致。
- 检查数据位、停止位、校验位配置。
- 使用
setserial
查看串口参数:
示例输出:setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0 Baud_base: 115200, close_delay: 0, divisor: 0
- 若参数不匹配,使用
setserial
调整:sudo setserial /dev/ttyUSB0 baud_base 115200 spd_normal
- 若参数不匹配,使用
5.4 接收超时
- 问题:
serial_recv
或serial_recv_all
返回SERIAL_ERR_TIMEOUT
。 - 解决:
- 确认设备是否发送数据:使用 minicom 测试。
- 增加超时时间:修改
timeout_ms
(如 5000)。 - 检查硬件连接:确保 TX/RX 线正确连接。
6. 高级测试:使用 strace 监控
对于深入调试,可以使用 strace
监控串口 I/O 操作:
strace -tt -e read=all -e write=all -e trace=ioctl,read,write -o serial_trace.txt ./serial_test
示例输出(部分):
20:30:45.123456 open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY) = 3
20:30:45.123789 ioctl(3, TCGETS, {c_iflag=0, c_oflag=0, c_cflag=B115200|CS8|CREAD|CLOCAL, ...}) = 0
20:30:45.124012 write(3, "Hello, Serial!\0", 14) = 14
20:30:45.124567 read(3, "Hello, Serial!\0", 128) = 14
- 分析
serial_trace.txt
可查看低级 I/O 操作和配置细节,帮助定位问题。
7. 总结
在 Ubuntu 中测试串口通信可以通过命令行工具(如 minicom
、socat
)或自定义 C 程序实现。本文提供了详细的步骤和示例输出:
- 使用
dmesg
和ls
查找串口设备。 - 配置用户权限以访问串口。
- 使用
minicom
进行交互式测试,socat
模拟虚拟串口。 - 通过 C 程序(
serial_test.c
)自动化测试,验证初始化、发送、接收和错误处理。 - 提供故障排查方法,解决设备未找到、权限问题、乱码和超时等常见问题。
通过以上步骤,你可以轻松在 Ubuntu 上测试串口通信,无论是调试 Arduino、配置工业设备,还是开发嵌入式应用。希望这篇指南为你提供了清晰的指引!
参考资料:
- Ubuntu 串口通信文档
- Linux 串口监控工具
- setserial 命令使用