3cky / mbusd

Open-source Modbus TCP to Modbus RTU (RS-232/485) gateway.
BSD 3-Clause "New" or "Revised" License
565 stars 216 forks source link

Make use of Linux RS-485 Support #97

Closed equinox0815 closed 1 year ago

equinox0815 commented 1 year ago

I have a two port RS-422/RS-485 Mini-PCIe card which is based on the Exar XR17V352. This chip supports half-duplex RS-485 with automatic direction control but the latter needs to be enabled by the driver. On Linux this can be done using an ioctl. This is implemented by a number of serial port drivers with varying degree of support for the feature flags that can be set using this method. While enabling the mode can be done before or even while mbusd is running (currently i use the code below to enable the mode) it would be great if mbusd does this directly.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/serial.h>
#include <sys/ioctl.h>

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(int argc, char** argv)
{
  if (argc < 2) {
    printf("Usage: tty-rs485 <tty-device>\n");
    return -1;
  }

  int fd = open (argv[1], O_RDWR);
  if (fd < 0) {
    printf("open(): %s\n",strerror(errno));
    return -1;
  }

  struct serial_rs485 rs485conf;
  if (ioctl (fd, TIOCGRS485, &rs485conf) < 0) {
    printf("ioctl(TIOCGRS485): %s\n",strerror(errno));
    return -1;
  }

  rs485conf.flags |= SER_RS485_ENABLED;
  if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
    printf("ioctl(TIOCSRS485): %s\n",strerror(errno));
    return -1;
  }

  return 0;
}

I'm happy to create a PR for this but would like to get some input on how to make this configurable. My first idea was to add another possible value for trx_control (i.e. addc_ioctl) that basically works like addc but also instructs mbusd to set the SER_RS485_ENABLED feature flag after opening the serial device. For my use case this fine but it might be desirable to make use of the other features that can be controlled using the TIOCSRS485 ioctl.

While researching this topic i also came around this discussion which might be of interest.

3cky commented 1 year ago

I have added a new command line option -S and a config file option enable_rs485. By now mbusd only trying to enable RS-485 support for a given serial device, but there could be additional options to control RS-485 behavior in the future. Please update and test.

equinox0815 commented 1 year ago

I can confirm that the changes work on the hardware i'm using. Thanks!