Closed nzfarmer1 closed 9 years ago
You need libyaml development package installed in the system.
Currently I'm on heavy mbus-gw development. We're using it in pre-production to gate ext TCP and several RTU behind the number of serial ports with many Modbus-RTU devices on it. Other connection types untested: MBus-TCP <-> many mapped MBus-TCP and MBus-TCP <-> Moxa RealCOM proto.
There are several known bugs:
1. double free somewhere
2. epoll loop with no event data (almost 100% CPU load) after inbound connection close/lost, may be some race.
Ok I have it installed and running. Perhaps I can help track some bugs. I am looking to solve a similar. Can give me a heads up on running it and the config options? I want to run a slave on the serial side that will requests from multiple clients, then expose the registers via TCP.
have tried running
Error message: Error Response address 94 is different from request address 1
Config looks like this:
# Cache page TTL, cached answer will expired in 3 seconds. Every request for the same slave_id, function, address and length would get cached value
ttl: 3
# Number of TCP threads to serve incoming requests (optional)
workers: 4
# Default baud rate (optional)
baud: 115200
# List of endpoints
rtu:
- type: Modbus-RTU
device: /dev/ttyS1
# Map of incoming SlaveId to the destination (real) SlaveId
- map:
- src: 113
dst: 1
- src: 114
dst: 2
- type: Modbus-RTU
# Override default baud rate value
baud: 9600
device: /dev/ttyS2
- map:
- src: 10
dst: 1
- src: 12
dst: 16
On the clients side you should configure Modbus-TCP with the following options: host: your gateway IP slave: choose appropriate from 113, 114, 10 or 12 to achive 1, 2 on ttyS1 and 1, 16 on ttyS2 respectively. function (supported 1, 2, 3 and 4), address and number of registers corresponding to the end point devices' specification.
Sorry, just change two "#if 0" to "#if 1" in cfg.c or fetch latest commit from git.
To debug you may run modbus-gw under strace:
strace -fF -etrace=read,write,sendto,recvfrom -x -tt -s 128 ./mbus-gw And do same trace for client side to examine Modbus packets later in case of failure. With the current version there is no known problem with fetching registers from several endpoints.
Just found missed unlock() in cache_update() nearby line 142.
…and fixed up the double free error. Should be much-much stable right now.
Well done!
Only a place with buffer overflow stands.
Have fixed a lot of things including async requests for the same slave id on the same port. Tested with 8 ports, 100+ slaves and over 400+ standalone registers. On the ARM hardware it takes around 10 seconds (with 5 sec timeout/request) to read all requested registers at 19200. No buffer overflows, no double free anymore.
That's great Anton, I must take another look.
Right now I am developing a Stream library that creates a transparent layer on top of XBees API layer. On the gateway side I can expose ports to the individual streams via UNIX sockets or character special devices then run ModbusRTU on the ARM processors .
With your software can I create a map and say
IP : Port : slaveId1 -> /dev/tty.xxx
IP : Port : slaveId2 -> /dev/tty.zzz
Yes, just add:
baud: 115200
rtu:
- type: Modbus-RTU
device: /dev/ttt.xxx
# Map of incoming SlaveId to the destination (real) SlaveId
- map:
- src: slaveId1
dst: slaveId1
- type: Modbus-RTU
device: /dev/ttt.yyy
- map:
- src: slaveId2
dst: slaveId2
In the next few days I will rewrite config part to JSON-format to work with already ported cJSON to NuttX.
Hi Anton
Hope you are well.
Am just about to try out your updated code.
Here is the use case I have:
I thought I could use socat to create a tunnel between the device and a tcp listener but it doesn't seem to work.
i.e.: socat -d -d -v tcp4-connect:127.0.0.1:1503 "/dev/tty.usbserial-A50285BI,raw,ispeed=115200,ospeed=115200"
Andrew
Hi. Modbus RTU and Modbus TCP has a slightly different header. TCP includes TID (Transaction ID), magic number and additional packet length of the following data like in RTU answer. Sametime RTU has CRC (last two bytes). So, you cannot just pass through (wrap) data between Modbus RTU <-> Modbus TCP. My modbus-gateway designed to proxy Modbus TCP to Modbus RTU. gateway acts like a Modbus Master. What kind of Modbus Master do you have? Usually, Master is directly connected to the RS-485 network or so. If your Master is a software (you may configure system ports to connect to), then you need to build virtual serial device and pass it to the remote host. Please pay attention, that the remote side have to be a real serial device accepting Modbus RTU. You can try as a "man socat" stated:
socat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \ EXEC:'"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"'
Then you'll have a local $HOME/dev/vmodem0 serial device passing data to the /dev/ttyS0 on modemserver.us.org.
Thanks Anton
I battled for a night with this and am yet to succeed. This is where I got to, but am still only getting 1 byte transferred at a time and socket timeouts on the TCP slave.
The Rtu slave works ok, but I'd prefer TCP so I can share it and exchange data - i.e. expose it to another device.
socat -t5 -b8 -d -d -d -d -t15 "tcp4:127.0.0.1:1503,sndlowat=8,readbytes=8,ignoreeof" "file:/dev/tty.usbserial-A50285BI,raw,nonblock,ignoreeof,readbytes=8,waitlock=/tmp/usbserial-A50285BI.lo
Please consider the environment before printing this email.
Any information contained within this email is for the use of the recipient only and is sent in confidence. The information may not be copied, distributed or forwarded to any other parties. This information may not be used by any other person or organization. If you have received this in error, please notify us immediately by return mail and return the message with your notification.
If you would like to stop receiving correspondence from this email address, please confirm by return mail.
On 20/11/2015, at 12:42 am, Anton D. Kachalov notifications@github.com wrote:
Hi. Modbus RTU and Modbus TCP has a slightly different header. TCP includes TID (Transaction ID), magic number and additional packet length of the following data like in RTU answer. Sametime RTU has CRC (last two bytes). So, you cannot just pass through (wrap) data between Modbus RTU <-> Modbus TCP. My modbus-gateway designed to proxy Modbus TCP to Modbus RTU. gateway acts like a Modbus Master. What kind of Modbus Master do you have? Usually, Master is directly connected to the RS-485 network or so. If your Master is a software (you may configure system ports to connect to), then you need to build virtual serial device and pass it to the remote host. Please pay attention, that the remote side have to be a real serial device accepting Modbus RTU. You can try as a "man socat" stated:
socat PTY,link=$HOME/dev/vmodem0,rawer,wait-slave \ EXEC:'"ssh modemserver.us.org socat - /dev/ttyS0,nonblock,rawer"'
Then you'll have a local $HOME/dev/vmodem0 serial device passing data to the /dev/ttyS0 on modemserver.us.org.
— Reply to this email directly or view it on GitHub.
Andrew, if you want to expose RTU device (serial) as the Modbus TCP, you may use my modbus-gateway. It is designed for. Just configure mbus.conf:
# Port speed
baud: 115200
# Cache TTL
ttl: 1
# Timeout for proxied requests
timeout: 1
# RTU config
rtu:
- type: Modbus-RTU
device: /dev/tty.usbserial-A50285BI
# Map of incoming SlaveId to the destination (real) SlaveId
- map:
- src: 1
dst: 1
- src: 2
dst: 2
- src: 3
dst: 3
And then run mbus-gw from the same directory. Then you'll able to multi-connect to the your RTU device via TCP. You may want to map SlaveID. For one port config just map one-to-one.
Thanks Anton
I actually have two use cases. I have developed a reliable datagram protocol that allows me to send addressed messages of individual Xbee wireless nodes - yet appear as a dedicated serial stream to the end devices.
The end devices can then work in either Master or Slave mode. I also encapsulated the Stream library so that the Modbus master/slave on the nodes can use a Hardware Serial; Software Serial; or xStream (my protocol) Serial interface.
Your solition should help for the Slave mode but am not sure about when the end nodes become the master and needs to update a TCP slave.
Please consider the environment before printing this email.
Any information contained within this email is for the use of the recipient only and is sent in confidence. The information may not be copied, distributed or forwarded to any other parties. This information may not be used by any other person or organization. If you have received this in error, please notify us immediately by return mail and return the message with your notification.
If you would like to stop receiving correspondence from this email address, please confirm by return mail.
On 20/11/2015, at 9:30 am, Anton D. Kachalov notifications@github.com wrote:
Andrew, if you want to expose RTU device (serial) as the Modbus TCP, you may use my modbus-gateway. It is designed for. Just configure mbus.conf:
baud: 115200 rtu:
- type: Modbus-RTU device: /dev/tty.usbserial-A50285BI
Map of incoming SlaveId to the destination (real) SlaveId
- map:
- src: 1 dst: 1
- src: 2 dst: 2 And then run mbus-gw from the same directory. Then you'll able to multi-connect to the your RTU device.
— Reply to this email directly or view it on GitHub.
Ha
All I had to do was add a 6 byte header!
Great! :)
Hi Anton
Just want to check again as I might be able to do something with your code.
When you say "incoming SlaveId" do you mean that the src would be an RTU Master, and that your Gateway would then be a TCP Master, and that the dst would be a TCP Slave?
I can socat between my UNIX sockets and psuedo terminal, or change your code to read from a socket instead of a device.
And would it be possible to reverse this scenario and make src be incoming TCP Master and slave be the RTU?
Thanks
Andrew
Yes, just add:
baud: 115200 rtu:
- type: Modbus-RTU device: /dev/ttt.xxx
Map of incoming SlaveId to the destination (real) SlaveId
- map:
- src: slaveId1 dst: slaveId1
- type: Modbus-RTU device: /dev/ttt.yyy
- map:
- src: slaveId2 dst: slaveId2 — Reply to this email directly or view it on GitHub.
Hello. Let me clarify a few things. modbus-gate acts as Modbus Master and Slave at the same time. Slave mode is to listen for TCP-connections and serve requests for Modbus-TCP and pass it to the RTU (mostly) as a Master. From RTU side modbus-gate acts as a Master:
TCP-client <-> Modbus-TCP <-> Slave ]| GATE |[ Master <-> Modbus-RTU <-> Serial slaves
So, modbus-gate just pass TCP-requests to RTU slaves (serial) and convert an answers back to TCP format.
Hi Anton
Thank you! Perhaps a README file in your repo would be good?
I ended up rolling my own yesterday. This interfaces is between either a ModbusTCPMaster and an RTU Slave exposes via a UNIX socket, or provides a TCP Listener for an RTU Slave.
It is nodejs, so the development time was fast, and the run time less so - but it seems fine for our purposes! See attached.
cheers
Andrew
Please consider the environment before printing this email.
Any information contained within this email is for the use of the recipient only and is sent in confidence. The information may not be copied, distributed or forwarded to any other parties. This information may not be used by any other person or organization. If you have received this in error, please notify us immediately by return mail and return the message with your notification.
If you would like to stop receiving correspondence from this email address, please confirm by return mail.
On 11/12/2015, at 3:35 am, Anton D. Kachalov notifications@github.com wrote:
Hello. Let me clarify a few things. modbus-gate acts as Modbus Master and Slave at the same time. Slave mode is to listen for TCP-connections and serve requests for Modbus-TCP and pass it to the RTU (mostly) as a Master. From RTU side modbus-gate acts as a Master:
TCP-client <-> Modbus-TCP <-> Slave ]| GATE |[ Master <-> Modbus-RTU <-> Serial slaves
— Reply to this email directly or view it on GitHub.
Hi, Andrew.
README should be a good idea :) Good luck!
Any tips for building on Linux? thx.