串口读取异常:重启读取程序后无法接收LIDAR持续发送的数据
针对LIDAR串口接收异常的优化方案
1. 直接重置USB转串口设备
Prolific芯片的USB转串口在Ubuntu下容易因缓冲区残留或硬件状态异常导致接收失败,比起仅清理串口缓冲区,直接重置整个USB设备能彻底恢复初始状态:
- 先用
lsusb找到设备ID(Prolific芯片一般是067b:2303) - 安装
usbreset工具:sudo apt install usbreset - 执行重置命令:
sudo usbreset 067b:2303(替换为你的设备实际ID)
可以把这条命令加到程序启动脚本里,每次启动前先重置USB设备。
2. 完善串口初始化流程,重置UART硬件状态
仅用tcflush无法解决硬件层面的状态异常,打开串口后需要做全套重置操作:
- 先发送break信号重置UART接收逻辑:
tcsendbreak(fd, 0) - 重新配置串口参数(波特率、数据位、停止位等),确保与LIDAR参数完全匹配
- 最后调用
tcflush(fd, TCIOFLUSH)清除所有输入输出缓冲区
以下是C语言示例片段:
#include <termios.h> #include <unistd.h> #include <string.h> int setup_serial(int fd) { struct termios tty; memset(&tty, 0, sizeof(tty)); if(tcgetattr(fd, &tty) != 0) return -1; // 设置波特率,替换为你的LIDAR实际波特率 cfsetospeed(&tty, B115200); cfsetispeed(&tty, B115200); // 配置数据位、停止位、奇偶校验(按需调整) tty.c_cflag &= ~PARENB; // 无校验位 tty.c_cflag &= ~CSTOPB; // 1位停止位 tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; // 8位数据位 tty.c_cflag |= CREAD | CLOCAL; // 启用接收、忽略调制解调器状态 tty.c_cflag &= ~CRTSCTS; // 禁用硬件流控 // 设置原始模式,避免系统对数据的额外处理 tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); tty.c_iflag &= ~(IXON | IXOFF | IXANY | IGNBRK | ICRNL); tty.c_oflag &= ~OPOST; // 设置超时参数 tty.c_cc[VTIME] = 1; tty.c_cc[VMIN] = 0; if(tcsetattr(fd, TCSANOW, &tty) != 0) return -1; tcsendbreak(fd, 0); // 重置UART硬件状态 usleep(1000); tcflush(fd, TCIOFLUSH); // 清空所有缓冲区 return 0; }
3. 调大内核串口缓冲区
默认内核串口缓冲区可能无法承载每秒100帧的高数据量,通过修改内核参数扩容:
- 编辑
/etc/sysctl.conf文件,添加一行:dev.ttyUSB0.rx_buffer_size = 65536(替换ttyUSB0为你的串口设备名,缓冲区大小可根据LIDAR单帧数据量调整) - 执行
sudo sysctl -p让配置立即生效
4. 确保程序正常退出,清理串口状态
避免用kill -9强制终止程序,要让程序在退出时主动清理串口状态:
- 注册退出处理函数(比如用
atexit),在函数内先执行tcflush(fd, TCIOFLUSH),再调用close(fd)关闭串口
5. 更新Prolific驱动
Ubuntu自带的Prolific驱动可能存在兼容性bug,尝试更换官方或更新版本的驱动:
- 先卸载默认驱动:
sudo rmmod pl2303 - 下载对应内核版本的PL2303官方驱动安装,或使用第三方维护的更新版驱动
内容的提问来源于stack exchange,提问作者Timothy Miller
相关产品推荐
相关产品推荐

