RE: Modbus (was RE: FAQ anyone?)

  • Thread starter Campbell, David (Ex AS17)
  • Start date
C

Thread Starter

Campbell, David (Ex AS17)

Curt Wuollet wrote:

> No Modbus doesn't require special hardware, but does have
> some interesting requirements.

When I was in Bracknell (UK) earlier this year I saw a Modbus emulator program that runs under NT via the serial port. The only special hardware requirements is the RS-232 to the "flavour of the month" serial protocol (RS-422/485)

>> Also Modbus is not an open standard which may or may not
>> require special licensing (I am not a lawyer so this has to
>> come from someone who knows this!) terms.
>
> No it isn't an Open Standard but is widely implemented and
> I have not heard of Groupe Schnieder suing anyone although
> I suppose they could.
>

My reading of this is Groupe Schnieder retain the copyright so they have sole control over the protocol definition. Placing the protocol in the public domain would mean they would loose this "intellectual monopoly", to be fair they have earned that position by good will.

Remember that the copyright to the protocol and the copyright to source code are two different issues. Providing Groupe Schnieder's copyright to the protocol is noted (with a suitable
reference) then there should not be an issue. (Providing we do not copy any of the original protocol document into the source code, but that shouldn't be hard, we just don't comment the
code ;-)

I would need to do a web trawl and see if I can get some background info on how the first PC clone got it's BIOS. I vaguely remember something about two seperate groups of engineers, one reverse engineered the API, the second group coded a new BIOS from the API without looking at
the original BIOS dump. This survived a legal challenge from IBM however many years ago (15+ years).

I need to check the Australian copyright laws, there was something about reverse engineering for purposes of interoperability being legal (I think a couple of other countries have also introduced similar legislation). So Jini and myself might be legally safe (which team are you supporting in the AFL final Jini? Bombers or Demons?). In summary there are a number of avenues to explore as far as legal concerns go.

Finally we could always ask Groupe Schnieder for
permission to write source code using their published protocol. They may give us their blessing with a few conditions.

David Campbell

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
G

Gilles Allard

Receiving a Modbus RTU message is not easier.
The inter-character timer is not implemented in hardware. So it must be implemented in the driver (retriggered on every interrupt).
You should also disable the FIFO on the UART.
I do not think this protocol will be easy to implement on a general-purpose OS.

Gilles

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
M

Mario de Sousa

Yes, considering that I had also decided on not implementing it as a kernel device driver, there is simply nothing we can do on this respect.

Howerver, I do check whether the write() returns with the appropriate number of characters, and re-send otherwise. There is a maximum number of retries.

In other words, I may send out aborted frames! Not intentionally, mind you, but because the OS might be interrupted by something else during
the call to write(). So the slaves must be prepared to handle them.

I guess it would be better to continue sending an aborted frame, even if it has an interval larger than the 1.5 character limit? It seems most
implementations (at least on PCs, I don't know about PLCs, anyone?) don't care about these delays, and would therefore consider that frame
perfectly correct, even though it is not following the modbus spec.
But, on the other hand, if we are talking to a slave that follows the modbus spec, then it won't understand our query, and we will only re-issue it once we time-out on the response from that slave.

So, let me sum up my current doubt this way. Should we:
1) Continue sending a frame to the end, even though we know we have an interchacarcter interval larger than 1.5 characters.
2) Abort sending a frame that we know has an intercharacter interval larger than the 1.5 character time limit. Re-send the frame from the
start.

1) will we better for PC slave applications, that do not follow the spec, but worse for implementations that do follow the spec, because we will ony re-send the query after a time-out waiting for the response.
2) Is the other way around.

Currently my implementation uses 2), and my guess is that your's follows 1). Which one should it be?


I believe I will probably make this a user defined option. But the question remains, which of them should be the default? 1) which doesn't
follow the standard, or 2) that does?

(...)
>
> We do not detect aborted frames by the timing gap. We determine that
> the "message" we got isn't any good. At that point, we can either do
> something sophisticated or something simple. The sophisticated approach
> is to step through the available data stream, looking for the start of a
> legal message. The simple approach is to throw away the entire message
> (or collection of fragments, or noisy garbage, or whatever it was we
> actually got) and ask the question again.
>
> Personally, I prefer the simple solution. Any number of things can
> cause a response to be garbled, requiring that the master re-request the
> data. And noisy comm lines seem to occur a whole lot oftener than a
> deliberately aborted frame. So we keep the code simple and occasionally
> suffer a small inefficiency. I have implemented "sophisticated" before,
> to no apparent benefit. PuffinSCADA currently implements "simple".
>
> I'm pretty sure that's not the answer you were looking for, but I'll bet
> that more PC-based Modbus implementations do lazy error handling at the
> application level than do righteous realtime handling in a kernel
> module. And it seems to work for most people most of the time.

That is exactly the answer I was looking for! What you implemented, and most improtantly, the rationale behind it!

I have almost come to the decision of implementing both approaches. Doing my best to figure out what is being sent over the bus, but if all else fails, then re-send the query.

The reason I will probably go the hard way is that on the back of my mind I have always been considering re-using the same code for a modbus
slave module, and on a non-RT OS it seems to me that we can't be too lazy here, or else the slave gets out of synch with the state of the bus. Especially if the master follows the spec and uses the method 2) I discussed above.

I guess a lazy implementation will also work most of the time on a slave because
a) there will be very few aborted frames on the bus;
b) most query-response transactions will usually have large delays between the query and the response, and the slave will be able to synch
with the state of the bus using these silent intervals. But we have no guarantees this will occur, especially if the slave is on a heavily
loaded system.

