diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index 5fccbc78..e34201bb 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -433,7 +433,7 @@ result_t BusHandler::handleSymbol() { // check if another symbol has to be sent and determine timeout for receive switch (m_state) { case bs_noSignal: - timeout = m_generateSynInterval > 0 ? m_generateSynInterval+m_transferLatency : SIGNAL_TIMEOUT; + timeout = m_generateSynInterval > 0 ? m_generateSynInterval : SIGNAL_TIMEOUT; break; case bs_skip: @@ -485,7 +485,7 @@ result_t BusHandler::handleSymbol() { break; case bs_recvCmdAck: - timeout = m_slaveRecvTimeout+(m_currentRequest ? m_transferLatency : 0); + timeout = m_slaveRecvTimeout; break; case bs_recvRes: @@ -498,7 +498,7 @@ result_t BusHandler::handleSymbol() { break; case bs_recvResAck: - timeout = m_slaveRecvTimeout+m_transferLatency; + timeout = m_slaveRecvTimeout; break; case bs_sendCmd: @@ -565,9 +565,9 @@ result_t BusHandler::handleSymbol() { clockGettime(&sentTime); if (result == RESULT_OK) { if (m_state == bs_ready) { - timeout = m_transferLatency+m_busAcquireTimeout; + timeout = m_busAcquireTimeout; } else { - timeout = m_transferLatency+SEND_TIMEOUT; + timeout = SEND_TIMEOUT; } } else { sending = false; @@ -579,7 +579,7 @@ result_t BusHandler::handleSymbol() { // receive next symbol (optionally check reception of sent symbol) symbol_t recvSymbol; ArbitrationState arbitrationState = as_none; - result = m_device->recv(timeout+m_transferLatency, &recvSymbol, &arbitrationState); + result = m_device->recv(timeout, &recvSymbol, &arbitrationState); if (sending) { clockGettime(&recvTime); } @@ -593,7 +593,7 @@ result_t BusHandler::handleSymbol() { } clockGettime(&sentTime); recvSymbol = ESC; - result = m_device->recv(SEND_TIMEOUT+m_transferLatency, &recvSymbol, &arbitrationState); + result = m_device->recv(SEND_TIMEOUT, &recvSymbol, &arbitrationState); clockGettime(&recvTime); if (result != RESULT_OK) { logError(lf_bus, "unable to receive sent AUTO-SYN symbol: %s", getResultCode(result)); diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index da93e88c..e9190fe8 100755 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -378,14 +378,14 @@ class BusHandler : public WaitThread { BusHandler(Device* device, MessageMap* messages, symbol_t ownAddress, bool answer, unsigned int busLostRetries, unsigned int failedSendRetries, - unsigned int transferLatency, unsigned int busAcquireTimeout, unsigned int slaveRecvTimeout, + unsigned int busAcquireTimeout, unsigned int slaveRecvTimeout, unsigned int lockCount, bool generateSyn, unsigned int pollInterval) : WaitThread(), m_device(device), m_reconnect(false), m_messages(messages), m_ownMasterAddress(ownAddress), m_ownSlaveAddress(getSlaveAddress(ownAddress)), m_answer(answer), m_addressConflict(false), m_busLostRetries(busLostRetries), m_failedSendRetries(failedSendRetries), - m_transferLatency(transferLatency), m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout), + m_busAcquireTimeout(busAcquireTimeout), m_slaveRecvTimeout(slaveRecvTimeout), 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), @@ -686,9 +686,6 @@ class BusHandler : public WaitThread { /** the number of times a failed send is repeated (other than lost arbitration). */ const unsigned int m_failedSendRetries; - /** the bus transfer latency in microseconds. */ - const unsigned int m_transferLatency; - /** the maximum time in microseconds for bus acquisition. */ const unsigned int m_busAcquireTimeout; diff --git a/src/ebusd/main.cpp b/src/ebusd/main.cpp index a1924f35..4f07eec6 100644 --- a/src/ebusd/main.cpp +++ b/src/ebusd/main.cpp @@ -1306,7 +1306,11 @@ int main(int argc, char* argv[]) { } // open the device - Device *device = Device::create(opt.device, !opt.noDeviceCheck, opt.readOnly, opt.initialSend); + unsigned int latency = 0; + if (opt.latency >= 0) { + latency = (unsigned int)opt.latency; + } + Device *device = Device::create(opt.device, latency, !opt.noDeviceCheck, opt.readOnly, opt.initialSend); if (device == nullptr) { logError(lf_main, "unable to create device %s", opt.device); return EINVAL; diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index a1fca732..581894fc 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -141,16 +141,10 @@ MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messag } } // create BusHandler - unsigned int latency; - if (opt.latency < 0) { - latency = device->getLatency(); - } else { - latency = (unsigned int)opt.latency; - } m_busHandler = new BusHandler(m_device, m_messages, m_address, opt.answer, opt.acquireRetries, opt.sendRetries, - latency, opt.acquireTimeout, opt.receiveTimeout, + opt.acquireTimeout, opt.receiveTimeout, opt.masterCount, opt.generateSyn, opt.pollInterval); m_busHandler->start("bushandler"); diff --git a/src/lib/ebus/device.cpp b/src/lib/ebus/device.cpp index b95e0d0b..a8d471dd 100755 --- a/src/lib/ebus/device.cpp +++ b/src/lib/ebus/device.cpp @@ -73,17 +73,9 @@ namespace ebusd { #define ENH_BYTE2 ((uint8_t)0x80) #define makeEnhancedSequence(cmd, data) {(uint8_t)(ENH_BYTE1 | ((cmd)<<2) | (((data)&0xc0)>>6)), (uint8_t)(ENH_BYTE2 | ((data)&0x3f))} -/** - * Construct a new instance. - * @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network). - * @param address the socket address of the device. - * @param readOnly whether to allow read access to the device only. - * @param initialSend whether to send an initial @a ESC symbol in @a open(). - * @param udp true for UDP, false to TCP. - * @param enhancedProto whether to use the ebusd enhanced protocol. - */ -Device::Device(const char* name, bool checkDevice, bool readOnly, bool initialSend, bool enhancedProto) - : m_name(name), m_checkDevice(checkDevice), m_readOnly(readOnly), m_initialSend(initialSend), +Device::Device(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend, + bool enhancedProto) + : m_name(name), m_checkDevice(checkDevice), m_latency(latency), m_readOnly(readOnly), m_initialSend(initialSend), m_enhancedProto(enhancedProto), m_fd(-1), m_listener(nullptr), m_arbitrationMaster(SYN), m_arbitrationCheck(false), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0) { m_buffer = reinterpret_cast(malloc(m_bufSize)); @@ -99,7 +91,7 @@ Device::~Device() { } } -Device* Device::create(const char* name, bool checkDevice, bool readOnly, bool initialSend) { +Device* Device::create(const char* name, unsigned int extraLatency, bool checkDevice, bool readOnly, bool initialSend) { bool enhanced = strncmp(name, "enh:", 4) == 0; if (enhanced) { name += 4; @@ -134,10 +126,10 @@ Device* Device::create(const char* name, bool checkDevice, bool readOnly, bool i *portpos = 0; char* hostOrIp = strdup(addrpos); free(in); - return new NetworkDevice(name, hostOrIp, port, readOnly, initialSend, udp, enhanced); + return new NetworkDevice(name, hostOrIp, port, extraLatency, readOnly, initialSend, udp, enhanced); } // support enh:/dev/ - return new SerialDevice(name, checkDevice, readOnly, initialSend, enhanced); + return new SerialDevice(name, checkDevice, extraLatency, readOnly, initialSend, enhanced); } result_t Device::open() { @@ -205,6 +197,7 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a } bool repeat = false; bool repeated = false; + timeout += m_latency; do { repeat = false; bool isAvailable = available(); @@ -263,7 +256,7 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a // for a two-byte transfer another poll is needed repeat = true; repeated = true; - timeout = ENHANCED_COMPLETE_WAIT_DURATION; + timeout = m_latency+ENHANCED_COMPLETE_WAIT_DURATION; continue; } return RESULT_ERR_TIMEOUT; diff --git a/src/lib/ebus/device.h b/src/lib/ebus/device.h index 84772a90..b995afa4 100755 --- a/src/lib/ebus/device.h +++ b/src/lib/ebus/device.h @@ -40,6 +40,9 @@ namespace ebusd { * to a file and/or forwarding it to a logging function. */ +/** the transfer latency of the network device [ms]. */ +#define NETWORK_LATENCY_MS 10 + /** the arbitration state handled by @a Device. */ enum ArbitrationState { as_none, //!< no arbitration in process @@ -80,17 +83,20 @@ class DeviceListener { * The base class for accessing an eBUS. */ class Device { - public: + protected: /** * Construct a new instance. * @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network). * @param checkDevice whether to regularly check the device availability. + * @param latency the bus transfer latency in milliseconds. * @param readOnly whether to allow read access to the device only. * @param initialSend whether to send an initial @a ESC symbol in @a open(). * @param enhancedProto whether to use the ebusd enhanced protocol. */ - Device(const char* name, bool checkDevice, bool readOnly, bool initialSend, bool enhancedProto=false); + Device(const char* name, bool checkDevice, unsigned int latency, bool readOnly, bool initialSend, + bool enhancedProto=false); + public: /** * Destructor. */ @@ -99,20 +105,21 @@ class Device { /** * Factory method for creating a new instance. * @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network). + * @param extraLatency the extra bus transfer latency in milliseconds. * @param checkDevice whether to regularly check the device availability (only for serial devices). * @param readOnly whether to allow read access to the device only. * @param initialSend whether to send an initial @a ESC symbol in @a open(). * @return the new @a Device, or nullptr on error. * Note: the caller needs to free the created instance. */ - static Device* create(const char* name, bool checkDevice = true, bool readOnly = false, - bool initialSend = false); + static Device* create(const char* name, unsigned int extraLatency = 0, bool checkDevice = true, + bool readOnly = false, bool initialSend = false); /** * Get the transfer latency of this device. * @return the transfer latency in microseconds. */ - virtual unsigned int getLatency() const { return 0; } + virtual unsigned int getLatency() const { return m_latency; } /** * Open the file descriptor. @@ -223,6 +230,9 @@ class Device { /** whether to regularly check the device availability. */ const bool m_checkDevice; + /** the bus transfer latency in milliseconds. */ + const unsigned int m_latency; + /** whether to allow read access to the device only. */ const bool m_readOnly; @@ -269,12 +279,14 @@ class SerialDevice : public Device { * Construct a new instance. * @param name the device name (e.g. "/dev/ttyUSB0" for serial, "127.0.0.1:1234" for network). * @param checkDevice whether to regularly check the device availability. + * @param extraLatency the extra bus transfer latency in milliseconds. * @param readOnly whether to allow read access to the device only. * @param initialSend whether to send an initial @a ESC symbol in @a open(). * @param enhancedProto whether to use the ebusd enhanced protocol. */ - SerialDevice(const char* name, bool checkDevice, bool readOnly, bool initialSend, bool enhancedProto=false) - : Device(name, checkDevice, readOnly, initialSend, enhancedProto) {} + SerialDevice(const char* name, bool checkDevice, unsigned int extraLatency, bool readOnly, bool initialSend, + bool enhancedProto=false) + : Device(name, checkDevice, extraLatency, readOnly, initialSend, enhancedProto) {} // @copydoc result_t open() override; @@ -304,14 +316,16 @@ class NetworkDevice : public Device { * @param address the socket address of the device. * @param hostOrIp the host name or IP address of the device. * @param port the TCP or UDP port of the device. + * @param extraLatency the extra bus transfer latency in milliseconds. * @param readOnly whether to allow read access to the device only. * @param initialSend whether to send an initial @a ESC symbol in @a open(). * @param udp true for UDP, false to TCP. * @param enhancedProto whether to use the ebusd enhanced protocol. */ - NetworkDevice(const char* name, const char* hostOrIp, uint16_t port, bool readOnly, bool initialSend, - bool udp, bool enhancedProto=false) - : Device(name, true, readOnly, initialSend, enhancedProto), m_hostOrIp(hostOrIp), m_port(port), m_udp(udp) {} + NetworkDevice(const char* name, const char* hostOrIp, uint16_t port, unsigned int extraLatency, bool readOnly, + bool initialSend, bool udp, bool enhancedProto=false) + : Device(name, true, NETWORK_LATENCY_MS+extraLatency, readOnly, initialSend, enhancedProto), + m_hostOrIp(hostOrIp), m_port(port), m_udp(udp) {} /** * Destructor. @@ -322,9 +336,6 @@ class NetworkDevice : public Device { } } - // @copydoc - unsigned int getLatency() const override { return 10000; } - // @copydoc result_t open() override;