QtSerialPort: дублированные чтения в Windows 7
Мое приложение связывается со встроенной системой через последовательный порт (последовательный порт USB).
Я занимаюсь разработкой с Qt 4.8 и QtSerialPort из gitorious ( https://qt.gitorious.org/qt/qtserialport/), а также я тестирую на ВМ с Windows 7 и Qt 5.2.1
Он прекрасно работает под Linux, но я получаю двойное, тройное и четверное чтение одного и того же сообщения. Я могу убедиться, что эти сообщения отправляются только один раз, общаясь через puTTY.
Так что вопрос в том, является ли это проблемой с QtSerialPort, виртуальной машиной (хотя она работает с замазкой?), Драйвером последовательного порта... и т. Д.
Это известная проблема? (Я ничего не мог найти, хотя) Есть идеи, как добраться до сути этого?
вот как я читаю:
РЕДАКТИРОВАТЬ: moar code:
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;
}
1 ответ
Проблемы были вызваны вызовом метода flush. Удаление сбрасываемых вызовов после записи в последовательный порт устраняет проблему.
Кажется, что есть известные проблемы с методом "flush" (хотя подсказка в документации была бы хорошей, пока она не исправлена). Вот сообщение об ошибке, которое я нашел:
https://bugreports.qt-project.org/browse/QTBUG-36726
Цитата:
Да, метод flush() имеет ошибки. Пожалуйста, не используйте флеш ().