move transfer latency to device

This commit is contained in:
John-Michael Baier
2020-11-01 10:25:57 +01:00
parent e519193797
commit d02b2bd331
6 changed files with 47 additions and 48 deletions
+7 -7
View File
@@ -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));
+2 -5
View File
@@ -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;
+5 -1
View File
@@ -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;
+1 -7
View File
@@ -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");
+8 -15
View File
@@ -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<symbol_t*>(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/<device>
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;
+24 -13
View File
@@ -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;