QSerialPort 不一致的行为取决于起始波特率
QSerialPort inconsistent behavior depending on starting baud rate
我正在尝试使用 QSerialPort 来实现简单串行通信协议的一侧。协议接收端的板子不在我的控制之下,所以我试图通过使用无效的 DE-9 电缆从同一板上的一个串行端口环回到另一个串行端口来调试我这边,并且 运行创建一个简单的 "listener" 应用程序,它依赖于相同的底层传输协议代码。
传输协议要求在接收到有效的消息包时立即发送一个"acknowledgment"包,因此端口始终以read/write模式打开,并且在发送每个消息包后代码等待并监听确认;在超时期限过去之前,端口不会再次关闭。 编辑 4: 端口 是 ,但是,当程序不尝试发送消息或专门监听数据时关闭。
我发现代码的行为有所不同,具体取决于 Qt 程序 运行 之前端口 的波特率是否与波特率 由Qt程序选择。也就是说,我正在使用 setBaudRate()
(在发送方和侦听器中)来确定波特率,如果我将它设置为 在我的程序 运行 之前,然后侦听器会看到正确的字节序列,但如果我将其设置为其他内容,则侦听器只会在串行端口上看到垃圾。
(即使侦听器看到正确的字节序列并发送acks,其他程序也看不到这些acks,我不确定为什么;我怀疑这个问题可能是相关的,但对于这个问题它是不是我的重点。)
实际使用的什么波特率似乎无关紧要;我只需要在 stty
before 运行 设置 Qt 程序, 即使 Qt 程序设置了波特率明确。如果我使用 stty
将波特率设置为 Qt 程序使用的波特率以外的值,听众会看到垃圾。
我已经为每个端口打印了 baudRate(Input)
、baudRate(Output)
、dataBits()
、flowControl()
、parity()
和 stopBits()
的值设置波特率后,以评估波特率是否设置不正确或串口的其他 属性 是否不正确,但打印的值在每种情况下都是相同的。
我已经对 stty
的其他属性进行了实验(虽然不是很广泛)(例如在 运行 设置我的程序之前将两个端口都设置为 raw
或 cooked
),并观察到除波特率外没有任何设置似乎有任何影响。
有没有人知道这里可能发生了什么,如何调试它,以及 QSerialPort 或 QSerialPortInfo 是否提供了适当的工具来修复出现的任何不一致?
编辑: 澄清一下,我知道 Qt 波特率设置代码是 有一些效果,因为协议的远程端(不受我控制的那个)使用 57600 波特,使用 Qt 后我可以使用该硬件发送和接收 some 消息(不是 stty
)将端口的波特率从默认的 9600 更改为 57600。(如果我不更改波特率,则无法进行通信;我得到的字符与硬件实际发送的字符不匹配.)
如果在我的程序中设置波特率没有影响,那么环回测试将始终有效,Qt 代码也会产生一些影响。
EDIT 2: 在设置波特率之前,Qt显然感知到由baudRate()
确定的速率,以为 9600(默认速率),不管 stty
.
是如何设置的
此外,如果我使用 stty
将 "sending" 端设置为 "right" 波特率,将 "listening" 端设置为 "wrong" 波特率,当两个端口都提前设置为 "wrong" 速率时,我得到了部分正确的行为(即听众看到消息,但发件人从未看到确认)。
编辑 3: 我之前进行了编辑,指出其中一些测试是在拔下环回电缆的情况下完成的,但我刚刚意识到我错了。
Qt版本:5.4.0
OS: Debian 7
事实证明,由于我打开和关闭端口,我丢失了数据。当 QSerialPort
关闭时,数据要么不首先(由驱动程序)缓冲,要么在端口重新打开后立即丢弃。
据推测,使用 stty
设置波特率以匹配 Qt
使用的波特率影响程序行为的原因是,当波特率已经是 Qt
需要将其设置为,setBaudRate()
调用是空操作,关闭时不需要清理操作来恢复旧的波特率;而当Qt
确实需要更改波特率时,它必须也在关闭端口时恢复旧的波特率,这需要增加了大量的处理时间。
我正在尝试使用 QSerialPort 来实现简单串行通信协议的一侧。协议接收端的板子不在我的控制之下,所以我试图通过使用无效的 DE-9 电缆从同一板上的一个串行端口环回到另一个串行端口来调试我这边,并且 运行创建一个简单的 "listener" 应用程序,它依赖于相同的底层传输协议代码。
传输协议要求在接收到有效的消息包时立即发送一个"acknowledgment"包,因此端口始终以read/write模式打开,并且在发送每个消息包后代码等待并监听确认;在超时期限过去之前,端口不会再次关闭。 编辑 4: 端口 是 ,但是,当程序不尝试发送消息或专门监听数据时关闭。
我发现代码的行为有所不同,具体取决于 Qt 程序 运行 之前端口 的波特率是否与波特率 由Qt程序选择。也就是说,我正在使用 setBaudRate()
(在发送方和侦听器中)来确定波特率,如果我将它设置为 在我的程序 运行 之前,然后侦听器会看到正确的字节序列,但如果我将其设置为其他内容,则侦听器只会在串行端口上看到垃圾。
(即使侦听器看到正确的字节序列并发送acks,其他程序也看不到这些acks,我不确定为什么;我怀疑这个问题可能是相关的,但对于这个问题它是不是我的重点。)
实际使用的什么波特率似乎无关紧要;我只需要在 stty
before 运行 设置 Qt 程序, 即使 Qt 程序设置了波特率明确。如果我使用 stty
将波特率设置为 Qt 程序使用的波特率以外的值,听众会看到垃圾。
我已经为每个端口打印了 baudRate(Input)
、baudRate(Output)
、dataBits()
、flowControl()
、parity()
和 stopBits()
的值设置波特率后,以评估波特率是否设置不正确或串口的其他 属性 是否不正确,但打印的值在每种情况下都是相同的。
我已经对 stty
的其他属性进行了实验(虽然不是很广泛)(例如在 运行 设置我的程序之前将两个端口都设置为 raw
或 cooked
),并观察到除波特率外没有任何设置似乎有任何影响。
有没有人知道这里可能发生了什么,如何调试它,以及 QSerialPort 或 QSerialPortInfo 是否提供了适当的工具来修复出现的任何不一致?
编辑: 澄清一下,我知道 Qt 波特率设置代码是 有一些效果,因为协议的远程端(不受我控制的那个)使用 57600 波特,使用 Qt 后我可以使用该硬件发送和接收 some 消息(不是 stty
)将端口的波特率从默认的 9600 更改为 57600。(如果我不更改波特率,则无法进行通信;我得到的字符与硬件实际发送的字符不匹配.)
如果在我的程序中设置波特率没有影响,那么环回测试将始终有效,Qt 代码也会产生一些影响。
EDIT 2: 在设置波特率之前,Qt显然感知到由baudRate()
确定的速率,以为 9600(默认速率),不管 stty
.
此外,如果我使用 stty
将 "sending" 端设置为 "right" 波特率,将 "listening" 端设置为 "wrong" 波特率,当两个端口都提前设置为 "wrong" 速率时,我得到了部分正确的行为(即听众看到消息,但发件人从未看到确认)。
编辑 3: 我之前进行了编辑,指出其中一些测试是在拔下环回电缆的情况下完成的,但我刚刚意识到我错了。
Qt版本:5.4.0
OS: Debian 7
事实证明,由于我打开和关闭端口,我丢失了数据。当 QSerialPort
关闭时,数据要么不首先(由驱动程序)缓冲,要么在端口重新打开后立即丢弃。
据推测,使用 stty
设置波特率以匹配 Qt
使用的波特率影响程序行为的原因是,当波特率已经是 Qt
需要将其设置为,setBaudRate()
调用是空操作,关闭时不需要清理操作来恢复旧的波特率;而当Qt
确实需要更改波特率时,它必须也在关闭端口时恢复旧的波特率,这需要增加了大量的处理时间。