Commit 525aadb23a82db0bbdc99d9318158d03f09616dd
1 parent
f410aea2
Remove the slave ID argument of modbus_new_rtu()
modbus_set_slave must be used to set the slave ID of the remote device to talk in master mode and to set the internal slave ID in slave mode. If you talk to several devices, you need to call modbus_set_slave each time the following requests must be sent to another device.
Showing
7 changed files
with
29 additions
and
16 deletions
src/modbus-data.c
src/modbus-rtu.c
| ... | ... | @@ -21,6 +21,7 @@ |
| 21 | 21 | #include <fcntl.h> |
| 22 | 22 | #include <string.h> |
| 23 | 23 | #include <unistd.h> |
| 24 | +#include <assert.h> | |
| 24 | 25 | |
| 25 | 26 | #include "modbus-private.h" |
| 26 | 27 | |
| ... | ... | @@ -87,6 +88,8 @@ static const uint8_t table_crc_lo[] = { |
| 87 | 88 | 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 |
| 88 | 89 | }; |
| 89 | 90 | |
| 91 | +/* Define the slave ID of the remote device to talk in master mode or set the | |
| 92 | + * internal slave ID in slave mode */ | |
| 90 | 93 | static int _modbus_set_slave(modbus_t *ctx, int slave) |
| 91 | 94 | { |
| 92 | 95 | if (slave >= 1 && slave <= 247) { |
| ... | ... | @@ -104,6 +107,7 @@ static int _modbus_rtu_build_request_basis(modbus_t *ctx, int function, |
| 104 | 107 | int addr, int nb, |
| 105 | 108 | uint8_t *req) |
| 106 | 109 | { |
| 110 | + assert(ctx->slave != -1); | |
| 107 | 111 | req[0] = ctx->slave; |
| 108 | 112 | req[1] = function; |
| 109 | 113 | req[2] = addr >> 8; |
| ... | ... | @@ -117,6 +121,8 @@ static int _modbus_rtu_build_request_basis(modbus_t *ctx, int function, |
| 117 | 121 | /* Builds a RTU response header */ |
| 118 | 122 | static int _modbus_rtu_build_response_basis(sft_t *sft, uint8_t *rsp) |
| 119 | 123 | { |
| 124 | + /* In this case, the slave is certainly valid because a check is already | |
| 125 | + * done in _modbus_rtu_listen */ | |
| 120 | 126 | rsp[0] = sft->slave; |
| 121 | 127 | rsp[1] = sft->function; |
| 122 | 128 | |
| ... | ... | @@ -712,6 +718,14 @@ int _modbus_rtu_listen(modbus_t *ctx, int nb_connection) |
| 712 | 718 | fprintf(stderr, "Not implemented"); |
| 713 | 719 | } |
| 714 | 720 | |
| 721 | + if (ctx->slave == -1) { | |
| 722 | + if (ctx->debug) { | |
| 723 | + fprintf(stderr, "The slave ID is not set (you must call modbus_set_slave() first)\n"); | |
| 724 | + } | |
| 725 | + errno = EINVAL; | |
| 726 | + return -1; | |
| 727 | + } | |
| 728 | + | |
| 715 | 729 | errno = EINVAL; |
| 716 | 730 | return -1; |
| 717 | 731 | } |
| ... | ... | @@ -832,23 +846,18 @@ const modbus_backend_t _modbus_rtu_backend = { |
| 832 | 846 | - parity: 'N' stands for None, 'E' for Even and 'O' for odd |
| 833 | 847 | - data_bits: 5, 6, 7, 8 |
| 834 | 848 | - stop_bits: 1, 2 |
| 835 | - - slave: slave number of the caller | |
| 836 | 849 | */ |
| 837 | 850 | modbus_t* modbus_new_rtu(const char *device, |
| 838 | 851 | int baud, char parity, int data_bit, |
| 839 | - int stop_bit, int slave) | |
| 852 | + int stop_bit) | |
| 840 | 853 | { |
| 841 | 854 | modbus_t *ctx; |
| 842 | 855 | modbus_rtu_t *ctx_rtu; |
| 843 | 856 | |
| 844 | 857 | ctx = (modbus_t *) malloc(sizeof(modbus_t)); |
| 845 | 858 | _modbus_init_common(ctx); |
| 846 | - if (_modbus_set_slave(ctx, slave) == -1) { | |
| 847 | - return NULL; | |
| 848 | - } | |
| 849 | 859 | |
| 850 | 860 | ctx->backend = &_modbus_rtu_backend; |
| 851 | - | |
| 852 | 861 | ctx->backend_data = (modbus_rtu_t *) malloc(sizeof(modbus_rtu_t)); |
| 853 | 862 | ctx_rtu = (modbus_rtu_t *)ctx->backend_data; |
| 854 | 863 | #if defined(OpenBSD) | ... | ... |
src/modbus-rtu.h
src/modbus.c
| ... | ... | @@ -1225,14 +1225,17 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *data_dest) |
| 1225 | 1225 | |
| 1226 | 1226 | void _modbus_init_common(modbus_t *ctx) |
| 1227 | 1227 | { |
| 1228 | + /* Slave is initialized to -1 */ | |
| 1229 | + ctx->slave = -1; | |
| 1230 | + | |
| 1231 | + ctx->debug = FALSE; | |
| 1232 | + ctx->error_recovery = FALSE; | |
| 1233 | + | |
| 1228 | 1234 | ctx->timeout_begin.tv_sec = 0; |
| 1229 | 1235 | ctx->timeout_begin.tv_usec = _TIME_OUT_BEGIN_OF_TRAME; |
| 1230 | 1236 | |
| 1231 | 1237 | ctx->timeout_end.tv_sec = 0; |
| 1232 | 1238 | ctx->timeout_end.tv_usec = _TIME_OUT_END_OF_TRAME; |
| 1233 | - | |
| 1234 | - ctx->error_recovery = FALSE; | |
| 1235 | - ctx->debug = FALSE; | |
| 1236 | 1239 | } |
| 1237 | 1240 | |
| 1238 | 1241 | /* Define the slave number */ | ... | ... |
tests/random-test-client.c
| ... | ... | @@ -37,7 +37,6 @@ |
| 37 | 37 | range defined by the following defines. |
| 38 | 38 | */ |
| 39 | 39 | #define LOOP 1 |
| 40 | -#define MY_ID 1 | |
| 41 | 40 | #define SERVER_ID 17 |
| 42 | 41 | #define ADDRESS_START 0 |
| 43 | 42 | #define ADDRESS_END 99 |
| ... | ... | @@ -59,14 +58,16 @@ int main(void) |
| 59 | 58 | uint16_t *tab_rw_rq_registers; |
| 60 | 59 | uint16_t *tab_rp_registers; |
| 61 | 60 | |
| 62 | - /* | |
| 63 | - ctx = modbus_new_rtu("/dev/ttyS0", 19200, 'N', 8, 1, MY_ID); | |
| 61 | + /* RTU */ | |
| 62 | +/* | |
| 63 | + ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1); | |
| 64 | 64 | modbus_set_slave(ctx, SERVER_ID); |
| 65 | - */ | |
| 65 | +*/ | |
| 66 | 66 | |
| 67 | 67 | /* TCP */ |
| 68 | 68 | ctx = modbus_new_tcp("127.0.0.1", 1502); |
| 69 | 69 | modbus_set_debug(ctx, TRUE); |
| 70 | + | |
| 70 | 71 | if (modbus_connect(ctx) == -1) { |
| 71 | 72 | fprintf(stderr, "Connection failed: %s\n", |
| 72 | 73 | modbus_strerror(errno)); | ... | ... |
tests/unit-test-client.c
| ... | ... | @@ -41,7 +41,7 @@ int main(void) |
| 41 | 41 | struct timeval timeout_begin_new; |
| 42 | 42 | |
| 43 | 43 | /* |
| 44 | - ctx = modbus_new_rtu("/dev/ttyS0", 19200, 'N', 8, 1, CLIENT_ID); | |
| 44 | + ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1); | |
| 45 | 45 | modbus_set_slave(ctx, SERVER_ID); |
| 46 | 46 | is_mode_rtu = TRUE; |
| 47 | 47 | */ | ... | ... |