summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@qt.io>2020-04-20 14:19:11 +0200
committerKarsten Heimrich <karsten.heimrich@qt.io>2020-04-21 14:50:10 +0200
commit19d515266cf416f2fd003454d52331ad40e1ac07 (patch)
tree6aad6ee271aea57a8e5a596db0f887727e9fcaed
parentd029646e293ea869201d644aec53a97763513226 (diff)
Report intermediate errors while in a Modbus send/receive cycle
Task-number: QTBUG-79312 Change-Id: Iec1f9a0427bd04ebb8ceb4c66ece96e443092a6e Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/serialbus/qmodbusdevice.cpp21
-rw-r--r--src/serialbus/qmodbusdevice.h8
-rw-r--r--src/serialbus/qmodbusreply.cpp37
-rw-r--r--src/serialbus/qmodbusreply.h5
-rw-r--r--src/serialbus/qmodbusrtuserialmaster_p.h4
5 files changed, 73 insertions, 2 deletions
diff --git a/src/serialbus/qmodbusdevice.cpp b/src/serialbus/qmodbusdevice.cpp
index ab8e126..7c81ebf 100644
--- a/src/serialbus/qmodbusdevice.cpp
+++ b/src/serialbus/qmodbusdevice.cpp
@@ -217,6 +217,27 @@ void QModbusDevice::setConnectionParameter(int parameter, const QVariant &value)
*/
/*!
+ \since 6.0
+ \enum QModbusDevice::IntermediateError
+
+ This enum describes possible errors that can happen during a full send and
+ receive cycle for a Modbus reply.
+
+ \value ResponseCrcError A Modbus response with a wrong CRC was received.
+ \value ResponseRequestMismatch A Modbus response was received but did not
+ match the open request, probably due to the
+ PDU's function code not matching.
+
+ If any of the above intermediate errors occurred, the frame is likely
+ resent until the maximum number of retries has been reached.
+
+ The list of intermediate errors can be inspected from the \l QModbusReply
+ intermediate errors function.
+
+ \sa QModbusClient::numberOfRetries(), QModbusReply::intermediateErrors()
+*/
+
+/*!
\fn QModbusDevice::errorOccurred(QModbusDevice::Error error)
This signal is emitted when an error of the type, \a error, occurs.
diff --git a/src/serialbus/qmodbusdevice.h b/src/serialbus/qmodbusdevice.h
index 0e6dad7..0a51a84 100644
--- a/src/serialbus/qmodbusdevice.h
+++ b/src/serialbus/qmodbusdevice.h
@@ -86,6 +86,13 @@ public:
};
Q_ENUM(ConnectionParameter)
+ enum IntermediateError
+ {
+ ResponseCrcError,
+ ResponseRequestMismatch
+ };
+ Q_ENUM(IntermediateError)
+
explicit QModbusDevice(QObject *parent = nullptr);
~QModbusDevice();
@@ -118,6 +125,7 @@ protected:
Q_DECLARE_TYPEINFO(QModbusDevice::Error, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QModbusDevice::State, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(QModbusDevice::ConnectionParameter, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QModbusDevice::IntermediateError, Q_PRIMITIVE_TYPE);
QT_END_NAMESPACE
diff --git a/src/serialbus/qmodbusreply.cpp b/src/serialbus/qmodbusreply.cpp
index caa2dd9..e5561c2 100644
--- a/src/serialbus/qmodbusreply.cpp
+++ b/src/serialbus/qmodbusreply.cpp
@@ -53,6 +53,7 @@ public:
QString m_errorText;
QModbusResponse m_response;
QModbusReply::ReplyType m_type;
+ QVector<QModbusDevice::IntermediateError> m_intermediateErrors;
};
/*!
@@ -239,7 +240,6 @@ QString QModbusReply::errorString() const
return d->m_errorText;
}
-
/*!
Returns the type of the reply.
@@ -278,6 +278,41 @@ void QModbusReply::setRawResult(const QModbusResponse &response)
d->m_response = response;
}
+/*!
+ \since 6.0
+ \fn void intermediateErrorOccurred(QModbusDevice::IntermediateError error)
+
+ This signal is emitted when an error has been detected in the processing of
+ this reply. The error will be described by the error code \a error.
+*/
+
+/*!
+ \since 6.0
+
+ Returns the list of intermediate errors that might have happened during
+ the send-receive cycle of a Modbus request until the QModbusReply reports
+ to be finished.
+*/
+QVector<QModbusDevice::IntermediateError> QModbusReply::intermediateErrors() const
+{
+ Q_D(const QModbusReply);
+ return d->m_intermediateErrors;
+}
+
+/*!
+ \internal
+ \since 6.0
+
+ Adds an intermediate error to the list of intermediate errors.
+ This will also cause the \l intermediateErrorOccurred() signal to be emitted.
+*/
+void QModbusReply::addIntermediateError(QModbusDevice::IntermediateError error)
+{
+ Q_D(QModbusReply);
+ d->m_intermediateErrors.append(error);
+ emit intermediateErrorOccurred(error);
+}
+
QT_END_NAMESPACE
#include "moc_qmodbusreply.cpp"
diff --git a/src/serialbus/qmodbusreply.h b/src/serialbus/qmodbusreply.h
index ffefc89..7381912 100644
--- a/src/serialbus/qmodbusreply.h
+++ b/src/serialbus/qmodbusreply.h
@@ -37,6 +37,7 @@
#ifndef QMODBUSREPLY_H
#define QMODBUSREPLY_H
+#include <QtCore/qvector.h>
#include <QtSerialBus/qmodbusdataunit.h>
#include <QtSerialBus/qmodbusdevice.h>
#include <QtSerialBus/qmodbuspdu.h>
@@ -77,9 +78,13 @@ public:
void setFinished(bool isFinished);
void setError(QModbusDevice::Error error, const QString &errorText);
+ QVector<QModbusDevice::IntermediateError> intermediateErrors() const;
+ void addIntermediateError(QModbusDevice::IntermediateError error);
+
Q_SIGNALS:
void finished();
void errorOccurred(QModbusDevice::Error error);
+ void intermediateErrorOccurred(QModbusDevice::IntermediateError error);
};
Q_DECLARE_TYPEINFO(QModbusReply::ReplyType, Q_PRIMITIVE_TYPE);
diff --git a/src/serialbus/qmodbusrtuserialmaster_p.h b/src/serialbus/qmodbusrtuserialmaster_p.h
index d206eec..4c75951 100644
--- a/src/serialbus/qmodbusrtuserialmaster_p.h
+++ b/src/serialbus/qmodbusrtuserialmaster_p.h
@@ -98,7 +98,7 @@ private:
class QModbusRtuSerialMasterPrivate : public QModbusClientPrivate
{
Q_DECLARE_PUBLIC(QModbusRtuSerialMaster)
- enum State
+ enum State
{
Idle,
WaitingForReplay,
@@ -165,6 +165,7 @@ public:
qCWarning(QT_MODBUS) << "(RTU client) Discarding response with wrong CRC, received:"
<< adu.checksum<quint16>() << ", calculated CRC:"
<< QModbusSerialAdu::calculateCRC(adu.data(), adu.size());
+ m_queue.first().reply->addIntermediateError(QModbusClient::ResponseCrcError);
return;
}
@@ -172,6 +173,7 @@ public:
if (!canMatchRequestAndResponse(response, adu.serverAddress())) {
qCWarning(QT_MODBUS) << "(RTU client) Cannot match response with open request, "
"ignoring";
+ m_queue.first().reply->addIntermediateError(QModbusClient::ResponseRequestMismatch);
return;
}