Commit cf22eabc2701cc9ddfd4a921ba7c6e0822db5d7a
Committed by
Stéphane Raimbault
1 parent
c7eb7b96
Implemented runtime configurable RTS delay
Showing
6 changed files
with
155 additions
and
7 deletions
doc/Makefile.am
| ... | ... | @@ -29,6 +29,8 @@ TXT3 = \ |
| 29 | 29 | modbus_rtu_set_serial_mode.txt \ |
| 30 | 30 | modbus_rtu_get_rts.txt \ |
| 31 | 31 | modbus_rtu_set_rts.txt \ |
| 32 | + modbus_rtu_get_rts_delay.txt \ | |
| 33 | + modbus_rtu_set_rts_delay.txt \ | |
| 32 | 34 | modbus_rtu_set_custom_rts.txt \ |
| 33 | 35 | modbus_send_raw_request.txt \ |
| 34 | 36 | modbus_set_bits_from_bytes.txt \ | ... | ... |
doc/modbus_rtu_get_rts_delay.txt
0 → 100644
| 1 | +modbus_rtu_get_rts_delay(3) | |
| 2 | +=========================== | |
| 3 | + | |
| 4 | + | |
| 5 | +NAME | |
| 6 | +---- | |
| 7 | +modbus_rtu_get_rts_delay - get the current RTS delay in RTU | |
| 8 | + | |
| 9 | + | |
| 10 | +SYNOPSIS | |
| 11 | +-------- | |
| 12 | +*int modbus_rtu_get_rts_delay(modbus_t *'ctx');* | |
| 13 | + | |
| 14 | + | |
| 15 | +DESCRIPTION | |
| 16 | +----------- | |
| 17 | + | |
| 18 | +The _modbus_rtu_get_rts_delay()_ function shall get the current Request To Send | |
| 19 | +delay period of the libmodbus context 'ctx'. | |
| 20 | + | |
| 21 | +This function can only be used with a context using a RTU backend. | |
| 22 | + | |
| 23 | + | |
| 24 | +RETURN VALUE | |
| 25 | +------------ | |
| 26 | +The _modbus_rtu_get_rts_delay()_ function shall return the current RTS delay in | |
| 27 | +microseconds if successful. Otherwise it shall return -1 and set errno. | |
| 28 | + | |
| 29 | + | |
| 30 | +ERRORS | |
| 31 | +------ | |
| 32 | +*EINVAL*:: | |
| 33 | +The libmodbus backend is not RTU. | |
| 34 | + | |
| 35 | + | |
| 36 | +SEE ALSO | |
| 37 | +-------- | |
| 38 | +linkmb:modbus_rtu_set_rts_delay[3] | |
| 39 | + | |
| 40 | + | |
| 41 | +AUTHORS | |
| 42 | +------- | |
| 43 | +Jimmy Bergström <jimmy@ekontroll.com> | |
| 44 | + | |
| 45 | +The libmodbus documentation was written by Stéphane Raimbault | |
| 46 | +<stephane.raimbault@gmail.com> | ... | ... |
doc/modbus_rtu_set_rts_delay.txt
0 → 100644
| 1 | +modbus_rtu_set_rts_delay(3) | |
| 2 | +=========================== | |
| 3 | + | |
| 4 | + | |
| 5 | +NAME | |
| 6 | +---- | |
| 7 | +modbus_rtu_set_rts_delay - set the RTS delay in RTU | |
| 8 | + | |
| 9 | + | |
| 10 | +SYNOPSIS | |
| 11 | +-------- | |
| 12 | +*int modbus_rtu_set_rts_delay(modbus_t *'ctx', int 'us');* | |
| 13 | + | |
| 14 | + | |
| 15 | +DESCRIPTION | |
| 16 | +----------- | |
| 17 | + | |
| 18 | +The _modbus_rtu_set_rts_delay()_ function shall set the Request To Send delay | |
| 19 | +period of the libmodbus context 'ctx'. | |
| 20 | + | |
| 21 | +This function can only be used with a context using a RTU backend. | |
| 22 | + | |
| 23 | + | |
| 24 | +RETURN VALUE | |
| 25 | +------------ | |
| 26 | +The _modbus_rtu_set_rts_delay()_ function shall return 0 if successful. | |
| 27 | +Otherwise it shall return -1 and set errno. | |
| 28 | + | |
| 29 | + | |
| 30 | +ERRORS | |
| 31 | +------ | |
| 32 | +*EINVAL*:: | |
| 33 | +The libmodbus backend is not RTU or a negative delay was specified. | |
| 34 | + | |
| 35 | + | |
| 36 | +SEE ALSO | |
| 37 | +-------- | |
| 38 | +linkmb:modbus_rtu_get_rts_delay[3] | |
| 39 | + | |
| 40 | + | |
| 41 | +AUTHORS | |
| 42 | +------- | |
| 43 | +Jimmy Bergström <jimmy@ekontroll.com> | |
| 44 | + | |
| 45 | +The libmodbus documentation was written by Stéphane Raimbault | |
| 46 | +<stephane.raimbault@gmail.com> | ... | ... |
src/modbus-rtu-private.h
| ... | ... | @@ -25,10 +25,6 @@ |
| 25 | 25 | |
| 26 | 26 | #define _MODBUS_RTU_CHECKSUM_LENGTH 2 |
| 27 | 27 | |
| 28 | -/* Time waited beetween the RTS switch before transmit data or after transmit | |
| 29 | - data before to read (1 ms) */ | |
| 30 | -#define _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH 1000 | |
| 31 | - | |
| 32 | 28 | #if defined(_WIN32) |
| 33 | 29 | #if !defined(ENOTSUP) |
| 34 | 30 | #define ENOTSUP WSAEOPNOTSUPP |
| ... | ... | @@ -69,6 +65,7 @@ typedef struct _modbus_rtu { |
| 69 | 65 | #endif |
| 70 | 66 | #if HAVE_DECL_TIOCM_RTS |
| 71 | 67 | int rts; |
| 68 | + int rts_delay; | |
| 72 | 69 | int onebyte_time; |
| 73 | 70 | void (*set_rts) (modbus_t *ctx, int on); |
| 74 | 71 | #endif | ... | ... |
src/modbus-rtu.c
| ... | ... | @@ -284,11 +284,11 @@ static ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_lengt |
| 284 | 284 | } |
| 285 | 285 | |
| 286 | 286 | ctx_rtu->set_rts(ctx, ctx_rtu->rts == MODBUS_RTU_RTS_UP); |
| 287 | - usleep(_MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH); | |
| 287 | + usleep(ctx_rtu->rts_delay); | |
| 288 | 288 | |
| 289 | 289 | size = write(ctx->s, req, req_length); |
| 290 | 290 | |
| 291 | - usleep(ctx_rtu->onebyte_time * req_length + _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH); | |
| 291 | + usleep(ctx_rtu->onebyte_time * req_length + ctx_rtu->rts_delay); | |
| 292 | 292 | ctx_rtu->set_rts(ctx, ctx_rtu->rts != MODBUS_RTU_RTS_UP); |
| 293 | 293 | |
| 294 | 294 | return size; |
| ... | ... | @@ -1028,6 +1028,57 @@ int modbus_rtu_get_rts(modbus_t *ctx) |
| 1028 | 1028 | } |
| 1029 | 1029 | } |
| 1030 | 1030 | |
| 1031 | +int modbus_rtu_set_rts_delay(modbus_t *ctx, int us) | |
| 1032 | +{ | |
| 1033 | + if (ctx == NULL || us < 0) { | |
| 1034 | + errno = EINVAL; | |
| 1035 | + return -1; | |
| 1036 | + } | |
| 1037 | + | |
| 1038 | + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | |
| 1039 | +#if HAVE_DECL_TIOCM_RTS | |
| 1040 | + modbus_rtu_t *ctx_rtu; | |
| 1041 | + ctx_rtu = (modbus_rtu_t *)ctx->backend_data; | |
| 1042 | + ctx_rtu->rts_delay = us; | |
| 1043 | + return 0; | |
| 1044 | +#else | |
| 1045 | + if (ctx->debug) { | |
| 1046 | + fprintf(stderr, "This function isn't supported on your platform\n"); | |
| 1047 | + } | |
| 1048 | + errno = ENOTSUP; | |
| 1049 | + return -1; | |
| 1050 | +#endif | |
| 1051 | + } else { | |
| 1052 | + errno = EINVAL; | |
| 1053 | + return -1; | |
| 1054 | + } | |
| 1055 | +} | |
| 1056 | + | |
| 1057 | +int modbus_rtu_get_rts_delay(modbus_t *ctx) | |
| 1058 | +{ | |
| 1059 | + if (ctx == NULL) { | |
| 1060 | + errno = EINVAL; | |
| 1061 | + return -1; | |
| 1062 | + } | |
| 1063 | + | |
| 1064 | + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { | |
| 1065 | +#if HAVE_DECL_TIOCM_RTS | |
| 1066 | + modbus_rtu_t *ctx_rtu; | |
| 1067 | + ctx_rtu = (modbus_rtu_t *)ctx->backend_data; | |
| 1068 | + return ctx_rtu->rts_delay; | |
| 1069 | +#else | |
| 1070 | + if (ctx->debug) { | |
| 1071 | + fprintf(stderr, "This function isn't supported on your platform\n"); | |
| 1072 | + } | |
| 1073 | + errno = ENOTSUP; | |
| 1074 | + return -1; | |
| 1075 | +#endif | |
| 1076 | + } else { | |
| 1077 | + errno = EINVAL; | |
| 1078 | + return -1; | |
| 1079 | + } | |
| 1080 | +} | |
| 1081 | + | |
| 1031 | 1082 | int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)) |
| 1032 | 1083 | { |
| 1033 | 1084 | if (ctx == NULL) { |
| ... | ... | @@ -1209,9 +1260,12 @@ modbus_t* modbus_new_rtu(const char *device, |
| 1209 | 1260 | ctx_rtu->rts = MODBUS_RTU_RTS_NONE; |
| 1210 | 1261 | |
| 1211 | 1262 | /* Calculate estimated time in micro second to send one byte */ |
| 1212 | - ctx_rtu->onebyte_time = (1000 * 1000) * (1 + data_bit + (parity == 'N' ? 0 : 1) + stop_bit) / baud; | |
| 1263 | + ctx_rtu->onebyte_time = 1000000 * (1 + data_bit + (parity == 'N' ? 0 : 1) + stop_bit) / baud; | |
| 1213 | 1264 | |
| 1214 | 1265 | ctx_rtu->set_rts = _modbus_rtu_ioctl_rts; |
| 1266 | + | |
| 1267 | + /* The delay before and after transmission when toggling the RTS pin */ | |
| 1268 | + ctx_rtu->rts_delay = ctx_rtu->onebyte_time; | |
| 1215 | 1269 | #endif |
| 1216 | 1270 | |
| 1217 | 1271 | ctx_rtu->confirmation_to_ignore = FALSE; | ... | ... |
src/modbus-rtu.h
| ... | ... | @@ -33,6 +33,9 @@ MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode); |
| 33 | 33 | MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx); |
| 34 | 34 | MODBUS_API int modbus_rtu_set_custom_rts(modbus_t *ctx, void (*set_rts) (modbus_t *ctx, int on)); |
| 35 | 35 | |
| 36 | +MODBUS_API int modbus_rtu_set_rts_delay(modbus_t *ctx, int us); | |
| 37 | +MODBUS_API int modbus_rtu_get_rts_delay(modbus_t *ctx); | |
| 38 | + | |
| 36 | 39 | MODBUS_END_DECLS |
| 37 | 40 | |
| 38 | 41 | #endif /* MODBUS_RTU_H */ | ... | ... |