From 18fb6d086eece477236042a53dccde540c220330 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Fri, 29 Sep 2023 17:19:51 +0300 Subject: [PATCH 1/9] Fix tests for changes in pymodbus API --- tests/environment/rtu_slave.py | 6 +++--- tests/run_itests.py | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/environment/rtu_slave.py b/tests/environment/rtu_slave.py index 42d8a75..234dfae 100644 --- a/tests/environment/rtu_slave.py +++ b/tests/environment/rtu_slave.py @@ -14,7 +14,7 @@ #---------------------------------------------------------------------------# #from pymodbus.server.async import StartTcpServer #from pymodbus.server.async import StartUdpServer -from pymodbus.server.asynchronous import StartSerialServer +from pymodbus.server import StartSerialServer from pymodbus.device import ModbusDeviceIdentification from pymodbus.datastore import ModbusSequentialDataBlock @@ -92,7 +92,7 @@ def _start_rtu_server(self, framer=ModbusRtuFramer): hr = ModbusSequentialDataBlock(0, [0]*8), # holding regs ir = ModbusSequentialDataBlock(0, list(range(8))), # input regs zero_mode=True) # request(0-7) will map to the address (0-7) - context = ModbusServerContext(slaves=store, single=True) + context = ModbusServerContext(slaves={1: store}, single=False) #---------------------------------------------------------------------------# # initialize the server information @@ -112,7 +112,7 @@ def _start_rtu_server(self, framer=ModbusRtuFramer): #---------------------------------------------------------------------------# #StartTcpServer(context, identity=identity, address=("localhost", 5020)) #StartUdpServer(context, identity=identity, address=("localhost", 502)) - StartSerialServer(context, identity=identity, port=self.serialPort, baudrate=19200, framer=framer, broadcast_enable=True) + StartSerialServer(context=context, identity=identity, port=self.serialPort, baudrate=19200, framer=framer, broadcast_enable=True) #StartSerialServer(context, identity=identity, port='/dev/pts/3', framer=ModbusAsciiFramer) p = None diff --git a/tests/run_itests.py b/tests/run_itests.py index db77067..7c0ec78 100755 --- a/tests/run_itests.py +++ b/tests/run_itests.py @@ -8,7 +8,7 @@ from os.path import isfile from time import sleep -from pymodbus.client.sync import ModbusTcpClient +from pymodbus.client import ModbusTcpClient from pymodbus.pdu import ExceptionResponse from pymodbus.bit_read_message import ReadDiscreteInputsResponse, ReadCoilsResponse from pymodbus.bit_write_message import WriteMultipleCoilsResponse, WriteSingleCoilResponse @@ -62,35 +62,35 @@ def test_coils(self): bits = [random.randrange(2)>0 for i in range(8)] # 15 Write Multiple Coils - result = self.client.write_coils(0, bits, unit=1) + result = self.client.write_coils(0, bits, slave=1) self.assertIsInstance(result, WriteMultipleCoilsResponse, result) self.assertEqual(result.address, 0, result) self.assertEqual(result.count, 8, result) # 01 Read Coils - result = self.client.read_coils(0, 8, unit=1) + result = self.client.read_coils(0, 8, slave=1) self.assertIsInstance(result, ReadCoilsResponse, result) self.assertEqual(result.bits, bits, result) # 05 Write Single Coil bit1 = not bits[0] - result = self.client.write_coil(0, bit1, unit=1) + result = self.client.write_coil(0, bit1, slave=1) self.assertIsInstance(result, WriteSingleCoilResponse, result) self.assertEqual(result.address, 0, result) self.assertEqual(result.value, bit1, result) - result = self.client.read_coils(0, 1, unit=1) + result = self.client.read_coils(0, 1, slave=1) self.assertIsInstance(result, ReadCoilsResponse, result) self.assertEqual(result.bits[0], bit1, result) def test_discreteInputs(self): # 02 Read Discrete Inputs - result = self.client.read_discrete_inputs(0, 8, unit=1) + result = self.client.read_discrete_inputs(0, 8, slave=1) self.assertIsInstance(result, ReadDiscreteInputsResponse, result) self.assertEqual(result.bits, [True]*8, result) def test_inputRegisters(self): # 04 Read Input Registers - result = self.client.read_input_registers(0, 8, unit=1) + result = self.client.read_input_registers(0, 8, slave=1) self.assertIsInstance(result, ReadInputRegistersResponse, result) self.assertEqual(result.registers, list(range(8)), result) @@ -98,28 +98,28 @@ def test_holdingRegisters(self): registers = [random.randrange(8) for i in range(8)] # 16 Write Multiple Holding Registers - result = self.client.write_registers(0, registers, unit=1) + result = self.client.write_registers(0, registers, slave=1) self.assertIsInstance(result, WriteMultipleRegistersResponse, result) self.assertEqual(result.address, 0, result) self.assertEqual(result.count, 8, result) # 03 Read Multiple Holding Registers - result = self.client.read_holding_registers(0, 8, unit=1) + result = self.client.read_holding_registers(0, 8, slave=1) self.assertIsInstance(result, ReadHoldingRegistersResponse, result) self.assertEqual(result.registers, registers, result) # 06 Write Single Holding Register register1 = (registers[0] + 1) % 65535 - result = self.client.write_register(0, register1, unit=1) + result = self.client.write_register(0, register1, slave=1) self.assertIsInstance(result, WriteSingleRegisterResponse, result) self.assertEqual(result.address, 0, result) self.assertEqual(result.value, register1, result) - result = self.client.read_holding_registers(0, 1, unit=1) + result = self.client.read_holding_registers(0, 1, slave=1) self.assertIsInstance(result, ReadHoldingRegistersResponse, result) self.assertEqual(result.registers[0], register1, result) def test_exception(self): - result = self.client.write_coil(1000, False, unit=1) # invalid address 1000 + result = self.client.write_coil(1000, False, slave=1) # invalid address 1000 self.assertIsInstance(result, ExceptionResponse, result) self.assertEqual(result.original_code, 5, result) # fc05 Write Single Coil self.assertEqual(result.exception_code, 2, result) # Illegal Data Address @@ -127,10 +127,10 @@ def test_exception(self): def test_broadcast(self): registers = [random.randrange(8) for i in range(8)] # 16 Write Multiple Holding Registers - result = self.client.write_registers(0, registers, unit=0) + result = self.client.write_registers(0, registers, slave=0) # 03 Read Multiple Holding Registers - result = self.client.read_holding_registers(0, 8, unit=1) + result = self.client.read_holding_registers(0, 8, slave=1) self.assertIsInstance(result, ReadHoldingRegistersResponse, result) self.assertEqual(result.registers, registers, result) From 0f7a8c50fb6a93ad96eff0213e26d0132c1f1198 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Fri, 29 Sep 2023 17:20:23 +0300 Subject: [PATCH 2/9] Update .gitignore --- .gitignore | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 8ff65da..a18ea62 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,11 @@ -/autom4te.cache -/config.cache -/config.h -/config.status -/.settings/ -/src/.deps/ -/src/*.o -/src/mbusd -/doc/mbusd.8 -Makefile +/.settings *.log -*.in~ -systemd-units/mbusd@.service *.conf *.pyc -CMakeCache.txt -CMakeFiles -CPackConfig.cmake -CPackSourceConfig.cmake -cmake_install.cmake -.idea -*~ +/.idea +/.vscode .project .cproject -build +.pydevproject +/build +build.sh \ No newline at end of file From 6517dea57f6a5fbcbf77e0117947b9a2c31d014c Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Fri, 29 Sep 2023 18:04:09 +0300 Subject: [PATCH 3/9] Make use of Linux RS-485 support #97 --- CMakeLists.txt | 5 +++++ README.md | 9 ++++++--- conf/mbusd.conf.example | 3 +++ doc/mbusd.8.in | 6 ++++-- src/cfg.c | 9 +++++++++ src/cfg.h | 6 ++++++ src/globals.h | 1 + src/main.c | 21 ++++++++++++++++++--- src/tty.c | 22 ++++++++++++++++++++++ src/tty.h | 7 +++++++ 10 files changed, 81 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7102ec9..b72f3ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ project(mbusd VERSION 0.5.1) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/extern_GPL) include(CheckFunctionExists) include(CheckLibraryExists) +include(CheckSymbolExists) include(GNUInstallDirs) include(FindUnixCommands) include(FindSystemd) @@ -41,6 +42,10 @@ check_function_exists(cfsetispeed HAVE_CFSETISPEED) if(HAVE_CFSETSPEED AND HAVE_CFSETISPEED) add_definitions(-DHAVE_CFSETSPEED) endif() +check_symbol_exists(TIOCSRS485 sys/ioctl.h HAVE_TIOCRS485) +if(HAVE_TIOCRS485) + add_definitions(-DHAVE_TIOCRS485) +endif() check_function_exists(time HAVE_TIME) check_function_exists(localtime HAVE_LOCALTIME) if(HAVE_TIME AND HAVE_LOCALTIME) diff --git a/README.md b/README.md index 2943682..3c82d75 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,10 @@ can be altered in many ways, e.g. by using the following tools in the `build` di Usage: ------ - mbusd [-h] [-d] [-L logfile] [-v level] [-c cfgfile] [-p device] [-s speed] [-m mode] - [-t] [-y file] [-Y file] [-A address] [-P port] [-C maxconn] [-N retries] + mbusd [-h] [-d] [-L logfile] [-v level] [-c cfgfile] + [-p device] [-s speed] [-m mode] [-S] + [-t] [-y sysfsfile] [-Y sysfsfile] + [-A address] [-P port] [-C maxconn] [-N retries] [-R pause] [-W wait] [-T timeout] -h Usage help. @@ -73,6 +75,7 @@ Usage: Specifies serial port speed. -m mode Specifies serial port mode (like 8N1). + -S Enable RS-485 support for given serial port device (Linux only) -t Enable RTS RS-485 data direction control (if not disabled while compile). -y file Enable RS-485 direction data direction control by writing '1' to file @@ -95,7 +98,7 @@ Usage: -T timeout Specifies connection timeout value in seconds (0 disables timeout). -b - Instructs **mbusd** to reply on a broadcast. + Instructs mbusd to reply on a broadcast. Please note running **mbusd** on default Modbus TCP port (502) requires root privileges! diff --git a/conf/mbusd.conf.example b/conf/mbusd.conf.example index 67ae365..2cde560 100644 --- a/conf/mbusd.conf.example +++ b/conf/mbusd.conf.example @@ -15,6 +15,9 @@ speed = 9600 # Serial port mode mode = 8n1 +# Enable RS-485 support for given serial port device (Linux only) +# enable_rs485 = no + # RS-485 data direction control type (addc, rts, sysfs_0, sysfs_1) trx_control = addc diff --git a/doc/mbusd.8.in b/doc/mbusd.8.in index b1f9cc5..6aee070 100644 --- a/doc/mbusd.8.in +++ b/doc/mbusd.8.in @@ -19,9 +19,9 @@ mbusd \- MODBUS/TCP to MODBUS/RTU gateway. .IR mode ] .RB [ -t ] .RB [ -y -.IR file ] +.IR sysfsfile ] .RB [ -Y -.IR file ] +.IR sysfsfile ] .RB [ -A .IR address ] .RB [ -P @@ -60,6 +60,8 @@ Specifies serial port device name. Specifies serial port speed. .IP "\fB-m \fImode\fR" Specifies serial port mode (like 8N1). +.IP \fB-S\fR +Enable RS-485 support for given serial port device (Linux only). .IP "\fB-A \fIaddress\fR" Specifies TCP address to bind. .IP "\fB-P \fIport\fR" diff --git a/src/cfg.c b/src/cfg.c index a6c5abf..deb522c 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -64,6 +64,9 @@ cfg_init(void) strncpy(cfg.ttyport, DEFAULT_PORT, INTBUFSIZE); cfg.ttyspeed = DEFAULT_SPEED; strncpy(cfg.ttymode, DEFAULT_MODE, INTBUFSIZE); +#ifdef HAVE_TIOCRS485 + cfg.rs485 = FALSE; +#endif #ifdef TRXCTL cfg.trxcntl = TRX_ADDC; *cfg.trxcntl_file = '\0'; @@ -183,6 +186,12 @@ cfg_handle_param(char *name, char *value) cfg.conntimeout = strtoul(value, NULL, 0); if (cfg.conntimeout > MAX_CONNTIMEOUT) return 0; +#ifdef HAVE_TIOCRS485 + } + else if (CFG_NAME_MATCH("enable_rs485")) + { + cfg.rs485 = CFG_VALUE_BOOL(); +#endif #ifdef TRXCTL } else if (CFG_NAME_MATCH("trx_control")) diff --git a/src/cfg.h b/src/cfg.h index 0f0033f..f4b7fbd 100644 --- a/src/cfg.h +++ b/src/cfg.h @@ -54,10 +54,16 @@ typedef struct int ttyspeed; /* tty mode */ char ttymode[INTBUFSIZE + 1]; +#ifdef HAVE_TIOCRS485 + /* Linux RS-485 support use flag */ + bool rs485; +#endif +#ifdef TRXCTL /* trx control type (0 - ADDC, 1 - by RTS, 2 - by sysfs GPIO with 1 activating transmit, 3 - by sysfs GPIO with 0 activating transmit) */ int trxcntl; /* trx control sysfs file */ char trxcntl_file[INTBUFSIZE + 1]; +#endif /* TCP server address */ char serveraddr[INTBUFSIZE + 1]; /* TCP server port number */ diff --git a/src/globals.h b/src/globals.h index 77b7167..cb145a8 100644 --- a/src/globals.h +++ b/src/globals.h @@ -59,6 +59,7 @@ #include #include #include +#include #ifdef HAVE_LIBUTIL # include #endif diff --git a/src/main.c b/src/main.c index c04f3b4..79c91bc 100644 --- a/src/main.c +++ b/src/main.c @@ -107,7 +107,11 @@ usage(char *exename) "[-L logfile] [-v level] " #endif "[-c cfgfile] \n" - " [-p device] [-s speed] [-m mode]\n" + " [-p device] [-s speed] [-m mode]" +#ifdef HAVE_TIOCRS485 + " [-S]" +#endif + "\n" #ifdef TRXCTL " [-t] [-y sysfsfile] [-Y sysfsfile]\n" #endif @@ -129,6 +133,9 @@ usage(char *exename) " -p device : set serial port device name (default %s)\n" " -s speed : set serial port speed (default %d)\n" " -m mode : set serial port mode (default %s)\n" +#ifdef HAVE_TIOCRS485 + " -S : enable Linux RS-485 support for given serial port device\n" +#endif " -A address : set TCP server address to bind (default %s)\n" " -P port : set TCP server port number (default %d)\n" #ifdef TRXCTL @@ -182,6 +189,9 @@ main(int argc, char *argv[]) #ifdef TRXCTL "ty:Y:" #endif +#ifdef HAVE_TIOCRS485 + "S" +#endif #ifdef LOG "v:L:" #endif @@ -213,11 +223,16 @@ main(int argc, char *argv[]) case 'y': cfg.trxcntl = TRX_SYSFS_1; strncpy(cfg.trxcntl_file, optarg, INTBUFSIZE); - break; + break; case 'Y': cfg.trxcntl = TRX_SYSFS_0; strncpy(cfg.trxcntl_file, optarg, INTBUFSIZE); - break; + break; +#endif +#ifdef HAVE_TIOCRS485 + case 'S': + cfg.rs485 = TRUE; + break; #endif #ifdef LOG case 'v': diff --git a/src/tty.c b/src/tty.c index 0b377b5..92462c7 100644 --- a/src/tty.c +++ b/src/tty.c @@ -65,6 +65,9 @@ tty_init(ttydata_t *mod) { mod->bpc++; } +#ifdef HAVE_TIOCRS485 + mod->rs485 = cfg.rs485; +#endif #ifdef TRXCTL mod->trxcntl = cfg.trxcntl; #endif @@ -187,6 +190,25 @@ tty_set_attr(ttydata_t *mod) tcflush(mod->fd, TCIOFLUSH); #ifdef TRXCTL tty_clr_rts(mod->fd); +#endif +#ifdef HAVE_TIOCRS485 + if (mod->rs485) + { + struct serial_rs485 rs485conf; +#ifdef LOG + logw(2, "tty: trying to enable RS-485 support for %s", mod->port); +#endif + if (ioctl(mod->fd, TIOCGRS485, &rs485conf) < 0) { + return RC_ERR; + } + rs485conf.flags |= SER_RS485_ENABLED; + if (ioctl(mod->fd, TIOCSRS485, &rs485conf) < 0) { + return RC_ERR; + } +#ifdef LOG + logw(2, "tty: enabled RS-485 support for %s", mod->port); +#endif + } #endif flag = fcntl(mod->fd, F_GETFL, 0); if (flag < 0) diff --git a/src/tty.h b/src/tty.h index e49965f..fe7d82f 100644 --- a/src/tty.h +++ b/src/tty.h @@ -34,6 +34,10 @@ #ifndef _TTY_H #define _TTY_H +#ifdef HAVE_TIOCRS485 +#include +#endif + #include "globals.h" #include "cfg.h" @@ -96,6 +100,9 @@ typedef struct int speed; /* serial port speed */ char *port; /* serial port device name */ int bpc; /* bits per character */ +#ifdef HAVE_TIOCRS485 + bool rs485; /* use Linux RS-485 support flag */ +#endif #ifdef TRXCTL int trxcntl; /* trx control type (enum - see values in config.h) */ #endif From b464ec9676dd75d8a37be0460a2906e6071aac08 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Fri, 29 Sep 2023 18:09:00 +0300 Subject: [PATCH 4/9] Update version to 0.5.2 and year to 2023 --- CMakeLists.txt | 2 +- LICENSE | 2 +- src/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b72f3ac..413f742 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.2) -project(mbusd VERSION 0.5.1) +project(mbusd VERSION 0.5.2) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/extern_GPL) include(CheckFunctionExists) diff --git a/LICENSE b/LICENSE index 2df3efd..1b52725 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2002-2003, 2013-2022 Victor Antonovich (v.antonovich@gmail.com) +Copyright (c) 2002-2003, 2013-2023 Victor Antonovich (v.antonovich@gmail.com) Copyright (c) 2011 Andrew Denysenko All rights reserved. diff --git a/src/main.c b/src/main.c index 79c91bc..14e4637 100644 --- a/src/main.c +++ b/src/main.c @@ -100,7 +100,7 @@ void usage(char *exename) { cfg_init(); - printf("%s-%s Copyright (C) 2002-2003, 2011, 2013-2022 Victor Antonovich , " + printf("%s-%s Copyright (C) 2002-2003, 2011, 2013-2023 Victor Antonovich , " "Andrew Denysenko \n\n" "Usage: %s [-h] [-d] " #ifdef LOG From b07681842fdf15ef8bc9882b4b629b8c8a0ebb30 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Fri, 29 Sep 2023 18:16:45 +0300 Subject: [PATCH 5/9] Add pyserial as a dependency for github workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a59845..eade4dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: - name: Install test dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel twisted pymodbus + pip install setuptools wheel twisted pyserial pymodbus sudo apt-get install -y socat - name: Run tests From 4ee7e8a8343a94ce8f04d42866393e11396efde7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=ADan=20Hughes?= Date: Mon, 27 Nov 2023 12:14:38 +0000 Subject: [PATCH 6/9] Add new flag (-r) to support inverted RTS flow control\n\nThis is useful if you have a MAX485 connected to a Raspberry PI where you pull want RST low to transmit (#98) --- src/cfg.c | 6 +++++- src/main.c | 8 ++++++-- src/tty.c | 12 +++++++++--- src/tty.h | 7 ++++--- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/cfg.c b/src/cfg.c index deb522c..08b20f0 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -202,7 +202,11 @@ cfg_handle_param(char *name, char *value) } else if (CFG_VALUE_MATCH("rts")) { - cfg.trxcntl = TRX_RTS; + cfg.trxcntl = TRX_RTS_1; + } + else if (CFG_VALUE_MATCH("rts_0")) + { + cfg.trxcntl = TRX_RTS_0; } else if (CFG_VALUE_MATCH("sysfs_0")) { diff --git a/src/main.c b/src/main.c index 14e4637..b8d920e 100644 --- a/src/main.c +++ b/src/main.c @@ -139,7 +139,8 @@ usage(char *exename) " -A address : set TCP server address to bind (default %s)\n" " -P port : set TCP server port number (default %d)\n" #ifdef TRXCTL - " -t : enable RTS RS-485 data direction control using RTS\n" + " -t : enable RTS RS-485 data direction control using RTS, active transmit\n" + " -r : enable RTS RS-485 data direction control using RTS, active receive\n" " -y : enable RTS RS-485 data direction control using sysfs file, active transmit\n" " -Y : enable RTS RS-485 data direction control using sysfs file, active receive\n" #endif @@ -218,7 +219,10 @@ main(int argc, char *argv[]) break; #ifdef TRXCTL case 't': - cfg.trxcntl = TRX_RTS; + cfg.trxcntl = TRX_RTS_1; + break; + case 'r': + cfg.trxcntl = TRX_RTS_0; break; case 'y': cfg.trxcntl = TRX_SYSFS_1; diff --git a/src/tty.c b/src/tty.c index 92462c7..6a5280b 100644 --- a/src/tty.c +++ b/src/tty.c @@ -469,10 +469,13 @@ void sysfs_gpio_set(char *filename, char *value) { void tty_set_rts(int fd) { - if ( TRX_RTS == cfg.trxcntl ) { + if ( TRX_RTS_1 == cfg.trxcntl ) { int mstat = TIOCM_RTS; ioctl(fd, TIOCMBIS, &mstat); - } else if ( TRX_SYSFS_1 == cfg.trxcntl) { + } else if ( TRX_RTS_0 == cfg.trxcntl ) { + int mstat = TIOCM_RTS; + ioctl(fd, TIOCMBIC, &mstat); + } else if ( TRX_SYSFS_1 == cfg.trxcntl) { sysfs_gpio_set(cfg.trxcntl_file,"1"); } else if ( TRX_SYSFS_0 == cfg.trxcntl) { sysfs_gpio_set(cfg.trxcntl_file,"0"); @@ -483,9 +486,12 @@ tty_set_rts(int fd) void tty_clr_rts(int fd) { - if ( TRX_RTS == cfg.trxcntl ) { + if ( TRX_RTS_1 == cfg.trxcntl ) { int mstat = TIOCM_RTS; ioctl(fd, TIOCMBIC, &mstat); + } else if ( TRX_RTS_0 == cfg.trxcntl ) { + int mstat = TIOCM_RTS; + ioctl(fd, TIOCMBIS, &mstat); } else if ( TRX_SYSFS_1 == cfg.trxcntl) { sysfs_gpio_set(cfg.trxcntl_file,"0"); } else if ( TRX_SYSFS_0 == cfg.trxcntl) { diff --git a/src/tty.h b/src/tty.h index fe7d82f..f63fb74 100644 --- a/src/tty.h +++ b/src/tty.h @@ -77,9 +77,10 @@ */ #ifdef TRXCTL #define TRX_ADDC 0 -#define TRX_RTS 1 -#define TRX_SYSFS_1 2 -#define TRX_SYSFS_0 3 +#define TRX_RTS_1 1 +#define TRX_RTS_0 2 +#define TRX_SYSFS_1 3 +#define TRX_SYSFS_0 4 #endif /* From 20c87df994c617f6857ec7a642e9668d7bdb4d36 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Mon, 27 Nov 2023 15:43:34 +0300 Subject: [PATCH 7/9] Add `rts_1` config value as an alias for `rts` --- conf/mbusd.conf.example | 2 +- src/cfg.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/mbusd.conf.example b/conf/mbusd.conf.example index 2cde560..0599768 100644 --- a/conf/mbusd.conf.example +++ b/conf/mbusd.conf.example @@ -18,7 +18,7 @@ mode = 8n1 # Enable RS-485 support for given serial port device (Linux only) # enable_rs485 = no -# RS-485 data direction control type (addc, rts, sysfs_0, sysfs_1) +# RS-485 data direction control type (addc, rts_0, rts/rts_1, sysfs_0, sysfs_1) trx_control = addc # Sysfs file to use to control data direction diff --git a/src/cfg.c b/src/cfg.c index 08b20f0..f40af71 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -200,7 +200,7 @@ cfg_handle_param(char *name, char *value) { cfg.trxcntl = TRX_ADDC; } - else if (CFG_VALUE_MATCH("rts")) + else if (CFG_VALUE_MATCH("rts") || CFG_VALUE_MATCH("rts_1")) { cfg.trxcntl = TRX_RTS_1; } From b03d50b58c8243b532f6f53ff08c1989e90fb105 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Mon, 27 Nov 2023 16:21:31 +0300 Subject: [PATCH 8/9] Improve documentation --- README.md | 35 ++++++++++++++++++----------------- doc/mbusd.8.in | 9 ++++++--- src/main.c | 26 +++++++++++++------------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 3c82d75..c4fa410 100644 --- a/README.md +++ b/README.md @@ -54,19 +54,19 @@ Usage: mbusd [-h] [-d] [-L logfile] [-v level] [-c cfgfile] [-p device] [-s speed] [-m mode] [-S] - [-t] [-y sysfsfile] [-Y sysfsfile] + [-t] [-r] [-y sysfsfile] [-Y sysfsfile] [-A address] [-P port] [-C maxconn] [-N retries] - [-R pause] [-W wait] [-T timeout] + [-R pause] [-W wait] [-T timeout] [-b] -h Usage help. -d Instruct mbusd not to fork itself (non-daemonize). -L logfile - Specifies log file name ('-' for logging to STDOUT only, default is /var/log/mbusd.log). + Specifies log file name ('-' for logging to STDOUT only, relative path or bare filename + will be stored at /var/log, default is /var/log/mbusd.log). -v level - Specifies log verbosity level (0 for errors only, 1 for warnings - and 2 for also information messages.) If mbusd was compiled in debug mode, - valid log levels are up to 9, where log levels above 2 forces - logging of information about additional internal events. + Specifies log verbosity level (0 for errors only, 1 for warnings and 2 for informational + messages also). If mbusd was compiled in debug mode, valid log levels are up to 9, + where log levels above 2 adds logging of information about additional internal events. -c cfgfile Read configuration from cfgfile. -p device @@ -76,27 +76,28 @@ Usage: -m mode Specifies serial port mode (like 8N1). -S Enable RS-485 support for given serial port device (Linux only) - -t Enable RTS RS-485 data direction control (if not disabled while compile). + -t Enable RTS RS-485 data direction control using RTS, active transmit. + -r Enable RTS RS-485 data direction control using RTS, active receive. -y file Enable RS-485 direction data direction control by writing '1' to file - for transmitter enable and '0' to file for transmitter disable + for transmitter enable and '0' to file for transmitter disable. -Y file Enable RS-485 direction data direction control by writing '0' to file - for transmitter enable and '1' to file for transmitter disable + for transmitter enable and '1' to file for transmitter disable. -A address - Specifies TCP address to bind (default 0.0.0.0). + Specifies TCP server address to bind (default is 0.0.0.0). -P port - Specifies TCP port number (default 502). + Specifies TCP server port number (default is 502). -C maxconn - Specifies maximum number of simultaneous TCP connections. + Specifies maximum number of simultaneous TCP connections (default is 32). -N retries - Specifies maximum number of request retries (0 disables retries). + Specifies maximum number of request retries (0 disables retries, default is 3). -R pause - Specifies pause between requests in milliseconds. + Specifies pause between requests in milliseconds (default is 100ms). -W wait - Specifies response wait time in milliseconds. + Specifies response wait time in milliseconds (default is 500ms). -T timeout - Specifies connection timeout value in seconds (0 disables timeout). + Specifies connection timeout value in seconds (0 disables timeout, default is 60). -b Instructs mbusd to reply on a broadcast. diff --git a/doc/mbusd.8.in b/doc/mbusd.8.in index 6aee070..42c3b9b 100644 --- a/doc/mbusd.8.in +++ b/doc/mbusd.8.in @@ -18,6 +18,7 @@ mbusd \- MODBUS/TCP to MODBUS/RTU gateway. .RB [ -m .IR mode ] .RB [ -t ] +.RB [ -r ] .RB [ -y .IR sysfsfile ] .RB [ -Y @@ -67,13 +68,15 @@ Specifies TCP address to bind. .IP "\fB-P \fIport\fR" Specifies TCP port number. .IP \fB-t\fR -Enable RTS RS-485 data direction control (if not disabled while compile). +Enable RTS RS-485 data direction control using RTS, active transmit. +.IP \fB-r\fR +Enable RTS RS-485 data direction control using RTS, active receive. .IP "\fB-y \fIfile\fR" Enable RS-485 direction data direction control by writing '1' to file -for transmitter enable and '0' to file for transmitter disable +for transmitter enable and '0' to file for transmitter disable. .IP "\fB-Y \fIfile\fR" Enable RS-485 direction data direction control by writing '0' to file -for transmitter enable and '1' to file for transmitter disable +for transmitter enable and '1' to file for transmitter disable. .IP "\fB-C \fImaxconn\fR" Specifies maximum number of simultaneous TCP connections. .IP "\fB-N \fIretries\fR" diff --git a/src/main.c b/src/main.c index b8d920e..cedb992 100644 --- a/src/main.c +++ b/src/main.c @@ -113,7 +113,7 @@ usage(char *exename) #endif "\n" #ifdef TRXCTL - " [-t] [-y sysfsfile] [-Y sysfsfile]\n" + " [-t] [-r] [-y sysfsfile] [-Y sysfsfile]\n" #endif " [-A address] [-P port] [-C maxconn] [-N retries]\n" " [-R pause] [-W wait] [-T timeout] [-b]\n\n" @@ -121,23 +121,23 @@ usage(char *exename) " -h : this help\n" " -d : don't daemonize\n" #ifdef LOG - " -L logfile : set log file name (default %s%s, \n" + " -L logfile : set log file name (default is %s%s, \n" " '-' for logging to STDOUT only)\n" #ifdef DEBUG - " -v level : set log level (0-9, default %d, 0 - errors only)\n" + " -v level : set log level (0-9, default is %d, 0 - errors only)\n" #else " -v level : set log level (0-2, default %d, 0 - errors only)\n" #endif #endif " -c cfgfile : read configuration from cfgfile\n" - " -p device : set serial port device name (default %s)\n" - " -s speed : set serial port speed (default %d)\n" - " -m mode : set serial port mode (default %s)\n" + " -p device : set serial port device name (default is %s)\n" + " -s speed : set serial port speed (default is %d)\n" + " -m mode : set serial port mode (default is %s)\n" #ifdef HAVE_TIOCRS485 " -S : enable Linux RS-485 support for given serial port device\n" #endif - " -A address : set TCP server address to bind (default %s)\n" - " -P port : set TCP server port number (default %d)\n" + " -A address : set TCP server address to bind (default is %s)\n" + " -P port : set TCP server port number (default is %d)\n" #ifdef TRXCTL " -t : enable RTS RS-485 data direction control using RTS, active transmit\n" " -r : enable RTS RS-485 data direction control using RTS, active receive\n" @@ -145,15 +145,15 @@ usage(char *exename) " -Y : enable RTS RS-485 data direction control using sysfs file, active receive\n" #endif " -C maxconn : set maximum number of simultaneous TCP connections\n" - " (1-%d, default %d)\n" + " (1-%d, default is %d)\n" " -N retries : set maximum number of request retries\n" - " (0-%d, default %d, 0 - without retries)\n" + " (0-%d, default is %d, 0 disables retrying)\n" " -R pause : set pause between requests in milliseconds\n" - " (1-%d, default %lu)\n" + " (1-%d, default is %lu)\n" " -W wait : set response wait time in milliseconds\n" - " (1-%d, default %lu)\n" + " (1-%d, default is %lu)\n" " -T timeout : set connection timeout value in seconds\n" - " (0-%d, default %d, 0 - no timeout)\n" + " (0-%d, default is %d, 0 disables timeout)\n" " -b : enable reply on broadcast" "\n", PACKAGE, VERSION, exename, #ifdef LOG From 68f988051c9b6fc6bb2960da04e7642a96d6d5e7 Mon Sep 17 00:00:00 2001 From: Victor Antonovich Date: Mon, 27 Nov 2023 16:48:47 +0300 Subject: [PATCH 9/9] Rename `tty_(set|clr)_rts` to `tty_set_(tx|rx)` --- src/conn.c | 4 ++-- src/tty.c | 10 +++++----- src/tty.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/conn.c b/src/conn.c index f1fa0c7..9077f92 100644 --- a/src/conn.c +++ b/src/conn.c @@ -251,7 +251,7 @@ conn_write(int d, void *buf, size_t nbytes, int istty) #ifdef TRXCTL if (istty && cfg.trxcntl != TRX_ADDC) { - tty_set_rts(d); + tty_set_tx(d); tty_delay(35000000l/cfg.ttyspeed); } #endif @@ -267,7 +267,7 @@ conn_write(int d, void *buf, size_t nbytes, int istty) if (istty && cfg.trxcntl != TRX_ADDC ) { tty_delay(DV(nbytes, tty.bpc, cfg.ttyspeed)); - tty_clr_rts(d); + tty_set_rx(d); } #endif diff --git a/src/tty.c b/src/tty.c index 6a5280b..f557338 100644 --- a/src/tty.c +++ b/src/tty.c @@ -189,7 +189,7 @@ tty_set_attr(ttydata_t *mod) return RC_ERR; tcflush(mod->fd, TCIOFLUSH); #ifdef TRXCTL - tty_clr_rts(mod->fd); + tty_set_rx(mod->fd); #endif #ifdef HAVE_TIOCRS485 if (mod->rs485) @@ -465,9 +465,9 @@ void sysfs_gpio_set(char *filename, char *value) { } -/* Set RTS line to active state */ +/* Set tty device into transmit mode */ void -tty_set_rts(int fd) +tty_set_tx(int fd) { if ( TRX_RTS_1 == cfg.trxcntl ) { int mstat = TIOCM_RTS; @@ -482,9 +482,9 @@ tty_set_rts(int fd) } } -/* Set RTS line to passive state */ +/* Set tty device into receive mode */ void -tty_clr_rts(int fd) +tty_set_rx(int fd) { if ( TRX_RTS_1 == cfg.trxcntl ) { int mstat = TIOCM_RTS; diff --git a/src/tty.h b/src/tty.h index f63fb74..d00033c 100644 --- a/src/tty.h +++ b/src/tty.h @@ -128,8 +128,8 @@ int tty_set_attr(ttydata_t *mod); speed_t tty_transpeed(int speed); int tty_cooked(ttydata_t *mod); int tty_close(ttydata_t *mod); -void tty_set_rts(int fd); -void tty_clr_rts(int fd); +void tty_set_tx(int fd); +void tty_set_rx(int fd); void tty_delay(int usec); #endif /* _TTY_H */