我的应用程序通过串行端口(USB 串行)与嵌入式系统通信。
我正在使用 gitorious 的 Qt 4.8 和 QtSerialPort 进行开发 (https://qt.gitorious.org/qt/qtserialport/),并且我还在使用 Windows 7 和 Qt 5.2.1 的虚拟机中进行测试
它在 Linux 下工作正常,但我对同一条消息进行了两次、三次、四次读取。 我可以验证这些消息仅发送一次,通过 puTTY 进行通信。
所以问题是,这是否是 QtSerialPort、VM(尽管它可以与 putty 一起使用?)、串行驱动程序...等的问题。
这是一个已知问题吗? (不过我什么也没找到) 有什么想法如何弄清楚这一点吗?
这就是我的阅读方式:
编辑:摩尔代码:
ModuleCommunicator::ModuleCommunicator(const QString &device, SBStateModel &state_model)
: upstate(UpdateDone), model(state_model)
{
port = new QSerialPort(device);
if (!port->open(QIODevice::ReadWrite /*| QIODevice::Truncate*/)) {
qDebug() << "Failed to open - Portname: " << port->portName() << endl;
qDebug() << "Error: " << port->errorString() << endl;
return;
}
port->setBaudRate(QSerialPort::Baud115200, QSerialPort::AllDirections);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setDataBits(QSerialPort::Data8);
port->setFlowControl(QSerialPort::NoFlowControl);
msgBuffer = new QStringList();
log_init = false;
connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(port, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onError(QSerialPort::SerialPortError)));
connect(port, SIGNAL(aboutToClose()), this, SLOT(devClosing()));
/* Timer for log level */
conTimer = new QTimer(this);
connect(conTimer, SIGNAL(timeout()), this, SLOT(timerFired()));
}
ModuleCommunicator::~ModuleCommunicator()
{
if (port->isOpen())
port->close();
delete msgBuffer;
delete port;
}
...
void ModuleCommunicator::onReadyRead()
{
if (port->bytesAvailable()) {
QString msg = QString(port->readAll());
msgBuffer->append(msg);
if (msg.endsWith("\n")) {
msg = msgBuffer->join("").trimmed();
msgBuffer->clear();
msgBuffer->append(msg.split("\r\n"));
} else {
return;
}
for (int i = 0; i < msgBuffer->size(); i++) {
msg = msgBuffer->at(i);
qDebug() << "MSG: " << msg << endl;
if (isResponse(msg)) {
handleMsg(msg);
}
}
msgBuffer->clear();
}
}
编辑:有趣。取消注释“flush()”可以使事情正常进行。随着冲洗,我看到了成倍的消息。但在接收端呢?是否有可能因为“flush()”而多次发送消息?
void ModuleCommunicator::handleMsg(const QString &msg)
{
// Parse msg
QSharedPointer<USBResponse> resp = QSharedPointer<USBResponse>(parse_message(msg));
if (!resp->is_valid()) {
// LOG
return; // Invalid response
}
// omitted
/* Find completion handler for response
Match to first command in Queue with same command & address,
or same command and wildcard adress */
// Omitted
// Sending next msg in queue if there is one
if (!sendQueue.isEmpty()) {
QueuedCommand qc = sendQueue.takeFirst();
QString nxtcmd = qc.cmdstr;
completionHandlerQueue.append(qc.ch);
qDebug() << "handleMsg: Sending next msg: " << qc.cmdstr;
if (port->write(nxtcmd.toLatin1()) == -1) {
qDebug() << "handleMsg: write failed!";
}
// !!! Removing the following line makes things work?!
port->flush();
}
return;
}
问题是由调用“flush”方法引起的。 写入串行端口后删除刷新调用可以解决问题。
“flush”方法似乎存在已知问题(尽管文档中的提示会很好,直到它被修复)。这是我发现的错误报告:
https://bugreports.qt-project.org/browse/QTBUG-36726
引用:
是的,flush() 方法还存在错误。请不要使用flush()。
Обнаружил аналогичную проблему в WinForms C++/CLI, при попытке считать данные возникла ошибка。 请参阅 F7 D5 00 1B 05 00 00 00 все хорошо。 请注意马斯西夫 E4 C2 00 1A 05 00 00 00 ошибка,потому что происходит множественное чтение。 проблему получилось решить вставив проверку на количество байт в массиве.
我在WinForms C++/CLI中发现了类似的问题,尝试读取数据时发生错误。 当读取数组 F7 D5 00 1B 05 00 00 00 时,一切正常。 读取数组 E4 C2 00 1A 05 00 00 00 时出现错误,因为发生了多次读取。 通过插入对数组中字节数的检查解决了问题。
if(COMPORT->BytesToRead == 8)COMPORT->Read(InputByte, 0, 8);