QextSerialPort (QIODevice) 的 readyRead() 信号调用速度不够快

Posted

技术标签:

【中文标题】QextSerialPort (QIODevice) 的 readyRead() 信号调用速度不够快【英文标题】:readyRead() signal of QextSerialPort (QIODevice) is not being called fast enough 【发布时间】:2013-08-06 14:18:37 【问题描述】:

我在 Raspberry Pi 上使用 qextserialport 与 PanStamp(Arduino 兼容设备)进行通信。

这个连接到 Pi 的 PanStamp 执行两个功能:

每秒发送一些传感器读数(大约 12 个字节); 通过无线链路发送它接收到的所有数据(大约 60 字节,大约每秒 6 次)。

我的架构是:

集线器:PanStamp + Raspberry Pi; 卫星:PanStamp + 一些传感器。

有两种情况:

卫星以无线方式向集线器发送数据。在这种情况下,树莓派每秒都会通过它的串口接收大量数据; 卫星关闭,Pi 每秒通过串口接收大约 12 个字节。

当卫星关闭时,readyRead() 信号不会在每次字节到达时产生,它会将我的程序驱动到“不同步”状态,其中每个数据包读取一个或多个留在缓冲区中(保持增长)。

但是,当我打开卫星并且 Pi 开始接收大量数据时,这种“不同步”情况消失了,出现了数据突发(缓冲区增长得更快,之后被清空),我的程序开始“实时”工作。

这是我的程序输出的示例:www.tiago.eti.br/storage/iSEDE.log

正如您在日志中看到的那样,可用字节数不断增长,并且每秒发送一次数据(以HUB: 开头的行不是每秒都在处理。开头有一个时间戳)。过了一会儿,爆发(卫星已打开)并且每秒处理大量数据,开始处理卫星的数据(以8开头的行),缓冲区被清空,我的程序开始“实时”处理数据。

那么我该怎么做才能避免缓冲区增长过多并且不丢失数据呢? 当缓冲区大于 100 字节时,我尝试调用连接到 readyRead() 的函数,但它造成了混乱,我开始丢失一些数据包。

【问题讨论】:

请发布一些代码,尤其是您从QIODevice 读取的代码。 有什么理由不使用 QtSerialPort? 是的,当我第一次使用串口时(几年前)Qt QtSerialPort 不可用,所以我使用了我已经知道的。 【参考方案1】:

您的问题是人们使用 QIODevice 时最常犯的错误。您错误地假设每个字节都调用了 readyRead,并说如果它像这样工作将是完全错误的。想法是,每次您收到 readyRead 时,都会从设备中读取 SOMETHING .. 它可以是 1 字节、10 字节、1k .. 等等。简而言之,这样做是为了最小化在块传输的情况下以及在硬件上加载以块而不是字节为单位读取数据的 CPU 负载。

所以你应该做的是调用 readAll() 来获取所有到达的可用数据并以你喜欢的方式处理它们。

你可能想看看here..

【讨论】:

以上是关于QextSerialPort (QIODevice) 的 readyRead() 信号调用速度不够快的主要内容,如果未能解决你的问题,请参考以下文章

Qt 控制台应用程序:while 循环阻止事件循环

QIODevice::write : 设备未打开

连接 QMediaPlayer 和 QIODevice

如何确定要读取的 QIODevice 的总大小?

实现 QIODevice::writeData,文档混乱

如何摆脱 QIoDevice 中的 memcpy