Hi Mark,
Thanks for looking into this. We hacked out the
epicsThreadSleep(0.02);
from modbusInterpose.c and my problem was solved - no more 20ms delay.
I found the Modbus specifications at - http://www.modbus.org/specs.php
There is no mention of a required delay in the Modbus Protocol
Application Specification V1.1b or in the Modbus Messaging on TCP/IP
Implementation Guide V1.0b.
In the Modbus Over Serial Line Specification and Implementation Guide
V1.02 there are references to delays allowing time for slaves to respond
to requests in the Master/Slave Serial implementation, and the optimal
length of delay depends on the communication rate and slave hardware.
It doesn't seem to me that this delay is needed for an Ethernet
implementation of Modbus, but it's not really my area of expertise.
Thanks again,
Rob
Excerpts from Modbus Over Serial Line Specification and Implementation
Guide V1.02
"When a broadcast request is sent on the serial bus, no response is
returned from the slaves. Nevertheless a delay is respected
by the Master in order to allow any slave to process the current request
before sending a new one. This delay is called
"Turnaround delay". Therefore the master goes into "Waiting Turnaround
delay" state before going back in "idle" state and before
being able to send another request."
"In unicast the Response time out must be set long enough for any slave
to process the request and return the response, in
broadcast the Turnaround delay must be long enough for any slave to
process only the request and be able to receive a new one.
Therefore the Turnaround delay should be shorter than the Response
time-out. Typically the Response time-out is from 1s to
several second at 9600 bps; and the Turnaround delay is from 100 ms to
200ms."
On 3/9/11 6:19 AM, Mark Rivers wrote:
Hi Rob,
I see the source of the 20ms delay. It is in modbusInterpose.c:
static asynStatus writeIt(void *ppvt, asynUser *pasynUser,
const char *data, size_t numchars,
size_t *nbytesTransfered)
{
modbusPvt *pPvt = (modbusPvt *)ppvt;
asynStatus status = asynSuccess;
...
epicsThreadSleep(0.02);
...
That delay was added in this commit to the code:
------------------------------------------------------------------------
r9770 | rivers | 2009-11-27 10:36:51 -0600 (Fri, 27 Nov 2009) | 1 line
Move slave address from interpose layer to modbus packet layer, allowing multiple slave address per asyn IP or serial port; add 20 ms delay per Modbus spec; changes made by Yves Lussignol
------------------------------------------------------------------------
I made the commit, but the changes were actually done by Yves Lussignol when he got Modbus RTU running with multiple slave addressess on a single serial line. His comment says that the 20ms delay is "per Modbus spec".
I have not actually tried to find that in the Modbus spec. Can Rob or Yves you have a look and see if it is in the spec for all transports (TCP, RTU, ASCII) or perhaps just for the RTU and/or ASCII? If the spec says it is transport dependent it is easy to make that change in modbusInterpose.c. The Modbus specs are in the documentation in the module, I just don't have time to work on it today.
Thanks,
Mark
________________________________
From: Mark Rivers
Sent: Tue 3/8/2011 6:10 PM
To: 'Robert Emery'; [email protected]
Subject: RE: Asyn/Modbus Delay
This is the first I have heard of this.
Here is the first thing to do. Set the asynTraceMask to 0x9 on the underlying asyn TCP port (AcromagDO1), and send the asyn output to a file with asynSetTraceFile. Then look at the timestamps to see if you learn anything. You can also then set the asynTraceMask on the asyn Modbus port (CCC:ACROMAGDO1:Modbus:Output) and send its output to a file. By sending the asynTrace output to a file you hopefully won't mess up the timing too much, though 20ms is still a pretty short delay to be tracking down.
Mark
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Robert Emery
Sent: Tuesday, March 08, 2011 6:01 PM
To: [email protected]
Subject: Asyn/Modbus Delay
We are using Modbus/Asyn to talk to a Acromag ES2113 digital I/O
device. Since updating our controller software (Linux 2.6.24 to 2.6.32,
EPICS 3.14.8.2 to 3.14.12, Asyn 4.8 to 4.15, Modbus 1.1 to 2.1) the
Modbus/Asyn communication has slowed down. There is now a .02 sec delay
in messages sent out (see below). To illustrate this I ran a simple db
with 4 linked longout records writing to the Modbus/Asyn port and looked
at the timing with wireshark.
Any ideas why the delay and how I can get around it?
Thanks
Rob Emery
UW Medical Center
Original Timing
Time Source Destination Protocol Info
0.000000 .0.33 .0.31 Modbus/TCP query
0.002218 .0.31 .0.33 Modbus/TCP response
0.002229 .0.33 .0.31 TCP 53105> 502 [ACK]
0.002288 .0.33 .0.31 Modbus/TCP query
0.005003 .0.31 .0.33 Modbus/TCP response
0.005166 .0.33 .0.31 Modbus/TCP query
0.007680 .0.31 .0.33 Modbus/TCP response
0.008171 .0.33 .0.31 Modbus/TCP query
0.010342 .0.31 .0.33 Modbus/TCP response
New Timing
Time Source Destination Protocol Info
0.000000 .0.33 .0.31 Modbus/TCP query
0.002168 .0.31 .0.33 Modbus/TCP response
0.003864 .0.33 .0.31 TCP 59583> asa-appl-proto
[ACK]
0.024044 .0.33 .0.31 Modbus/TCP query
0.026214 .0.31 .0.33 Modbus/TCP response
0.046431 .0.33 .0.31 Modbus/TCP query
0.048319 .0.31 .0.33 Modbus/TCP response
0.068693 .0.33 .0.31 Modbus/TCP query
0.071181 .0.31 .0.33 Modbus/TCP response
Port Configuration
## Create the Asyn IP ports
drvAsynIPPortConfigure("AcromagDO1","192.168.0.31:502",0,0,1)
## Apply The Modbus Configuration to the IP ports
modbusInterposeConfig("AcromagDO1",0,1000)
## Create Test Port
drvModbusAsynConfigure("CCC:ACROMAGDO1:Modbus:Output","AcromagDO1",0,6,59,
6, 0, 0, "Acro Test")
Test db
record(longout, Tuning:Asyn:Timing:Test:LongOut) {
field(SCAN, "Passive")
field(DTYP, "asynUInt32Digital")
field(FLNK, "Tuning:Asyn:Timing:Test:LongOut2")
field(OUT, "@asynMask(CCC:ACROMAGDO1:Modbus:Output 0 0xFFFF)")
field(OMSL, "supervisory")
field(VAL, "101")
}
record(longout, Tuning:Asyn:Timing:Test:LongOut2) {
field(SCAN, "Passive")
field(DTYP, "asynUInt32Digital")
field(FLNK, "Tuning:Asyn:Timing:Test:LongOut3")
field(OUT, "@asynMask(CCC:ACROMAGDO1:Modbus:Output 1 0xFFFF)")
field(OMSL, "supervisory")
field(VAL, "102")
}
record(longout, Tuning:Asyn:Timing:Test:LongOut3) {
field(SCAN, "Passive")
field(DTYP, "asynUInt32Digital")
field(FLNK, "Tuning:Asyn:Timing:Test:LongOut4")
field(OUT, "@asynMask(CCC:ACROMAGDO1:Modbus:Output 2 0xFFFF)")
field(OMSL, "supervisory")
field(VAL, "103")
}
record(longout, Tuning:Asyn:Timing:Test:LongOut4) {
field(SCAN, "Passive")
field(DTYP, "asynUInt32Digital")
field(OUT, "@asynMask(CCC:ACROMAGDO1:Modbus:Output 3 0xFFFF)")
field(OMSL, "supervisory")
field(VAL, "104")
}
- Replies:
- Re: Asyn/Modbus Delay Yves Lussignol
- References:
- RE: Asyn/Modbus Delay Mark Rivers
- RE: Asyn/Modbus Delay Mark Rivers
- Navigate by Date:
- Prev:
Re: EDM X/Y Eric Norum
- Next:
Re: edm 1-12.40 on epics 3.14.12 Angus Gratton
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
<2011>
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: Asyn/Modbus Delay Mark Rivers
- Next:
Re: Asyn/Modbus Delay Yves Lussignol
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
<2011>
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|