Compare commits

...

3 Commits

Author SHA1 Message Date
Stefan Wahren
d4aa9520f9 mbus-serial-scan: Make timeout adjustable 2018-05-15 21:17:09 +02:00
Stefan Wahren
af5a843e6a Revert "mbus-serial: Increase serial timeouts"
This reverts commit a572c0f7429303c3b5974df9cb487911a07d986b.
2018-05-15 20:47:25 +02:00
Stefan Wahren
13e6811630 mbus-serial-scan: Refactor cmdline parsing 2018-05-15 20:20:34 +02:00
4 changed files with 63 additions and 62 deletions

View File

@ -11,6 +11,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <mbus/mbus.h>
static int debug = 0;
@ -54,60 +55,43 @@ main(int argc, char **argv)
{
mbus_handle *handle;
char *device;
int address, retries = 0;
int address, retries = 0, timeout = 0;
long baudrate = 9600;
int ret;
int opt, ret;
if (argc == 2)
while ((opt = getopt(argc, argv, "db:r:t:")) != -1)
{
device = argv[1];
switch (opt)
{
case 'd':
debug = 1;
break;
case 'b':
baudrate = atol(optarg);
break;
case 'r':
retries = atoi(optarg);
break;
case 't':
timeout = atoi(optarg);
break;
default:
fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] [-t TIMEOUT] device\n",
argv[0]);
return 0;
}
}
else if (argc == 3 && strcmp(argv[1], "-d") == 0)
{
debug = 1;
device = argv[2];
}
else if (argc == 4 && strcmp(argv[1], "-b") == 0)
{
baudrate = atol(argv[2]);
device = argv[3];
}
else if (argc == 4 && strcmp(argv[1], "-r") == 0)
{
retries = atoi(argv[2]);
device = argv[3];
}
else if (argc == 5 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-b") == 0)
{
debug = 1;
baudrate = atol(argv[3]);
device = argv[4];
}
else if (argc == 5 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-r") == 0)
{
debug = 1;
retries = atoi(argv[3]);
device = argv[4];
}
else if (argc == 6 && strcmp(argv[1], "-b") == 0 && strcmp(argv[3], "-r") == 0)
{
baudrate = atol(argv[2]);
retries = atoi(argv[4]);
device = argv[5];
}
else if (argc == 7 && strcmp(argv[1], "-d") == 0 && strcmp(argv[2], "-b") == 0 && strcmp(argv[4], "-r") == 0)
{
debug = 1;
baudrate = atol(argv[3]);
retries = atoi(argv[5]);
device = argv[6];
}
else
{
fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] device\n", argv[0]);
if (optind >= argc) {
fprintf(stderr,"usage: %s [-d] [-b BAUDRATE] [-r RETRIES] [-t TIMEOUT] device\n",
argv[0]);
return 0;
}
device = argv[optind];
if ((handle = mbus_context_serial(device)) == NULL)
{
fprintf(stderr,"Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str());
@ -132,6 +116,12 @@ main(int argc, char **argv)
return 1;
}
if (mbus_context_set_option(handle, MBUS_OPTION_TIMEOUT_OFFSET, timeout) == -1)
{
fprintf(stderr,"Failed to set timeout offset\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{
fprintf(stderr,"Failed to set baud rate.\n");

View File

@ -1519,6 +1519,7 @@ mbus_context_serial(const char *device)
handle->max_data_retry = 3;
handle->max_search_retry = 1;
handle->timeout_offset = 0;
handle->is_serial = 1;
handle->purge_first_frame = MBUS_FRAME_PURGE_M2S;
handle->auxdata = serial_data;
@ -1567,6 +1568,7 @@ mbus_context_tcp(const char *host, uint16_t port)
handle->max_data_retry = 3;
handle->max_search_retry = 1;
handle->timeout_offset = 0;
handle->is_serial = 0;
handle->purge_first_frame = MBUS_FRAME_PURGE_M2S;
handle->auxdata = tcp_data;
@ -1652,6 +1654,13 @@ mbus_context_set_option(mbus_handle * handle, mbus_context_option option, long v
return 0;
}
break;
case MBUS_OPTION_TIMEOUT_OFFSET:
if ((value >= 0) && (value <= 100))
{
handle->timeout_offset = value;
return 0;
}
break;
case MBUS_OPTION_PURGE_FIRST_FRAME:
if ((value == MBUS_FRAME_PURGE_NONE) ||
(value == MBUS_FRAME_PURGE_M2S) ||

View File

@ -87,6 +87,7 @@ typedef struct _mbus_handle {
int fd;
int max_data_retry;
int max_search_retry;
unsigned int timeout_offset;
char purge_first_frame;
char is_serial; /**< _handle type (non zero for serial) */
int (*open) (struct _mbus_handle *handle);
@ -154,7 +155,8 @@ typedef struct _mbus_record {
typedef enum _mbus_context_option {
MBUS_OPTION_MAX_DATA_RETRY, /**< option defines the maximum attempts of data request retransmission */
MBUS_OPTION_MAX_SEARCH_RETRY, /**< option defines the maximum attempts of search request retransmission */
MBUS_OPTION_PURGE_FIRST_FRAME /**< option controls the echo cancelation for mbus_recv_frame */
MBUS_OPTION_PURGE_FIRST_FRAME, /**< option controls the echo cancelation for mbus_recv_frame */
MBUS_OPTION_TIMEOUT_OFFSET, /**< option defines the additional timeout offset */
} mbus_context_option;
/**

View File

@ -72,13 +72,10 @@ mbus_serial_connect(mbus_handle *handle)
// between the end of a master send telegram and the beginning of the response telegram of the slave shall be
// between 11 bit times and (330 bit times + 50ms).
//
// Nowadays the usage of USB to serial adapter is very common, which could
// result in additional delay of 100 ms in worst case.
//
// For 2400Bd this means (330 + 11) / 2400 + 0.15 = 292 ms (added 11 bit periods to receive first byte).
// I.e. timeout of 0.3s seems appropriate for 2400Bd.
// For 2400Bd this means (330 + 11) / 2400 + 0.05 = 188.75 ms (added 11 bit periods to receive first byte).
// I.e. timeout of 0.2s seems appropriate for 2400Bd.
term->c_cc[VTIME] = (cc_t) 3; // Timeout in 1/10 sec
term->c_cc[VTIME] = (cc_t) 2 + handle->timeout_offset; // Timeout in 1/10 sec
cfsetispeed(term, B2400);
cfsetospeed(term, B2400);
@ -116,48 +113,51 @@ mbus_serial_set_baudrate(mbus_handle *handle, long baudrate)
{
case 300:
speed = B300;
serial_data->t.c_cc[VTIME] = (cc_t) 13; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 12; // Timeout in 1/10 sec
break;
case 600:
speed = B600;
serial_data->t.c_cc[VTIME] = (cc_t) 8; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 6; // Timeout in 1/10 sec
break;
case 1200:
speed = B1200;
serial_data->t.c_cc[VTIME] = (cc_t) 5; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 4; // Timeout in 1/10 sec
break;
case 2400:
speed = B2400;
serial_data->t.c_cc[VTIME] = (cc_t) 3; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
break;
case 4800:
speed = B4800;
serial_data->t.c_cc[VTIME] = (cc_t) 3; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
break;
case 9600:
speed = B9600;
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 1; // Timeout in 1/10 sec
break;
case 19200:
speed = B19200;
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 1; // Timeout in 1/10 sec
break;
case 38400:
speed = B38400;
serial_data->t.c_cc[VTIME] = (cc_t) 2; // Timeout in 1/10 sec
serial_data->t.c_cc[VTIME] = (cc_t) 1; // Timeout in 1/10 sec
break;
default:
return -1; // unsupported baudrate
}
// Add timeout offset for additional delay
serial_data->t.c_cc[VTIME] += handle->timeout_offset;
// Set input baud rate
if (cfsetispeed(&(serial_data->t), speed) != 0)
{