Once again, I'm sorry for rambling on. I'm still considering all the pro's and con's of each approach. That's why I am asking for everybody's
ideas and opinions...



Cheers,

Mario.



--
----------------------------------------------------------------------------
Mario J. R. de Sousa
[email protected]
----------------------------------------------------------------------------

The box said it requires Windows 95 or better, so I installed Linux

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
G

Greg Goodman

> Howerver, I do check whether the write() returns with the appropriate
> number of characters, and re-send otherwise. There is a maximum number
> of retries.
>
> In other words, I may send out aborted frames! Not intentionally, mind
> you, but because the OS might be interrupted by something else during
> the call to write(). So the slaves must be prepared to handle them.

Sure. A write() that doesn't send the specified number of characters is a failed write. The assumption has to be that we put garbage on the
line, and that it will be ignored by the slave.

> I guess it would be better to continue sending an aborted frame, even
> if it has an interval larger than the 1.5 character limit? It seems most
> implementations (at least on PCs, I don't know about PLCs, anyone?)
> don't
> care about these delays, and would therefore consider that frame
> perfectly correct, even though it is not following the modbus spec.

It depends on how big the gap is, as perceived by the receiver (slave). If the message is completely available to the slave when it gets around to reading the port, then there is no gap. If the message is only partially available when the slave tries to read it, then it's garbage.

> So, let me sum up my current doubt this way. Should we:
> 1) Continue sending a frame to the end, even though we know we have an
> interchacarcter interval larger than 1.5 characters.
> 2) Abort sending a frame that we know has an intercharacter interval
> larger than the 1.5 character time limit. Re-send the frame from the
> start.

[snip]

> Currently my implementation uses 2), and my guess is that your's
> follows 1). Which one should it be?

If I understand your summary, our implementation uses (2). That is, if the write() fails, we resend the entire message. We do this in a retry
loop up to a configurable max, and implement a deliberate wait between writes to make sure the slave has time to clear the garbage. (The wait
is currently hard-coded, and should probably be calculated from the configured baud rate.)

> I believe I will probably make this a user defined option. But the
> question remains, which of them should be the default? 1) which doesn't
> follow the standard, or 2) that does?

I don't expect it will happen often enough to matter. Pick whichever one makes you happy. As long as it's an option, users can tune their
own applications. The fun part is documenting the configuration switch well enough to let users make well-informed choices.

> I have almost come to the decision of implementing both approaches.
> Doing my best to figure out what is being sent over the bus, but if all
> else fails, then re-send the query.

My suggestion: implement as many different approaches as you think are warranted, but start with the simplest, most robust, most bullet-proof,
easiest-to-maintain. Make sure it works. Then add sophistication as time and interest allow, or as practical application requirements
dictate.

> The reason I will probably go the hard way is that on the back of my
> mind I have always been considering re-using the same code for a modbus
> slave module, and on a non-RT OS it seems to me that we can't be too
> lazy here, or else the slave gets out of synch with the state of the
> bus. Especially if the master follows the spec and uses the method 2) I
> discussed above.
>
> I guess a lazy implementation will also work most of the time on a
> slave because ...

I agree. As I see it, the slave can afford to be as lazy as it likes. Since Modbus is a synchronous protocol, the master will not get an
acknowledgment for any message the slave chooses to ignore, and so will (probably) resend it. The communication takes place for the the master's benefit, and so it falls to the master to assume the burden of correcting comm faults. (Consider it a sort of passive-aggressive behavior on the part of the slave, which seems somehow appropriate. :^)

On the issue of duplication of effort, I wouldn't worry about it much. The portions of code that are likely to be share-able are the most
trivial: message formatting and parsing, CRC calculations, etc. The complicated part - deciding what data to ask for, converting application configuration into stdio() calls to configure the port, handling the data returned by a slave - is all very specific to the application, its configuration and its data structures. Which is not to say that there's
no reason to share code. Just that a surprisingly small portion of a "protocol driver" actually concerns itself with the protocol; the bulk of the driver deals with higher-level issues of configuration, database management and client/server communication.

Regards,

Greg

_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
A
Dear all.
I had read this email-list for a long time!
I just have been develop linux/dos modbus rtu module on our linux plc
So hope I could help on this topic...

I think everyone who ever implemented Modbus has come up with the same question. My interpretation of it is this.

The transmitter must ensure there is no gap larger than 1.5 character times.

The receiver detects the start of a new message as the first character following a gap of at least 3.5 character times. It detects the end of a
message when 3.5 character times elapse following a character.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
no matter!
modbus rtu master should implement continue sending query after slave response timeout


If the receiver detects a gap of more than 1.5 characters in the middle of a message, it should discard the message and wait for the start of a new message.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
just open 16550 UART fifo and enable interrupt every 1 or 4 bytes and your isr implement receiving routine
if no interrupt after 3.5 char time
usually 19200bps takes 30~40ms
usually 9600bps takes 40~60ms
then check crc
if crc error clear receiving data and do receiving loop again
if CRC is ok
parse receiving frame and build response frame and send it back

that's it!
Lost data is fine! Don't worry!
RS232 is not a guarantee interface

In practice you can likely skip the last test, since the test for the end of a message accomplishes the same thing, although the timing is not the same.
There are a lot of implementations out there that are not very good at meeting the first rule. Testing for it may make the driver work worse.



_______________________________________________
LinuxPLC mailing list
[email protected]
http://linuxplc.org/mailman/listinfo/linuxplc
 
Top