diff --git a/contrib/docker/README.md b/contrib/docker/README.md index 2d3bf5b7..75cdf5e6 100644 --- a/contrib/docker/README.md +++ b/contrib/docker/README.md @@ -41,7 +41,7 @@ Using a network device ---------------------- When using a network device, the "--device" argument to docker can be omitted, but the device information has to be passed on to ebusd: -> docker run --rm -it -p 8888 john30/ebusd -f --scanconfig -d udp:192.168.178.123:10000 --latency=80000 +> docker run --rm -it -p 8888 john30/ebusd -f --scanconfig -d udp:192.168.178.123:10000 --latency=80 Note: the "-f" and "--scanconfig" arguments are only passed to ebusd if it is called without any additional arguments. So when passing further arguments, these two usually need to be added as well. diff --git a/src/ebusd/bushandler.h b/src/ebusd/bushandler.h index e9190fe8..515ea266 100755 --- a/src/ebusd/bushandler.h +++ b/src/ebusd/bushandler.h @@ -45,20 +45,23 @@ namespace ebusd { using std::string; -/** the default time [us] for retrieving a symbol from an addressed slave. */ -#define SLAVE_RECV_TIMEOUT 15000 +/** the default time [ms] for retrieving a symbol from an addressed slave. */ +#define SLAVE_RECV_TIMEOUT 15 -/** the maximum allowed time [us] for retrieving the AUTO-SYN symbol (45ms + 2*1,2% + 1 Symbol). */ -#define SYN_TIMEOUT 50800 +/** the maximum allowed time [ms] for retrieving the AUTO-SYN symbol (45ms + 2*1,2% + 1 Symbol). */ +#define SYN_TIMEOUT 51 -/** the time [us] for determining bus signal availability (AUTO-SYN timeout * 5). */ -#define SIGNAL_TIMEOUT 250000 +/** the time [ms] for determining bus signal availability (AUTO-SYN timeout * 5). */ +#define SIGNAL_TIMEOUT 250 /** the maximum duration [us] of a single symbol (Start+8Bit+Stop+Extra @ 2400Bd-2*1,2%). */ -#define SYMBOL_DURATION 4700 +#define SYMBOL_DURATION_MICROS 4700 -/** the maximum allowed time [us] for retrieving back a sent symbol (2x symbol duration). */ -#define SEND_TIMEOUT (2*SYMBOL_DURATION) +/** the maximum duration [ms] of a single symbol (Start+8Bit+Stop+Extra @ 2400Bd-2*1,2%). */ +#define SYMBOL_DURATION 5 + +/** the maximum allowed time [ms] for retrieving back a sent symbol (2x symbol duration). */ +#define SEND_TIMEOUT ((int)((2*SYMBOL_DURATION_MICROS+999)/1000)) /** the possible bus states. */ enum BusState { @@ -368,9 +371,8 @@ class BusHandler : public WaitThread { * @param answer whether to answer queries for the own master/slave address. * @param busLostRetries the number of times a send is repeated due to lost arbitration. * @param failedSendRetries the number of times a failed send is repeated (other than lost arbitration). - * @param transferLatency the bus transfer latency in microseconds. - * @param busAcquireTimeout the maximum time in microseconds for bus acquisition. - * @param slaveRecvTimeout the maximum time in microseconds an addressed slave is expected to acknowledge. + * @param busAcquireTimeout the maximum time in milliseconds for bus acquisition. + * @param slaveRecvTimeout the maximum time in milliseconds an addressed slave is expected to acknowledge. * @param lockCount the number of AUTO-SYN symbols before sending is allowed after lost arbitration, or 0 for auto detection. * @param generateSyn whether to enable AUTO-SYN symbol generation. * @param pollInterval the interval in seconds in which poll messages are cycled, or 0 if disabled. @@ -686,10 +688,10 @@ class BusHandler : public WaitThread { /** the number of times a failed send is repeated (other than lost arbitration). */ const unsigned int m_failedSendRetries; - /** the maximum time in microseconds for bus acquisition. */ + /** the maximum time in milliseconds for bus acquisition. */ const unsigned int m_busAcquireTimeout; - /** the maximum time in microseconds an addressed slave is expected to acknowledge. */ + /** the maximum time in milliseconds an addressed slave is expected to acknowledge. */ const unsigned int m_slaveRecvTimeout; /** the number of masters already seen. */ @@ -704,7 +706,7 @@ class BusHandler : public WaitThread { /** the remaining number of AUTO-SYN symbols before sending is allowed again. */ unsigned int m_remainLockCount; - /** the interval in microseconds after which to generate an AUTO-SYN symbol, or 0 if disabled. */ + /** the interval in milliseconds after which to generate an AUTO-SYN symbol, or 0 if disabled. */ unsigned int m_generateSynInterval; /** the interval in seconds in which poll messages are cycled, or 0 if disabled. */ diff --git a/src/ebusd/main.cpp b/src/ebusd/main.cpp index 4f07eec6..ce568dbf 100644 --- a/src/ebusd/main.cpp +++ b/src/ebusd/main.cpp @@ -79,7 +79,7 @@ static struct options opt = { false, // noDeviceCheck false, // readOnly false, // initialSend - -1, // latency + 0, // extraLatency CONFIG_PATH, // configPath false, // scanConfig @@ -92,7 +92,7 @@ static struct options opt = { 0x31, // address false, // answer - 9400, // acquireTimeout + 10, // acquireTimeout 3, // acquireRetries 2, // sendRetries SLAVE_RECV_TIMEOUT*5/3, // receiveTimeout @@ -184,7 +184,7 @@ static const struct argp_option argpoptions[] = { {"nodevicecheck", 'n', nullptr, 0, "Skip serial eBUS device test", 0 }, {"readonly", 'r', nullptr, 0, "Only read from device, never write to it", 0 }, {"initsend", O_INISND, nullptr, 0, "Send an initial escape symbol after connecting device", 0 }, - {"latency", O_DEVLAT, "USEC", 0, "Transfer latency in us [0 for USB, 10000 for IP]", 0 }, + {"latency", O_DEVLAT, "MSEC", 0, "Extra transfer latency in ms [0]", 0 }, {nullptr, 0, nullptr, 0, "Message configuration options:", 2 }, {"configpath", 'c', "PATH", 0, "Read CSV config files from PATH (local folder or HTTP URL) [" CONFIG_PATH @@ -204,10 +204,10 @@ static const struct argp_option argpoptions[] = { {nullptr, 0, nullptr, 0, "eBUS options:", 3 }, {"address", 'a', "ADDR", 0, "Use ADDR as own bus address [31]", 0 }, {"answer", O_ANSWER, nullptr, 0, "Actively answer to requests from other masters", 0 }, - {"acquiretimeout", O_ACQTIM, "USEC", 0, "Stop bus acquisition after USEC us [9400]", 0 }, + {"acquiretimeout", O_ACQTIM, "MSEC", 0, "Stop bus acquisition after MSEC ms [10]", 0 }, {"acquireretries", O_ACQRET, "COUNT", 0, "Retry bus acquisition COUNT times [3]", 0 }, {"sendretries", O_SNDRET, "COUNT", 0, "Repeat failed sends COUNT times [2]", 0 }, - {"receivetimeout", O_RCVTIM, "USEC", 0, "Expect a slave to answer within USEC us [25000]", 0 }, + {"receivetimeout", O_RCVTIM, "MSEC", 0, "Expect a slave to answer within MSEC us [25]", 0 }, {"numbermasters", O_MASCNT, "COUNT", 0, "Expect COUNT masters on the bus, 0 for auto detection [0]", 0 }, {"generatesyn", O_GENSYN, nullptr, 0, "Enable AUTO-SYN symbol generation", 0 }, @@ -267,6 +267,7 @@ static map s_templatesByPath; error_t parse_opt(int key, char *arg, struct argp_state *state) { struct options *opt = (struct options*)state->input; result_t result = RESULT_OK; + unsigned int value; switch (key) { // Device options: @@ -295,12 +296,13 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { } opt->initialSend = true; break; - case O_DEVLAT: // --latency=10000 - opt->latency = parseInt(arg, 10, 0, 200000, &result); - if (result != RESULT_OK) { + case O_DEVLAT: // --latency=10 + value = parseInt(arg, 10, 0, 200000, &result); // backwards compatible (micros) + if (result != RESULT_OK || (value<=1000 && value>200)) { // backwards compatible (micros) argp_error(state, "invalid latency"); return EINVAL; } + opt->extraLatency = value > 1000 ? value/1000 : value; // backwards compatible (micros) break; // Message configuration options: @@ -376,12 +378,13 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { } opt->answer = true; break; - case O_ACQTIM: // --acquiretimeout=9400 - opt->acquireTimeout = parseInt(arg, 10, 1000, 100000, &result); - if (result != RESULT_OK) { + case O_ACQTIM: // --acquiretimeout=10 + value = parseInt(arg, 10, 1, 100000, &result); // backwards compatible (micros) + if (result != RESULT_OK || (value<=1000 && value>100)) { // backwards compatible (micros) argp_error(state, "invalid acquiretimeout"); return EINVAL; } + opt->acquireTimeout = value > 1000 ? value/1000 : value; // backwards compatible (micros) break; case O_ACQRET: // --acquireretries=3 opt->acquireRetries = parseInt(arg, 10, 0, 10, &result); @@ -397,12 +400,13 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { return EINVAL; } break; - case O_RCVTIM: // --receivetimeout=25000 - opt->receiveTimeout = parseInt(arg, 10, 1000, 100000, &result); - if (result != RESULT_OK) { + case O_RCVTIM: // --receivetimeout=25 + value = parseInt(arg, 10, 1, 100000, &result); // backwards compatible (micros) + if (result != RESULT_OK || (value<=1000 && value>100)) { // backwards compatible (micros) argp_error(state, "invalid receivetimeout"); return EINVAL; } + opt->receiveTimeout = value > 1000 ? value/1000 : value; // backwards compatible (micros) break; case O_MASCNT: // --numbermasters=0 opt->masterCount = parseInt(arg, 10, 0, 25, &result); @@ -1306,11 +1310,7 @@ int main(int argc, char* argv[]) { } // open the device - 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); + Device *device = Device::create(opt.device, opt.extraLatency, !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/main.h b/src/ebusd/main.h index e2721365..ba63ce95 100644 --- a/src/ebusd/main.h +++ b/src/ebusd/main.h @@ -39,7 +39,7 @@ struct options { bool noDeviceCheck; //!< skip serial eBUS device test bool readOnly; //!< read-only access to the device bool initialSend; //!< send an initial escape symbol after connecting device - int latency; //!< transfer latency in us [0 for USB, 10000 for IP] + unsigned int extraLatency; //!< extra transfer latency in ms [0 for USB, 10 for IP] const char* configPath; //!< path to CSV configuration files [http://ebusd.eu/config/] bool scanConfig; //!< pick configuration files matching initial scan @@ -54,10 +54,10 @@ struct options { symbol_t address; //!< own bus address [31] bool answer; //!< answer to requests from other masters - unsigned int acquireTimeout; //!< bus acquisition timeout in us [9400] + unsigned int acquireTimeout; //!< bus acquisition timeout in ms [10] unsigned int acquireRetries; //!< number of retries for bus acquisition [3] unsigned int sendRetries; //!< number of retries for failed sends [2] - unsigned int receiveTimeout; //!< timeout for receiving answer from slave in us [25000] + unsigned int receiveTimeout; //!< timeout for receiving answer from slave in ms [25] unsigned int masterCount; //!< expected number of masters for arbitration [0] bool generateSyn; //!< enable AUTO-SYN symbol generation diff --git a/src/lib/ebus/device.cpp b/src/lib/ebus/device.cpp index a8d471dd..af3805e1 100755 --- a/src/lib/ebus/device.cpp +++ b/src/lib/ebus/device.cpp @@ -185,10 +185,10 @@ result_t Device::send(symbol_t value) { } /** - * the maximum duration to wait for an enhanced sequence to complete after the first part was already retrieved: - * 2* (Start+8Bit+Stop+Extra @ 9600Bd) + * the maximum duration in milliseconds to wait for an enhanced sequence to complete after the first part was already + * retrieved: 2* (Start+8Bit+Stop+Extra @ 9600Bd) */ -#define ENHANCED_COMPLETE_WAIT_DURATION (2*1150) +#define ENHANCED_COMPLETE_WAIT_DURATION 3 result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* arbitrationState) { @@ -206,8 +206,8 @@ result_t Device::recv(unsigned int timeout, symbol_t* value, ArbitrationState* a struct timespec tdiff; // set select timeout - tdiff.tv_sec = timeout/1000000; - tdiff.tv_nsec = (timeout%1000000)*1000; + tdiff.tv_sec = timeout/1000; + tdiff.tv_nsec = (timeout%1000)*1000000; #ifdef HAVE_PPOLL nfds_t nfds = 1; diff --git a/src/lib/ebus/device.h b/src/lib/ebus/device.h index b995afa4..f2248571 100755 --- a/src/lib/ebus/device.h +++ b/src/lib/ebus/device.h @@ -117,7 +117,7 @@ class Device { /** * Get the transfer latency of this device. - * @return the transfer latency in microseconds. + * @return the transfer latency in milliseconds. */ virtual unsigned int getLatency() const { return m_latency; } @@ -147,7 +147,7 @@ class Device { /** * Read a single byte from the device. - * @param timeout maximum time to wait for the byte in microseconds, or 0 for infinite. + * @param timeout maximum time to wait for the byte in milliseconds, or 0 for infinite. * @param value the reference in which the received byte value is stored. * @param arbitrationState the reference in which the current @a ArbitrationState is stored on success. When set to * @a as_won, the received byte is the master address that was successfully arbitrated with. diff --git a/test_coverage.sh b/test_coverage.sh index f5650060..74a13521 100755 --- a/test_coverage.sh +++ b/test_coverage.sh @@ -207,7 +207,7 @@ r,,SoftwareVersion,,,,,"0000",,,HEX:4,,, EOF echo "test,testpass,installer" > ./passwd #ebusd: -./src/ebusd/ebusd -d tcp:127.0.0.1:8876 --initsend --latency 10000 -n -c "$PWD/contrib/etc/ebusd" --pollinterval=10 -s -a 31 --acquireretries 3 --answer --generatesyn --receivetimeout 40000 --sendretries 1 --enablehex --htmlpath "$PWD/contrib/html" --httpport 8878 --pidfile "$PWD/ebusd.pid" --localhost -p 8877 -l "$PWD/ebusd.log" --logareas all --loglevel debug --lograwdata=bytes --lograwdatafile "$PWD/ebusd.raw" --lograwdatasize 1 --dumpfile "$PWD/ebusd.dump" --dumpsize 100 -D --scanconfig --aclfile=./passwd --mqttport=1883 +./src/ebusd/ebusd -d tcp:127.0.0.1:8876 --initsend --latency 10 -n -c "$PWD/contrib/etc/ebusd" --pollinterval=10 -s -a 31 --acquireretries 3 --answer --generatesyn --receivetimeout 40000 --sendretries 1 --enablehex --htmlpath "$PWD/contrib/html" --httpport 8878 --pidfile "$PWD/ebusd.pid" --localhost -p 8877 -l "$PWD/ebusd.log" --logareas all --loglevel debug --lograwdata=bytes --lograwdatafile "$PWD/ebusd.raw" --lograwdatasize 1 --dumpfile "$PWD/ebusd.dump" --dumpsize 100 -D --scanconfig --aclfile=./passwd --mqttport=1883 sleep 3 pid=`head -n 1 "$PWD/ebusd.pid"` if [ -z "$pid" ]; then