35

I am working on a project involving a microcontroller communicating to a PC via Modbus over TCP. My platform is an STM32F4 chip, programming in C with no RTOS. I looked around and found LwIP and Freemodbus and have had pretty good success getting them both to work. Unfortunately, I'm now running into some issues which I'm not sure how to handle.

I've noticed that if I establish connection, then lose connection (by unplugging the Ethernet cable) I will not be able to reconnect (once I've plugged back in, of course). Freemodbus only allows one client and still has the first client registered. Any new clients trying to connect are ignored. It won't drop the first client until after a specific timeout period which, as far as I can tell, is a TCP/IP standard.

My thoughts are...

  1. I need a Modbus module that will handle multiple clients. The new client request after communication loss will be accepted and the first client will eventually be dropped due to the timeout.

    • How do I modify Freemodbus to handle this? Are there examples out there? I've looked into doing it myself and it appears to be a decently sized project.
    • Are there any good Modbus packages out there that handle multiple clients, are not too expensive, and easy to use? I've seen several threads about various options, but I'm not sure any of them meet exactly what I need. I've had a hard time finding any on my own. Most don't support TCP and the ones that do only support one client. Is it generally a bad idea to support multiple clients?
  2. Is something wrong with how I connect to the microcontroller from my PC?

    • Why is the PC changing ports every time it tries to reconnect? If it kept the same port it used before, this wouldn't be a problem
  3. Should I drop the client from Freemodbus as soon as I stop communicating?

    • This seems to go against standards but might work.

I'm leaning towards 1. Especially since I'm going to need to support multiple connections eventually anyways. Any help would be appreciated.

Thanks.

JNMarch
  • 359
  • 2
  • 5
  • 8
    Who ever close voted this is mistaken - this is a highly specific issue (though by no means an uncommon one), which the poster has already put a lot of thought into. – Chris Stratton Oct 04 '13 at 15:19
  • Generally TCP is designed with the idea of "real computers" (of decent resources) talking to each over a link which may be unreliable but recover, and goes to a fair degree of trouble to prevent a new connection from being mistaken for an old one. Thus the PC using a new port number on its end, and neither side immediately forgetting about the other. On a highly resource constrained system on a tightly secured network, one simple thing you can do is make it so that any incoming connection request causes the device to immediately forget any old/existing connection but that's not without risk. – Chris Stratton Oct 04 '13 at 15:22
  • Thanks for the response. I actually just implemented what you mentioned. New requests from the same IP address are accepted, old/existing connection is forgotten. Definitely agree that it comes with it's own risks. Also, it will be a problem when I eventually get around to allowing multiple clients. For now, it should help me move forward. I'm still hoping someone might have a better solution though. – JNMarch Oct 04 '13 at 18:49
  • You have few good options here. 1) find a way to use one of the non-standard ModBus/UDP implementations, 2) treat each message as a connection (have your client close connection once the reply is sent). If doing option 2 maybe look at [TCP for Transactions](http://www.embedded.com/design/connectivity/4023984/TCP-IP-for-Transactions) to minimize the TCP overhead. – Speed8ump Dec 21 '14 at 18:33
  • Do you really need ModBus at all? ModBus is designed for "master/slave" configurations. Originally designed for serial communication over IEEE-422/485 and other multi-drop serial transports. It's cool that tunneling over TCP is possible, but why use such an archaic protocol on something as shiny as the internet? – jwdonahue Dec 28 '17 at 03:48
  • 2
    @jwdonahue Modbus isn't more archaic than TCP is, actually it's still in use, and i'm using it right now. Moreover Modbus provides some things that TCP doesn't e.g. the adresses that you can map to specific functions of a device with a single IP address. To me Modbus TCP is fine. – Dali Jul 05 '19 at 14:38
  • Looks like someone tried to add multi client support over [here](https://github.com/eziya/STM32_HAL_FREEMODBUS_TCP) – Bosz Jul 19 '19 at 14:10
  • Do you actually need to keep the TCP connection alive, or could you manually close the connection by e.g. sending a FIN packet? This obviously results in some overhead as each read/write operation has to be initiated by first opening the connection, but depending on your use case it might be fine. – lindblandro Oct 12 '19 at 11:15
  • I think you need to write a `xMBPortEventGet ` callback that uses an even queue (using `poll` or `select` to fill the queue. I'm not sure. Also - are you limited to the Freemodbus library, of would you consider writing a custom protocol handler? If you don't mind rolling your own (or extracting the protocol handling logic from Freemodbus), you could use `poll` to manage multi-client connectivity manually. There are a bunch of evened IO libraries that will make it easy, such as libuv and facil.io. – Myst Feb 17 '20 at 23:03
  • If you avoid going blocked on the socket, you can time out the old connection, using something like poll() or O_NONBLOCK, and close it. Having a second connection raises the specter of having to lock resources (thus still locked out) or scrambling state (two cooks in the same kitchen). Timeout disconnect needs to restore any half modified state, of course! – David G. Pickett Jul 02 '20 at 19:52

0 Answers0