QSerialPort 不一致的行为取决于起始波特率

Posted

技术标签:

【中文标题】QSerialPort 不一致的行为取决于起始波特率【英文标题】:QSerialPort inconsistent behavior depending on starting baud rate 【发布时间】:2015-03-24 01:13:51 【问题描述】:

我正在尝试使用 QSerialPort 来实现简单串行通信协议的一侧。协议接收端的板不在我的控制之下,所以我试图通过使用空 DE-9 电缆从同一板上的一个串行端口环回到另一个串行端口来调试我的一侧,并运行一个简单的依赖于相同底层传输协议代码的“监听器”应用。

传输协议要求在收到有效消息包时立即发送“确认”数据包,因此端口始终以读/写模式打开,并且在发送每个消息包后代码等待并侦听确认;直到超时时间过后,端口才会再次关闭。 编辑 4:但是,当程序不尝试发送消息或专门侦听数据时,端口 会关闭。

我发现代码的行为会有所不同,具体取决于端口的波特率Qt 程序运行之前是否匹配Qt 程序选择的波特率时间>。也就是说,我使用setBaudRate()(在发送者和侦听器中)来确定波特率,如果我将其设置为在运行我的程序之前的任何值,那么侦听器会看到正确的字节序列,但是如果我将其设置为其他内容,那么侦听器只会在串行端口上看到垃圾。

(即使侦听器看到正确的字节序列并发送确认,其他程序也看不到这些确认,我不知道为什么;我怀疑这个问题可能是相关的,但对于这个问题,这不是我的重点。)

实际使用什么波特率似乎并不重要;我只需要使用stty 在运行Qt 程序之前 设置它,即使 Qt 程序明确设置了波特率。如果我使用stty 将波特率设置为不同于 Qt 程序使用的波特率,那么侦听器会看到垃圾。

设置波特率后,我为每个端口打印了baudRate(Input)baudRate(Output)dataBits()flowControl()parity()stopBits()的值,以评估波特率是否'设置不正确或串口的其他属性是否不正确,但打印的值在每种情况下都是相同的。

我已经对stty 的其他属性进行了试验(虽然没有广泛)(例如,在运行我的程序之前将两个端口都设置为rawcooked),并且观察到除了波特率之外没有其他设置似乎有任何影响。

有没有人知道这里可能发生了什么,如何调试它,以及 QSerialPort 或 QSerialPortInfo 是否提供了适当的工具来修复任何出现的不一致?

编辑:为了澄清,我知道 Qt 波特率设置代码正在有一些效果,因为远程结束该协议(不受我控制的协议)使用 57600 波特,我可以在使用 Qt(不是 stty)之后使用该硬件发送和接收 一些 消息,以从默认 9600 到 57600。(如果我不更改波特率,则无法通信;我得到的字符与硬件实际发送的字符不匹配。)

还应该清楚的是,如果在我的程序中设置波特率没有影响,则环回测试将始终有效这一事实,Qt 代码会产生一些影响。

编辑 2: 在设置波特率之前,Qt 显然认为由baudRate() 确定的速率为 9600(默认速率),不管stty是如何设置的

另外,如果我使用 stty 将“发送”端设置为“正确”波特率,将“侦听”端设置为“错误”波特率,我会得到部分正确的行为,当两个端口都提前设置为“错误”速率(即侦听器看到消息,但发送者从未看到确认)。

编辑 3:我之前有一个编辑指出,其中一些测试是在拔下环回电缆的情况下完成的,但我刚刚意识到我错了。

Qt 版本: 5.4.0

操作系统: Debian 7

【问题讨论】:

用 strace 检查波特率是否由 Qt 设置? @HamishMoffatt 在程序执行期间,您的意思是?我知道至少发送方在两个方向上都正确设置了波特率,而听众使用的是相同的代码。 看起来stty实际上是在设置波特率(因为我们可以相信它可以工作),而Qt程序只是一个橡皮图章或什么都不做。注释掉 setBaudRate() 看看会发生什么;即我预测没有区别。 @sawdust 我认为你误解了这种情况。首先,两个 Qt 程序都使用相同的波特率设置代码,并且在启动程序之前我一直在使用 stty 将两个端口设置为相同的波特率,所以如果问题只是 setBaudRate() 什么也没做,环回测试将始终有效。其次,使用 Qt 设置波特率会影响我是否可以与其他硬件(我无法控制的那个)交换消息。 “我认为你误解了情况。” -- 也许,但不会比你更糟。使用串行端口正确编写的程序应该完全配置端口以满足其要求。任何先前的设置都不应干扰或影响程序对端口的使用。那不是你要报告的。您是在收集和报告大量实验数据,而不是分析初始化代码不完整的原因。 【参考方案1】:

事实证明,由于我正在打开和关闭端口,我正在丢失数据。当QSerialPort 关闭时,数据要么一开始就没有(由驱动程序)缓冲,要么在端口重新打开后立即被丢弃。

据推测,使用stty 设置波特率以匹配Qt 使用的波特率影响程序行为的原因是,当波特率已经是Qt 需要设置的值时, setBaudRate() 调用是空操作,关闭时不需要清理操作来恢复旧的波特率;而当Qt 确实需要更改波特率时,它必须在关闭端口时恢复旧的波特率,这会占用大量的处理时间。

【讨论】:

以上是关于QSerialPort 不一致的行为取决于起始波特率的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC:取决于 url 扩展的不一致映射行为

SwiftUI ObservableObject 的行为不一致,具体取决于调用站点的来源

有条件设置时,约束的行为不一致

Qt:支持波特率 250k 的串行库

Windows 7 上的奇怪行为 QT QSerialPort 不会更改串行 com 端口的设置

can的波特率