Commit 27b39f7e45c754764db26e9b75497492067481e6

Authored by Stéphane Raimbault
1 parent 88b2eaf3

Review of RTS flow control code

- avoid export of _modbus_rtu_set_rts and change its name to avoid
  confusion
- namespace RTU functions and constants
- use_rts is renamed rts
- add missing '_' in function name
- remove useless debug message in usual write
- wrong message about 'not supported'
- add check for TIOCM_RTS support
- block RTS flow control when not available
configure.ac
... ... @@ -129,6 +129,8 @@ fi
129 129  
130 130 # Check for RS485 support (Linux kernel version 2.6.28+)
131 131 AC_CHECK_DECLS([TIOCSRS485], [], [], [[#include <sys/ioctl.h>]])
  132 +# Check for RTS flags
  133 +AC_CHECK_DECLS([TIOCM_RTS], [], [], [[#include <sys/ioctl.h>]])
132 134  
133 135 AC_CONFIG_FILES([
134 136 Makefile
... ...
src/modbus-rtu-private.h
... ... @@ -37,6 +37,10 @@
37 37  
38 38 #define _MODBUS_RTU_CHECKSUM_LENGTH 2
39 39  
  40 +/* Time waited beetween the RTS switch before transmit data or after transmit
  41 + data before to read */
  42 +#define _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH 10000
  43 +
40 44 #if defined(_WIN32)
41 45 #define ENOTSUP WSAEOPNOTSUPP
42 46  
... ... @@ -80,12 +84,8 @@ typedef struct _modbus_rtu {
80 84 #endif
81 85 #if HAVE_DECL_TIOCSRS485
82 86 int serial_mode;
83   - int use_rts;
  87 + int rts;
84 88 #endif
85 89 } modbus_rtu_t;
86 90  
87   -/* Time waited beetween the RTS switch before transmit data or after transmit data before to read */
88   -#define TIME_BETWEEN_RTS_SWITCH 10000
89   -void _modbus_rtu_setrts(int fd, int on);
90   -
91 91 #endif /* _MODBUS_RTU_PRIVATE_H_ */
... ...
src/modbus-rtu.c
... ... @@ -257,6 +257,21 @@ static int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg,
257 257 }
258 258 #endif
259 259  
  260 +void _modbus_rtu_ioctl_rts(int fd, int on)
  261 +{
  262 +#if HAVE_DECL_TIOCM_RTS
  263 + int flags;
  264 +
  265 + ioctl(fd, TIOCMGET, &flags);
  266 + if (on) {
  267 + flags |= TIOCM_RTS;
  268 + } else {
  269 + flags &= ~TIOCM_RTS;
  270 + }
  271 + ioctl(fd, TIOCMSET, &flags);
  272 +#endif
  273 +}
  274 +
260 275 ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
261 276 {
262 277 #if defined(_WIN32)
... ... @@ -265,25 +280,23 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
265 280 return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1;
266 281 #else
267 282 modbus_rtu_t *ctx_rtu = ctx->backend_data;
268   - if (ctx_rtu->use_rts != MODBUS_RTS_NONE) {
  283 + if (ctx_rtu->rts != MODBUS_RTU_RTS_NONE) {
  284 + ssize_t size;
  285 +
269 286 if (ctx->debug) {
270   - fprintf(stderr, "sending request using RTS signal\n");
  287 + fprintf(stderr, "Sending request using RTS signal\n");
271 288 }
272 289  
273   - ssize_t size;
274   -
275   - _modbus_rtu_setrts(ctx->s, (ctx_rtu->use_rts == MODBUS_RTS_UP ? 1 : 0));
276   - usleep(TIME_BETWEEN_RTS_SWITCH);
  290 + _modbus_rtu_ioctl_rts(ctx->s, ctx_rtu->rts == MODBUS_RTU_RTS_UP);
  291 + usleep(_MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH);
277 292  
278 293 size = write(ctx->s, req, req_length);
279   - usleep(TIME_BETWEEN_RTS_SWITCH);
280   - _modbus_rtu_setrts(ctx->s, (ctx_rtu->use_rts == MODBUS_RTS_UP ? 0 : 1));
  294 +
  295 + usleep(_MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH);
  296 + _modbus_rtu_ioctl_rts(ctx->s, ctx_rtu->rts != MODBUS_RTU_RTS_UP);
281 297  
282 298 return size;
283 299 } else {
284   - if (ctx->debug) {
285   - fprintf(stderr, "sending request without RTS signal\n");
286   - }
287 300 return write(ctx->s, req, req_length);
288 301 }
289 302 #endif
... ... @@ -726,7 +739,7 @@ static int _modbus_rtu_connect(modbus_t *ctx)
726 739 ctx_rtu->serial_mode = MODBUS_RTU_RS232;
727 740  
728 741 /* The RTS use has been set by default */
729   - ctx_rtu->use_rts = MODBUS_RTS_NONE;
  742 + ctx_rtu->rts = MODBUS_RTU_RTS_NONE;
730 743  
731 744 #endif
732 745  
... ... @@ -789,35 +802,32 @@ int modbus_rtu_get_serial_mode(modbus_t *ctx) {
789 802 }
790 803 }
791 804  
792   -int modbus_rtu_set_use_rts(modbus_t *ctx, int mode)
  805 +int modbus_rtu_set_rts(modbus_t *ctx, int mode)
793 806 {
  807 +#if HAVE_DECL_TIOCM_RTS
794 808 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
795 809 modbus_rtu_t *ctx_rtu = ctx->backend_data;
796   -
797   - if (mode == MODBUS_RTS_NONE || mode == MODBUS_RTS_UP || mode == MODBUS_RTS_DOWN) {
798   - ctx_rtu->use_rts = mode;
799 810  
800   - // Set the RTS bit in order to not reserve the RS485 bus
801   - _modbus_rtu_setrts(ctx->s, (ctx_rtu->use_rts == MODBUS_RTS_UP ? 0 : 1));
802   - return 0;
803   - }
  811 + if (mode == MODBUS_RTU_RTS_NONE || mode == MODBUS_RTU_RTS_UP ||
  812 + mode == MODBUS_RTU_RTS_DOWN) {
  813 + ctx_rtu->rts = mode;
804 814  
805   - if (ctx->debug) {
806   - fprintf(stderr, "This function isn't supported on your platform\n");
  815 + /* Set the RTS bit in order to not reserve the RS485 bus */
  816 + _modbus_rtu_ioctl_rts(ctx->s, ctx_rtu->rts != MODBUS_RTU_RTS_UP);
  817 +
  818 + return 0;
807 819 }
808   - errno = ENOTSUP;
809   - return -1;
810 820 }
811   -
812   - /* Wrong backend and invalid mode specified */
  821 +#endif
  822 + /* Wrong backend or invalid mode specified */
813 823 errno = EINVAL;
814 824 return -1;
815 825 }
816 826  
817   -int modbus_rtu_get_use_rts(modbus_t *ctx) {
  827 +int modbus_rtu_get_rts(modbus_t *ctx) {
818 828 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
819 829 modbus_rtu_t *ctx_rtu = ctx->backend_data;
820   - return ctx_rtu->use_rts;
  830 + return ctx_rtu->rts;
821 831 } else {
822 832 errno = EINVAL;
823 833 return -1;
... ... @@ -975,17 +985,3 @@ modbus_t* modbus_new_rtu(const char *device,
975 985  
976 986 return ctx;
977 987 }
978   -
979   -void _modbus_rtu_setrts(int fd, int on)
980   -{
981   - int controlbits;
982   -
983   - ioctl(fd, TIOCMGET, &controlbits);
984   - if (on) {
985   - controlbits |= TIOCM_RTS;
986   - } else {
987   - controlbits &= ~TIOCM_RTS;
988   - }
989   - ioctl(fd, TIOCMSET, &controlbits);
990   -}
991   -
... ...
src/modbus-rtu.h
... ... @@ -32,14 +32,14 @@ modbus_t* modbus_new_rtu(const char *device, int baud, char parity,
32 32 #define MODBUS_RTU_RS232 0
33 33 #define MODBUS_RTU_RS485 1
34 34  
35   -#define MODBUS_RTS_NONE 0
36   -#define MODBUS_RTS_UP 1
37   -#define MODBUS_RTS_DOWN 2
38   -
39 35 int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);
40 36 int modbus_rtu_get_serial_mode(modbus_t *ctx);
41 37  
42   -int modbus_rtu_set_use_rts(modbus_t *ctx, int mode);
43   -int modbus_rtu_get_use_rts(modbus_t *ctx);
  38 +#define MODBUS_RTU_RTS_NONE 0
  39 +#define MODBUS_RTU_RTS_UP 1
  40 +#define MODBUS_RTU_RTS_DOWN 2
  41 +
  42 +int modbus_rtu_set_rts(modbus_t *ctx, int mode);
  43 +int modbus_rtu_get_rts(modbus_t *ctx);
44 44  
45 45 #endif /* _MODBUS_RTU_H_ */
... ...