使用qt编写上位机程序,出现串口死掉无法接受数据的bug

项目场景:

使用qt编写上位机程序,出现串口死掉无法接受数据的bug


问题描述

串口打开后一段时间内可以接受串口数据,过了一段时间后,端口就失去了响应,观察下位机指示灯发现下位机的串口还是在正常发送数据,使用其它串口工具打开也能正常接收数据,当上位机的串口死掉之后关掉串口重新打开又能正常接收数据了,过一会儿又会死掉,关掉串口再重新打开又恢复正常。

经调试发现,串口死掉之后时的串口状态仍是open状态,查看缓冲区并没有满,调用error()方法打印错误信息为noerror


原因分析:

多种可能:

1、程序采用的信号机制来读取信息,当产生readyread信号之后,由槽函数进行数据读取并处理,数据的读取和处理位于了同一个线程,可能导致下一包数据来时,上一包的数据还在处理,无法响应readyread信号并读物数据,进而导致上位机的串口缓冲区溢出,再无法触发readyread信号;

2、程序使用了很多定时器,有可能定时器触发定时信号和readyread信号冲突了,信号没有得到处理,进而影响了后续的readyread信号产生;

等等


解决方案:

1、串口和数据处理以及UI显示分别在不同的线程中处理;

2、设置各定时器的定时周期时避免同线程内出现多定时器同时触发的情况,譬如timerA定时周期为2ms、tiemrB的定时周一为1ms,那么在两个定时器同时启动之后,在初始值分别为2ms和1ms的情况下,2ms后两个定时器会同时触发。

3、将信号与槽的连接尽量选择队列的方式,避免,信号没有被处理完,或者产生冲突;

4、设置串口超时处理函数,在串口超时处理函数里以下两行代码:

cpp 复制代码
port->clear(QSerialPort::Input);  // 仅清空输入缓冲区
QCoreApplication::processEvents(); // 强制处理事件队列‌

我是在试了1、2、3之后问题还是没有解决,甚至尝试了在超时函数里面尝试了重启串口,没想到问题没解决还出现了程序闪退的问题。最终在删掉重启串口的操作,添加4之后问题得到解决,这个bug折磨了我近半个月,好在解决了。

相关推荐
汉克老师1 天前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
小短腿的代码世界1 天前
Qt日志系统深度解析:从qDebug到企业级日志框架
开发语言·qt
智者知已应修善业1 天前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
云泽8081 天前
C++11 核心特性全解:列表初始化、右值引用与移动语义实战
开发语言·c++
AI进化营-智能译站1 天前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
Morwit1 天前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen871 天前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码1 天前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
handler011 天前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy1131 天前
Linux进程与线程编程详解
linux·c++