Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modbus RTU Server #45

Open
thegreatco opened this issue Sep 4, 2024 · 3 comments
Open

Modbus RTU Server #45

thegreatco opened this issue Sep 4, 2024 · 3 comments

Comments

@thegreatco
Copy link

thegreatco commented Sep 4, 2024

I need a library that can act as a server for Modbus RTU over RS-485. I already use this library for a Modbus client over RS-485. If I implement the server functionality for this library and submit a PR, are you open to reviewing and (hopefully) merging it?

@simonvetter
Copy link
Owner

Hi Pete,

thanks for your interest and offer!

Sure, go ahead and feel free to open a PR. I still have incoming changes that I've been meaning to merge for ages (e.g. file records) but I haven't been able to find time to work on this project lately, so don't expect a prompt review/merge though.

I remember digging into an RTU server implementation a few years back. One of the main issues was that because RTU has no proper framing, it must observe silence times to decide when the end of frame has been reached, and the serial library I've been using up to now isn't well suited to do that.

I've been able to work around that for the client part but the server will definitely need to handle it.

Happy to see someone else giving it a stab :)

@thegreatco
Copy link
Author

Sorry for the long delay. After a bunch of testing, it doesn't seem possible to fully respect the RTU timings on Linux. It might be possible with a real-time kernel, but I get random ~15ms pauses while reading. The pauses appear to be in Read, unclear where inside this method they actually are, but I suspect it is inside the for loop there.

I think for most situations involving actual modbus devices running real-time code (eg: PLCs), your existing readRTUFrame is sufficient to ensure packets are fully read. Perhaps some more sanity checks and better error handling would be helpful, but it should be fine given the constraints of using a high level OS with a real-time protocol.

What are your thoughts?

@simonvetter
Copy link
Owner

After a bunch of testing, it doesn't seem possible to fully respect the RTU timings on Linux.

I believe getting close to the theoretical timings is doable at least at bitrates <= 19200 bps, at the expense of higher CPU load.

Here's how RTU reads for the client currently work :

I believe the ~15ms pauses you're observing are due to that third step above (10ms read timeout on the actual serial port).
Either enough response bytes are received from the target device and the code shouldn't need to wait more than necessary, or we're hitting a timeout after at least 10ms, regardless of link speed.

That 10ms timeout was a design choice to reduce CPU load. I actually had it set to 1ms at the beginning, but the syscall overhead of calling Read() on the port that often was so taxing that I adjusted it.
Remember that I'm targeting both low-end embedded ARM/MIPS SoC and faster Intel industrial computers, so having something that works everywhere is a requirement. Hardware drivers on exotic platforms tend to be poorly tested or just perform badly, so this semi-active polling mechanism, while not ideal, has proven to be working fairly well.

So that's for the client part.

What are your thoughts?

So many thoughts, so little time :-)

Building an RTU server using the same tricks should be possible, although that would be a little more involved w.r.t timers (mostly to flush the RX buffer after 3.5 char times if the frame isn't complete).
I guess I'd start by rewriting or extending the RTU transport, but the biggest part would be thorough testing with multiple masters (SCADA systems, PLCs in master mode, etc.) which I don't necessarily have easy access to.

I'm open to try again if there's popular demand but I'd need time to dig into it... which is currently in short supply.
Paid sponsorships is something I'm open to discuss privately in case anyone is interested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants