summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@theqtcompany.com>2016-01-08 10:20:40 +0100
committerKarsten Heimrich <karsten.heimrich@theqtcompany.com>2016-01-08 12:25:39 +0000
commitefe6ea57e456d98d88ed50a0a6f33d3c87a0f34f (patch)
treebdbf77775b81c9464fa38bb03e9c2adff65bc8fd
parent80f89689573598c5f89693263af34e435c2777be (diff)
Implement the ClearOverrunCounterAndFlag sub-function code.
Even if machine specific, we can implement it software side; as our server can and should be a total of all available and documented functionality as described by the Modbus specs. Change-Id: I97b9eb8f6495b6ce9c2a858d22326f236d9b044b Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
-rw-r--r--src/serialbus/qmodbus_symbols_p.h10
-rw-r--r--src/serialbus/qmodbusserver.cpp8
-rw-r--r--tests/auto/qmodbusserver/tst_qmodbusserver.cpp8
3 files changed, 18 insertions, 8 deletions
diff --git a/src/serialbus/qmodbus_symbols_p.h b/src/serialbus/qmodbus_symbols_p.h
index 6ffc938..20ec329 100644
--- a/src/serialbus/qmodbus_symbols_p.h
+++ b/src/serialbus/qmodbus_symbols_p.h
@@ -69,14 +69,8 @@ enum SubFunctionCode {
ReturnServerNoResponseCount = 0x000f,
ReturnServerNAKCount = 0x0010,
ReturnServerBusyCount = 0x0011,
- ReturnBusCharacterOverrunCount = 0x0012
-
- // The Clear Overrun Counter and Flag handling for diagnostics
- // sub-code is only used in the legacy Modicon 84 and 884 PLC
- // processor system where it clears the only counter there (the
- // IOP Overrun counter which doesn't exist anywhere else) and
- // the according overrun flag bit 0 in the diagnosticRegister.
- // ClearOverrunCounterAndFlag = 0x0014 // Deliberately not implemented!
+ ReturnBusCharacterOverrunCount = 0x0012,
+ ClearOverrunCounterAndFlag = 0x0014
};
}
diff --git a/src/serialbus/qmodbusserver.cpp b/src/serialbus/qmodbusserver.cpp
index 20ddec7..f3a5a58 100644
--- a/src/serialbus/qmodbusserver.cpp
+++ b/src/serialbus/qmodbusserver.cpp
@@ -894,6 +894,14 @@ QModbusResponse QModbusServerPrivate::processDiagnosticsRequest(const QModbusReq
CHECK_SIZE_AND_CONDITION(request, (data != 0x0000));
return QModbusResponse(request.functionCode(), subFunctionCode,
m_counters[static_cast<Counter> (subFunctionCode)]);
+
+ case Diagnostics::ClearOverrunCounterAndFlag: {
+ CHECK_SIZE_AND_CONDITION(request, (data != 0x0000));
+ m_counters[Diagnostics::ReturnBusCharacterOverrunCount] = 0;
+ quint16 reg = q_func()->value(QModbusServer::DiagnosticRegister).value<quint16>();
+ q_func()->setValue(QModbusServer::DiagnosticRegister, reg &~ 1); // clear first bit
+ return QModbusResponse(request.functionCode(), request.data());
+ }
}
return QModbusExceptionResponse(request.functionCode(),
QModbusExceptionResponse::IllegalFunction);
diff --git a/tests/auto/qmodbusserver/tst_qmodbusserver.cpp b/tests/auto/qmodbusserver/tst_qmodbusserver.cpp
index 09abdd3..6c3d844 100644
--- a/tests/auto/qmodbusserver/tst_qmodbusserver.cpp
+++ b/tests/auto/qmodbusserver/tst_qmodbusserver.cpp
@@ -1189,6 +1189,14 @@ private slots:
QCOMPARE(local.setValue(QModbusServer::ListenOnlyMode, true), true);
QCOMPARE(local.value(QModbusServer::ListenOnlyMode).toBool(), true);
}
+
+ void testClearOverrunCounterAndFlag()
+ {
+ TestServer server;
+ server.setValue(QModbusServer::DiagnosticRegister, 0xffff);
+ server.processRequest(QModbusRequest(QModbusRequest::Diagnostics, quint16(0x0014), quint16(0)));
+ QCOMPARE(server.value(QModbusServer::DiagnosticRegister).value<quint16>(), quint16(0xfffe));
+ }
};
QTEST_MAIN(tst_QModbusServer)