From 551d7e54174731f628c8a2b3d58146c4fc7e0bca Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 19 Nov 2017 14:14:18 +0100 Subject: [PATCH] added arbitration delay measurement --- src/ebusd/bushandler.cpp | 32 +++++++++++++++++++++++++------- src/ebusd/bushandler.h | 34 +++++++++++++++++++++++++++++----- src/ebusd/mainloop.cpp | 8 ++++++++ 3 files changed, 62 insertions(+), 12 deletions(-) mode change 100755 => 100644 src/ebusd/mainloop.cpp diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index efb7494d..6cde6475 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -419,7 +419,7 @@ void BusHandler::run() { setState(bs_noSignal, result); } symCount = 0; - m_symLatencyMin = m_symLatencyMax = -1; + m_symbolLatencyMin = m_symbolLatencyMax = m_arbitrationDelayMin = m_arbitrationDelayMax = -1; time(&lastTime); lastTime += 2; } @@ -603,6 +603,7 @@ result_t BusHandler::handleSymbol() { logNotice(lf_bus, "acting as AUTO-SYN generator"); } m_remainLockCount = 0; + m_lastSynReceiveTime = recvTime; return setState(bs_ready, result); } } @@ -629,6 +630,7 @@ result_t BusHandler::handleSymbol() { } else if (!sending && m_remainLockCount == 0 && m_command.size() == 1) { m_remainLockCount = 1; // wait for next AUTO-SYN after SYN / address / SYN (bus locked for own priority) } + clockGettime(&m_lastSynReceiveTime); return setState(bs_ready, m_state == bs_skip ? RESULT_OK : RESULT_ERR_SYN); } @@ -686,6 +688,22 @@ result_t BusHandler::handleSymbol() { m_currentRequest = startRequest; // check arbitration if (recvSymbol == sendSymbol) { // arbitration successful + // measure arbitration delay + long long latencyLong = (sentTime.tv_sec*1000000000 + sentTime.tv_nsec + - m_lastSynReceiveTime.tv_sec*1000000000 - m_lastSynReceiveTime.tv_nsec)/1000; + if (latencyLong >= 0 && latencyLong <= 10000) { // skip clock skew or out of reasonable range + int latency = (int)latencyLong; + logDebug(lf_bus, "arbitration delay %d ns", latency); + if (m_arbitrationDelayMin < 0 || (latency < m_arbitrationDelayMin || latency > m_arbitrationDelayMax)) { + if (m_arbitrationDelayMin == -1 || latency < m_arbitrationDelayMin) { + m_arbitrationDelayMin = latency; + } + if (m_arbitrationDelayMax == -1 || latency > m_arbitrationDelayMax) { + m_arbitrationDelayMax = latency; + } + logInfo(lf_bus, "arbitration delay %d - %d ns", m_arbitrationDelayMin, m_arbitrationDelayMax); + } + } m_nextSendPos = 1; m_repeat = false; return setState(bs_sendCmd, RESULT_OK); @@ -1006,16 +1024,16 @@ void BusHandler::measureLatency(struct timespec* sentTime, struct timespec* recv } int latency = (int)latencyLong; logDebug(lf_bus, "send/receive symbol latency %d ms", latency); - if (m_symLatencyMin >= 0 && (latency >= m_symLatencyMin && latency <= m_symLatencyMax)) { + if (m_symbolLatencyMin >= 0 && (latency >= m_symbolLatencyMin && latency <= m_symbolLatencyMax)) { return; } - if (m_symLatencyMin == -1 || latency < m_symLatencyMin) { - m_symLatencyMin = latency; + if (m_symbolLatencyMin == -1 || latency < m_symbolLatencyMin) { + m_symbolLatencyMin = latency; } - if (m_symLatencyMax == -1 || latency > m_symLatencyMax) { - m_symLatencyMax = latency; + if (m_symbolLatencyMax == -1 || latency > m_symbolLatencyMax) { + m_symbolLatencyMax = latency; } - logInfo(lf_bus, "send/receive symbol latency %lld - %lld ms", m_symLatencyMin, m_symLatencyMax); + logInfo(lf_bus, "send/receive symbol latency %d - %d ms", m_symbolLatencyMin, m_symbolLatencyMax); } bool BusHandler::addSeenAddress(symbol_t address) { diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index 08a394a8..fefe2128 100644 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -378,12 +378,15 @@ class BusHandler : public WaitThread { m_masterCount(device->isReadOnly()?0:1), m_autoLockCount(lockCount == 0), m_lockCount(lockCount <= 3 ? 3 : lockCount), m_remainLockCount(m_autoLockCount ? 1 : 0), m_generateSynInterval(generateSyn ? SYN_TIMEOUT*getMasterNumber(ownAddress)+SYMBOL_DURATION : 0), - m_pollInterval(pollInterval), m_symLatencyMin(-1), m_symLatencyMax(-1), m_lastReceive(0), m_lastPoll(0), + m_pollInterval(pollInterval), m_symbolLatencyMin(-1), m_symbolLatencyMax(-1), m_arbitrationDelayMin(-1), + m_arbitrationDelayMax(-1), m_lastReceive(0), m_lastPoll(0), m_currentRequest(NULL), m_currentAnswering(false), m_runningScans(0), m_nextSendPos(0), m_symPerSec(0), m_maxSymPerSec(0), m_state(bs_noSignal), m_escape(0), m_crc(0), m_crcValid(false), m_repeat(false), m_grabMessages(true) { memset(m_seenAddresses, 0, sizeof(m_seenAddresses)); + m_lastSynReceiveTime.tv_sec = 0; + m_lastSynReceiveTime.tv_nsec = 0; } /** @@ -548,13 +551,25 @@ class BusHandler : public WaitThread { * Return the minimal measured latency between send and receive of a symbol. * @return the minimal measured latency between send and receive of a symbol in milliseconds, -1 if not yet known. */ - int getMinSymbolLatency() const { return m_symLatencyMin; } + int getMinSymbolLatency() const { return m_symbolLatencyMin; } /** * Return the maximal measured latency between send and receive of a symbol. * @return the maximal measured latency between send and receive of a symbol in milliseconds, -1 if not yet known. */ - int getMaxSymbolLatency() const { return m_symLatencyMax; } + int getMaxSymbolLatency() const { return m_symbolLatencyMax; } + + /** + * Return the minimal measured delay between received SYN and sent own master address in nanoseconds. + * @return the minimal measured delay between received SYN and sent own master address in nanoseconds, -1 if not yet known. + */ + int getMinArbitrationDelay() const { return m_arbitrationDelayMin; } + + /** + * Return the maximal measured delay between received SYN and sent own master address in nanoseconds. + * @return the maximal measured delay between received SYN and sent own master address in nanoseconds, -1 if not yet known. + */ + int getMaxArbitrationDelay() const { return m_arbitrationDelayMax; } /** * Return the number of masters already seen. @@ -678,10 +693,19 @@ class BusHandler : public WaitThread { const unsigned int m_pollInterval; /** the minimal measured latency between send and receive of a symbol in milliseconds, -1 if not yet known. */ - int m_symLatencyMin; + int m_symbolLatencyMin; /** the maximal measured latency between send and receive of a symbol in milliseconds, -1 if not yet known. */ - int m_symLatencyMax; + int m_symbolLatencyMax; + + /** the minimal measured delay between received SYN and sent own master address in nanoseconds, -1 if not yet known. */ + int m_arbitrationDelayMin; + + /** the maximal measured delay between received SYN and sent own master address in nanoseconds, -1 if not yet known. */ + int m_arbitrationDelayMax; + + /** the time of the last received SYN symbol, or 0 for never. */ + struct timespec m_lastSynReceiveTime; /** the time of the last received symbol, or 0 for never. */ time_t m_lastReceive; diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp old mode 100755 new mode 100644 index 4d391796..a6be18be --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -1569,6 +1569,10 @@ result_t MainLoop::executeInfo(const vector& args, const string& user, o *ostream << "signal: acquired\n" << "symbol rate: " << m_busHandler->getSymbolRate() << "\n" << "max symbol rate: " << m_busHandler->getMaxSymbolRate() << "\n"; + if (m_busHandler->getMinArbitrationDelay() >= 0) { + *ostream << "min arbitration nanos: " << m_busHandler->getMinArbitrationDelay() << "\n" + << "max arbitration nanos: " << m_busHandler->getMaxArbitrationDelay() << "\n"; + } if (m_busHandler->getMinSymbolLatency() >= 0) { *ostream << "min symbol latency: " << m_busHandler->getMinSymbolLatency() << "\n" << "max symbol latency: " << m_busHandler->getMaxSymbolLatency() << "\n"; @@ -1791,6 +1795,10 @@ result_t MainLoop::executeGet(const vector& args, bool* connected, ostri if (m_busHandler->hasSignal()) { *ostream << ",\n \"symbolrate\": " << m_busHandler->getSymbolRate() << ",\n \"maxsymbolrate\": " << m_busHandler->getMaxSymbolRate(); + if (m_busHandler->getMinArbitrationDelay() >= 0) { + *ostream << ",\n \"minarbitrationnanos\": " << m_busHandler->getMinArbitrationDelay() + << ",\n \"minarbitrationnanos\": " << m_busHandler->getMaxArbitrationDelay(); + } if (m_busHandler->getMinSymbolLatency() >= 0) { *ostream << ",\n \"minsymbollatency\": " << m_busHandler->getMinSymbolLatency() << ",\n \"maxsymbollatency\": " << m_busHandler->getMaxSymbolLatency();