带线程的QSerialPort

时间:2017-06-05 17:25:01

标签: c++ multithreading qt5

我一直在努力通过Qt的串口通信大约两周的项目。首先我尝试了信号/插槽方法,它错过了一些数据。然后我决定使用一个线程,但我得到了相同的结果。当应用程序的窗口正在调整大小或最大化/最小化时,即使在窗口栏上按住鼠标左键,它也会丢失一些数据。请帮我这个条件。

MainWindow构造函数:

SerialPort *serial= new SerialPort();
serial->moveToThread(&cThread);

connect(this , &MainWindow::finished, &cThread, &QThread::quit);
connect(this , &MainWindow::destroyed, this, &SerialPort::deleteLater);
connect(serial, &SerialPort::getData, this, &MainWindow::displayData);

cThread.start();

串口读取线程:

void SerialPort::newData()
{
     mutex.lock();
     bArray.insert(bArray.length(),serial->readAll());
     mutex.unlock();

     emit getData(&bArray,&mutex);
}

SerialPort构造函数:

serial = new QSerialPort();
connect(serial, &QSerialPort::readyRead, this,  &SerialPort::newData);

bArray.clear();

fill_serial_ports();
portName = find_stm32_port();

serial->setReadBufferSize(20*1024*1024); // it's a huge buffer.
bArray.reserve(20*1024*1024);  // it's a huge buffer.

open_serial_port();

另外,我认为这可能是一个错过某些数据并写入错误跟踪器的错误。受让人说,QSerialPort永远不会丢失数据,我的代码是错误的。我很困惑,我不知道在哪里犯错误。拜托,你能检查我的其他解决方案吗?错误在哪里?

我的错误跟踪报告(不接受):https://bugreports.qt.io/browse/QTBUG-61233

4 个答案:

答案 0 :(得分:1)

Denis Shienkov在qtbugreports中解决了这个问题。您可以查看带有线程的串口的qsp-no-freeze-workaround-windows.zip示例。

链接:https://bugreports.qt.io/browse/QTBUG-61233

答案 1 :(得分:0)

尝试将内部QSerialPort对象serial移动到线程cThread

SerialPort *serial = new SerialPort();
serial->moveToThread(&cThread);
serial->serial.moveToThread(&cThread); // move you inner QSerialPort to cThread

在上面的代码中,内部字段serial->serial.moveToTheThread(...)具有魔力。

答案 2 :(得分:0)

  

当应用程序的窗口正在调整大小或最大化/最小化时,即使在窗口栏上按住鼠标左键,它也会遗漏一些数据

我编译the code you provided to a bug tracker,使用socat创建的一对虚拟串口启动它:

 socat -d -d pty,raw,echo=0 pty,raw,echo=0

并模拟发送数据块,每秒增加1个字节的大小:

#!/bin/bash
for i in {1..1000}
do
    dd if=/dev/urandom of=/dev/pts/25 bs=1 count=$i
    sleep 1
done

您的应用程序的日志如下所示:

"bytearray length:1"
"bytearray length:2"
"bytearray length:3"
"bytearray length:4"
"bytearray length:5"
"bytearray length:6"
"bytearray length:7"
...

然后我尝试调整应用程序窗口的大小,移动它,最大化/最小化,按下按钮等等。它没有任何效果:实际上,在一个相当长的测试会话期间,根本没有数据丢失(Ubuntu 16.04 x64)。因此,如果您仍然丢失数据,则问题可能出在您的虚拟COM端口中,其描述为“STMicroelectronics Virtual COM Port”。

答案 3 :(得分:0)

正如the comment中澄清的那样,问题在于

  

USBCan设备发出无法发送数据的错误,因此其错误导致正在开启。

尝试在创建QSerialPort实例serial之后立即添加以下行:

serial->setFlowControl(QSerialPort::HardwareControl);

如果您的设备支持RFC232标准,则应启用RTS(请求发送/ CTS(清除发送)线路,并使您的发送器在发送任何数据之前请求接收方准备就绪。请参阅{{3}有关详细信息。

相关问题