Looking for Modbus RTU frame receiver for Linux

R

Thread Starter

Ron

I need Modbus RTU support for my Linux application running on standard PC hardware. I know various drivers exist, but I need an implementation that accurately adheres to the spec defining a frame as a set of closely spaced bytes followed by 3.5 char times of silence. The various implementations around that identify the frame boundary by inspecting the content of the incoming bytes won't work for me.

Unfortunately, implementing to the dead-time spec is not feasible from outside the Linux kernel. Too much happens from the time a byte arrives off the wire until it's available to an application to accurately time its arrival. So, I believe my only recourse is a custom driver inside the kernel, and tightly coupled to the UART. I know others have posted about a similar need over the years, but I've never seen a solution.

Here's the driver I'm looking for:

1) Receives frames as defined per the 3.5 char times of silence spec, and passes them upwards to the application.

2) Sends frames passed down from the application, insuring that the outgoing bytes are tightly packed per the spec.

3) CRC checking and generation are optional. If not available, I can do it at the application level.

4) Stateless with regards to the Modbus RTU protocol machine. That will happen at the application level.

5) Completely agnostic of the Modbus application protocol.

6) The driver API is TBD, but there's flexibility here.

I'll take any and all suggestions, links, etc.

Thanks
 
The problem with depending on a strict implementation of the 3.5 character timing is that you can't control what is sent to you. When you send data you have to make sure the spacing is not *less* than 3.5 characters. Are you having problems with gaps in the middle of messages you are sending?

Have you looked at this one by the way? https://launchpad.net/libmodbus
 
I think a Modbus driver in user space is OK.

1 case: PC is Modbus master
In this case the PC application can call a sleep in milliseconds between each Modbus request. This can simply be done in the cycle where the Modbus signals are polled. We do this in our data acquisition daemons.

2 case: PC is Modbus slave
The PC application will get a timeout if it does not receive the whole Modbus frame from the master. Thus this cycle will be aborted. But the next cycle will be OK. Thus if you unplug/plug the cable for example in worst case 1 cycle will fail.

both cases:
We do only one write call to the serial interface per Modbus frame. Thus there is only one operating system request per frame. The OS should then take care that it writes the serial line without a pause between individual characters.

See our Modbus class:

http://pvbrowser.org/pvbrowser/sf/manual/rllib/html/classrlModbus.html

http://pvbrowser.org

A driver in user space also has the advantage that it can be portable. And it can support both RTU and TCP.
 
I have done this before, but you have to install the realtime version of the kernel, which makes the .tv_usec part of the timeval struct actually work for select(). Then in your c code, you just use the open() function to open the serial port, and use tcgetattr() and tcsetattr() to configure the port. Then you would use select() and read() to read data from the port with a specified timeout in microseconds (you really only get millisecond resolution on most machines, but thats 20 times better than you get without the realtime kernel).

I'm leaving out a whole lot of detail here (my code for a serial port driver daemon is around 1500 lines long), but that should get you started and give you an idea of the path to take.

I actually wrote my driver with very similar specs as you listed as a daemon that listens on a socket for serial data to transmit out the serial port, then passes the response back up the socket. It uses non blocking I/O and queing of requests to keep everything synchronized. Contact me off-board if you want more details.

Tim Kirk
tkirk [at] rogue-engr.com
 
Dear,

Could you please send me the general modbus frame.
I mean how the Modbus Request & Response frame look like.

Please send me link or photo

Regards.
 
As a clarification to my earlier post, by realtime kernel, I meant the CONFIG_PREEMPT and CONFIG_HIGH_RES_TIMERS, or whatever the latest similar option is set in the kernel. Without that, timers can't interrupt system processes, so even though your usec timer might have expired 500 usec ago your process won't regain the processor to handle it until the kernel level processes are done and give you a new processor timeslice, which may take several milliseconds depending on what the kernel is doing and what other high priority tasks are waiting on the processor.
 
Top