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,6 +129,8 @@ fi
129 129
130 # Check for RS485 support (Linux kernel version 2.6.28+) 130 # Check for RS485 support (Linux kernel version 2.6.28+)
131 AC_CHECK_DECLS([TIOCSRS485], [], [], [[#include <sys/ioctl.h>]]) 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 AC_CONFIG_FILES([ 135 AC_CONFIG_FILES([
134 Makefile 136 Makefile
src/modbus-rtu-private.h
@@ -37,6 +37,10 @@ @@ -37,6 +37,10 @@
37 37
38 #define _MODBUS_RTU_CHECKSUM_LENGTH 2 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 #if defined(_WIN32) 44 #if defined(_WIN32)
41 #define ENOTSUP WSAEOPNOTSUPP 45 #define ENOTSUP WSAEOPNOTSUPP
42 46
@@ -80,12 +84,8 @@ typedef struct _modbus_rtu { @@ -80,12 +84,8 @@ typedef struct _modbus_rtu {
80 #endif 84 #endif
81 #if HAVE_DECL_TIOCSRS485 85 #if HAVE_DECL_TIOCSRS485
82 int serial_mode; 86 int serial_mode;
83 - int use_rts; 87 + int rts;
84 #endif 88 #endif
85 } modbus_rtu_t; 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 #endif /* _MODBUS_RTU_PRIVATE_H_ */ 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,6 +257,21 @@ static int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg,
257 } 257 }
258 #endif 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 ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length) 275 ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
261 { 276 {
262 #if defined(_WIN32) 277 #if defined(_WIN32)
@@ -265,25 +280,23 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length) @@ -265,25 +280,23 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
265 return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1; 280 return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1;
266 #else 281 #else
267 modbus_rtu_t *ctx_rtu = ctx->backend_data; 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 if (ctx->debug) { 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 size = write(ctx->s, req, req_length); 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 return size; 298 return size;
283 } else { 299 } else {
284 - if (ctx->debug) {  
285 - fprintf(stderr, "sending request without RTS signal\n");  
286 - }  
287 return write(ctx->s, req, req_length); 300 return write(ctx->s, req, req_length);
288 } 301 }
289 #endif 302 #endif
@@ -726,7 +739,7 @@ static int _modbus_rtu_connect(modbus_t *ctx) @@ -726,7 +739,7 @@ static int _modbus_rtu_connect(modbus_t *ctx)
726 ctx_rtu->serial_mode = MODBUS_RTU_RS232; 739 ctx_rtu->serial_mode = MODBUS_RTU_RS232;
727 740
728 /* The RTS use has been set by default */ 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 #endif 744 #endif
732 745
@@ -789,35 +802,32 @@ int modbus_rtu_get_serial_mode(modbus_t *ctx) { @@ -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 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { 808 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
795 modbus_rtu_t *ctx_rtu = ctx->backend_data; 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 errno = EINVAL; 823 errno = EINVAL;
814 return -1; 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 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) { 828 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
819 modbus_rtu_t *ctx_rtu = ctx->backend_data; 829 modbus_rtu_t *ctx_rtu = ctx->backend_data;
820 - return ctx_rtu->use_rts; 830 + return ctx_rtu->rts;
821 } else { 831 } else {
822 errno = EINVAL; 832 errno = EINVAL;
823 return -1; 833 return -1;
@@ -975,17 +985,3 @@ modbus_t* modbus_new_rtu(const char *device, @@ -975,17 +985,3 @@ modbus_t* modbus_new_rtu(const char *device,
975 985
976 return ctx; 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,14 +32,14 @@ modbus_t* modbus_new_rtu(const char *device, int baud, char parity,
32 #define MODBUS_RTU_RS232 0 32 #define MODBUS_RTU_RS232 0
33 #define MODBUS_RTU_RS485 1 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 int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode); 35 int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);
40 int modbus_rtu_get_serial_mode(modbus_t *ctx); 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 #endif /* _MODBUS_RTU_H_ */ 45 #endif /* _MODBUS_RTU_H_ */