Commit 9bf830959754a8909a8477fdd238dfb31e3216ce

Authored by Stéphane Raimbault
1 parent bb23b4ab

Add functions to set/get RS485 communications on Linux

@@ -18,7 +18,8 @@ libmodbus 2.9.4 (2011-05-XX) @@ -18,7 +18,8 @@ libmodbus 2.9.4 (2011-05-XX)
18 * modbus_set_timeout_begin -> modbus_set_response_timeout 18 * modbus_set_timeout_begin -> modbus_set_response_timeout
19 * modbus_get_timeout_end -> modbus_get_byte_timeout 19 * modbus_get_timeout_end -> modbus_get_byte_timeout
20 * modbus_set_timeout_end -> modbus_set_byte_timeout 20 * modbus_set_timeout_end -> modbus_set_byte_timeout
21 - 21 +- New functions modbus_set/get_serial_mode by Manfred Gruber and Stéphane
  22 + Raimbault for RS485 communications
22 23
23 libmodbus 2.9.3 (2011-01-14) 24 libmodbus 2.9.3 (2011-01-14)
24 ============================ 25 ============================
configure.ac
@@ -77,6 +77,7 @@ AC_CHECK_HEADERS([ \ @@ -77,6 +77,7 @@ AC_CHECK_HEADERS([ \
77 netinet/tcp.h \ 77 netinet/tcp.h \
78 arpa/inet.h \ 78 arpa/inet.h \
79 netdb.h \ 79 netdb.h \
  80 + linux/serial.h \
80 ]) 81 ])
81 82
82 # Check whether to build docs / install man pages 83 # Check whether to build docs / install man pages
src/modbus-rtu-private.h
@@ -74,6 +74,7 @@ typedef struct _modbus_rtu { @@ -74,6 +74,7 @@ typedef struct _modbus_rtu {
74 #else 74 #else
75 /* Save old termios settings */ 75 /* Save old termios settings */
76 struct termios old_tios; 76 struct termios old_tios;
  77 + int serial_mode;
77 #endif 78 #endif
78 } modbus_rtu_t; 79 } modbus_rtu_t;
79 80
src/modbus-rtu.c
@@ -30,6 +30,11 @@ @@ -30,6 +30,11 @@
30 #include "modbus-rtu.h" 30 #include "modbus-rtu.h"
31 #include "modbus-rtu-private.h" 31 #include "modbus-rtu-private.h"
32 32
  33 +#if defined(linux)
  34 +#include <sys/ioctl.h>
  35 +#include <linux/serial.h>
  36 +#endif
  37 +
33 /* Table of CRC values for high-order byte */ 38 /* Table of CRC values for high-order byte */
34 static const uint8_t table_crc_hi[] = { 39 static const uint8_t table_crc_hi[] = {
35 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 40 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
@@ -692,11 +697,55 @@ static int _modbus_rtu_connect(modbus_t *ctx) @@ -692,11 +697,55 @@ static int _modbus_rtu_connect(modbus_t *ctx)
692 if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) { 697 if (tcsetattr(ctx->s, TCSANOW, &tios) < 0) {
693 return -1; 698 return -1;
694 } 699 }
695 -#endif  
696 700
  701 + /* The RS232 mode has been set by default */
  702 + ctx_rtu->serial_mode = MODBUS_RTU_RS232;
  703 +#endif
697 return 0; 704 return 0;
698 } 705 }
699 706
  707 +#if defined(linux)
  708 +int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode)
  709 +{
  710 + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
  711 + modbus_rtu_t *ctx_rtu = ctx->backend_data;
  712 + struct serial_rs485 rs485conf;
  713 + memset(&rs485conf, 0x0, sizeof(struct serial_rs485));
  714 +
  715 + if (mode == MODBUS_RTU_RS485) {
  716 + rs485conf.flags = SER_RS485_ENABLED;
  717 + if (ioctl(ctx->s, TIOCSRS485, &rs485conf) < 0) {
  718 + return -1;
  719 + }
  720 +
  721 + ctx_rtu->serial_mode |= MODBUS_RTU_RS485;
  722 + return 0;
  723 + } else if (mode == MODBUS_RTU_RS232) {
  724 + if (ioctl(ctx->s, TIOCSRS485, &rs485conf) < 0) {
  725 + return -1;
  726 + }
  727 +
  728 + ctx_rtu->serial_mode = MODBUS_RTU_RS232;
  729 + return 0;
  730 + }
  731 + }
  732 +
  733 + /* Wrong backend and invalid mode specified */
  734 + errno = EINVAL;
  735 + return -1;
  736 +}
  737 +
  738 +int modbus_rtu_get_serial_mode(modbus_t *ctx) {
  739 + if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU) {
  740 + modbus_rtu_t *ctx_rtu = ctx->backend_data;
  741 + return ctx_rtu->serial_mode;
  742 + } else {
  743 + errno = EINVAL;
  744 + return -1;
  745 + }
  746 +}
  747 +#endif
  748 +
700 void _modbus_rtu_close(modbus_t *ctx) 749 void _modbus_rtu_close(modbus_t *ctx)
701 { 750 {
702 /* Closes the file descriptor in RTU mode */ 751 /* Closes the file descriptor in RTU mode */
src/modbus-rtu.h
@@ -28,4 +28,13 @@ @@ -28,4 +28,13 @@
28 modbus_t* modbus_new_rtu(const char *device, int baud, char parity, 28 modbus_t* modbus_new_rtu(const char *device, int baud, char parity,
29 int data_bit, int stop_bit); 29 int data_bit, int stop_bit);
30 30
  31 +#if defined(linux)
  32 +/* On Linux, we can tell the kernel for RS485 communication */
  33 +#define MODBUS_RTU_RS232 0
  34 +#define MODBUS_RTU_RS485 1
  35 +
  36 +int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);
  37 +int modbus_rtu_get_serial_mode(modbus_t *ctx);
  38 +#endif
  39 +
31 #endif /* _MODBUS_RTU_H_ */ 40 #endif /* _MODBUS_RTU_H_ */