Commit d8f254779570daf8bba60819fe677af4cba8c87a
1 parent
7eac79a7
Fix #463299 - New functions to get/set timeouts of begin and end of trame
Original patch by Sisyph (eric-paul).
Showing
4 changed files
with
78 additions
and
6 deletions
NEWS
| ... | ... | @@ -4,10 +4,12 @@ libmodbus 2.1.1 (2010-XX-XX) |
| 4 | 4 | - Remove the internal function set_message_length_tcp |
| 5 | 5 | - Restore slave ID (server ID) argument in functions |
| 6 | 6 | - Error conventions of POSIX systems and error recover |
| 7 | -- Versioning infrastructure. | |
| 7 | +- Versioning infrastructure | |
| 8 | 8 | Inspired by the Clutter project and the work done by Florian Forster. |
| 9 | 9 | - Fix the broadcast constant (255 -> 0) |
| 10 | - Reported by David Olivari | |
| 10 | + Reported by David Olivari. | |
| 11 | +- Fix #463299 - New functions to define the timeouts of begin and end of trame | |
| 12 | + Original patch by Sisyph (eric-paul). | |
| 11 | 13 | |
| 12 | 14 | libmodbus 2.1.0 (2010-03-24) |
| 13 | 15 | ============================ | ... | ... |
src/modbus.c
| ... | ... | @@ -615,8 +615,8 @@ static int receive_msg(modbus_param_t *mb_param, |
| 615 | 615 | state = FUNCTION; |
| 616 | 616 | msg_length_computed = TAB_HEADER_LENGTH[mb_param->type_com] + 1; |
| 617 | 617 | } else { |
| 618 | - tv.tv_sec = 0; | |
| 619 | - tv.tv_usec = TIME_OUT_BEGIN_OF_TRAME; | |
| 618 | + tv.tv_sec = mb_param->timeout_begin.tv_sec; | |
| 619 | + tv.tv_usec = mb_param->timeout_begin.tv_usec; | |
| 620 | 620 | state = COMPLETE; |
| 621 | 621 | } |
| 622 | 622 | |
| ... | ... | @@ -697,8 +697,8 @@ static int receive_msg(modbus_param_t *mb_param, |
| 697 | 697 | if (length_to_read > 0) { |
| 698 | 698 | /* If no character at the buffer wait |
| 699 | 699 | TIME_OUT_END_OF_TRAME before to generate an error. */ |
| 700 | - tv.tv_sec = 0; | |
| 701 | - tv.tv_usec = TIME_OUT_END_OF_TRAME; | |
| 700 | + tv.tv_sec = mb_param->timeout_end.tv_sec; | |
| 701 | + tv.tv_usec = mb_param->timeout_end.tv_usec; | |
| 702 | 702 | |
| 703 | 703 | WAIT_DATA(); |
| 704 | 704 | } else { |
| ... | ... | @@ -1466,6 +1466,15 @@ int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *data_dest) |
| 1466 | 1466 | return rc; |
| 1467 | 1467 | } |
| 1468 | 1468 | |
| 1469 | +void init_common(modbus_param_t *mb_param) | |
| 1470 | +{ | |
| 1471 | + mb_param->timeout_begin.tv_sec = 0; | |
| 1472 | + mb_param->timeout_begin.tv_usec = TIME_OUT_BEGIN_OF_TRAME; | |
| 1473 | + | |
| 1474 | + mb_param->timeout_end.tv_sec = 0; | |
| 1475 | + mb_param->timeout_end.tv_usec = TIME_OUT_END_OF_TRAME; | |
| 1476 | +} | |
| 1477 | + | |
| 1469 | 1478 | /* Initializes the modbus_param_t structure for RTU |
| 1470 | 1479 | - device: "/dev/ttyS0" |
| 1471 | 1480 | - baud: 9600, 19200, 57600, 115200, etc |
| ... | ... | @@ -1488,6 +1497,8 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, |
| 1488 | 1497 | mb_param->type_com = RTU; |
| 1489 | 1498 | mb_param->error_recovery = FALSE; |
| 1490 | 1499 | mb_param->slave = slave; |
| 1500 | + | |
| 1501 | + init_common(mb_param); | |
| 1491 | 1502 | } |
| 1492 | 1503 | |
| 1493 | 1504 | /* Initializes the modbus_param_t structure for TCP. |
| ... | ... | @@ -1507,6 +1518,8 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int sla |
| 1507 | 1518 | mb_param->type_com = TCP; |
| 1508 | 1519 | mb_param->error_recovery = FALSE; |
| 1509 | 1520 | mb_param->slave = slave; |
| 1521 | + | |
| 1522 | + init_common(mb_param); | |
| 1510 | 1523 | } |
| 1511 | 1524 | |
| 1512 | 1525 | /* Define the slave number */ |
| ... | ... | @@ -1540,6 +1553,30 @@ int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled) |
| 1540 | 1553 | return 0; |
| 1541 | 1554 | } |
| 1542 | 1555 | |
| 1556 | +/* Get the timeout of begin of trame */ | |
| 1557 | +void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout) | |
| 1558 | +{ | |
| 1559 | + *timeout = mb_param->timeout_begin; | |
| 1560 | +} | |
| 1561 | + | |
| 1562 | +/* Set timeout when waiting the beginning of a trame */ | |
| 1563 | +void modbus_set_timeout_begin(modbus_param_t *mb_param, const struct timeval *timeout) | |
| 1564 | +{ | |
| 1565 | + mb_param->timeout_begin = *timeout; | |
| 1566 | +} | |
| 1567 | + | |
| 1568 | +/* Get the timeout of end of trame */ | |
| 1569 | +void modbus_get_timeout_end(modbus_param_t *mb_param, struct timeval *timeout) | |
| 1570 | +{ | |
| 1571 | + *timeout = mb_param->timeout_end; | |
| 1572 | +} | |
| 1573 | + | |
| 1574 | +/* Set timeout when waiting the end of a trame */ | |
| 1575 | +void modbus_set_timeout_end(modbus_param_t *mb_param, const struct timeval *timeout) | |
| 1576 | +{ | |
| 1577 | + mb_param->timeout_end = *timeout; | |
| 1578 | +} | |
| 1579 | + | |
| 1543 | 1580 | /* Sets up a serial port for RTU communications */ |
| 1544 | 1581 | static int modbus_connect_rtu(modbus_param_t *mb_param) |
| 1545 | 1582 | { | ... | ... |
src/modbus.h.in
| ... | ... | @@ -234,6 +234,8 @@ typedef struct { |
| 234 | 234 | char ip[16]; |
| 235 | 235 | /* Save old termios settings */ |
| 236 | 236 | struct termios old_tios; |
| 237 | + struct timeval timeout_begin; | |
| 238 | + struct timeval timeout_end; | |
| 237 | 239 | } modbus_param_t; |
| 238 | 240 | |
| 239 | 241 | typedef struct { |
| ... | ... | @@ -255,6 +257,12 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port, |
| 255 | 257 | void modbus_set_slave(modbus_param_t *mb_param, int slave); |
| 256 | 258 | int modbus_set_error_recovery(modbus_param_t *mb_param, int enabled); |
| 257 | 259 | |
| 260 | +void modbus_get_timeout_begin(modbus_param_t *mb_param, struct timeval *timeout); | |
| 261 | +void modbus_set_timeout_begin(modbus_param_t *mb_param, const struct timeval *timeout); | |
| 262 | + | |
| 263 | +void modbus_get_timeout_end(modbus_param_t *mb_param, struct timeval *timeout); | |
| 264 | +void modbus_set_timeout_end(modbus_param_t *mb_param, const struct timeval *timeout); | |
| 265 | + | |
| 258 | 266 | int modbus_connect(modbus_param_t *mb_param); |
| 259 | 267 | void modbus_close(modbus_param_t *mb_param); |
| 260 | 268 | ... | ... |
tests/unit-test-master.c
| ... | ... | @@ -36,6 +36,8 @@ int main(void) |
| 36 | 36 | int nb_points; |
| 37 | 37 | int rc; |
| 38 | 38 | float real; |
| 39 | + struct timeval timeout_begin_old; | |
| 40 | + struct timeval timeout_begin_new; | |
| 39 | 41 | |
| 40 | 42 | /* RTU parity : none, even, odd */ |
| 41 | 43 | /* |
| ... | ... | @@ -468,10 +470,33 @@ int main(void) |
| 468 | 470 | if (rc == UT_HOLDING_REGISTERS_NB_POINTS) { |
| 469 | 471 | printf("OK\n"); |
| 470 | 472 | } else { |
| 473 | + printf("FAILED\n"); | |
| 471 | 474 | goto close; |
| 475 | + } | |
| 476 | + | |
| 477 | + /* Save original timeout */ | |
| 478 | + modbus_get_timeout_begin(&mb_param, &timeout_begin_old); | |
| 479 | + | |
| 480 | + /* Define a new and too short timeout */ | |
| 481 | + timeout_begin_new.tv_sec = 0; | |
| 482 | + timeout_begin_new.tv_usec = 0; | |
| 483 | + modbus_set_timeout_begin(&mb_param, &timeout_begin_new); | |
| 484 | + | |
| 485 | + rc = read_holding_registers(&mb_param, SERVER_ID, | |
| 486 | + UT_HOLDING_REGISTERS_ADDRESS, | |
| 487 | + UT_HOLDING_REGISTERS_NB_POINTS, | |
| 488 | + tab_rp_registers); | |
| 489 | + printf("3/3 Too short timeout: "); | |
| 490 | + if (rc == -1 && errno == ETIMEDOUT) { | |
| 491 | + printf("OK\n"); | |
| 492 | + } else { | |
| 472 | 493 | printf("FAILED\n"); |
| 494 | + goto close; | |
| 473 | 495 | } |
| 474 | 496 | |
| 497 | + /* Restore original timeout */ | |
| 498 | + modbus_set_timeout_begin(&mb_param, &timeout_begin_old); | |
| 499 | + | |
| 475 | 500 | /** BAD RESPONSE **/ |
| 476 | 501 | printf("\nTEST BAD RESPONSE ERROR:\n"); |
| 477 | 502 | ... | ... |