EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Modbus TCP/IP "PSH" Command
From: Tobin Weber <[email protected]>
To: Mark Rivers <[email protected]>, "[email protected]" <[email protected]>
Date: Fri, 05 Sep 2014 11:25:17 -0700
Hi Mark,

First, thanks very much for the reply. The "asynSetTraceIOMask"/"asynSetTraceMask" are two fantastic tools that I did not know about. That is extremely helpful

Here is the output from dbpr(AcroRead,10):

epics> dbpr(AcroRead,10)
ACKS: NO_ALARM      ACKT: YES           ACMD: None          ADDR: 0            
AINP: �            AOUT:               AQR: 0              ASG:               
ASP: (nil)          AUCT: autoConnect   BAUD: Unknown       BINP: 0            
BKPT: 00            BOUT: 0             CNCT: Connect       DBIT: Unknown      
DESC:               DISA: 0             DISP: 0             DISS: NO_ALARM     
DISV: 1             DPVT: 0x211de40     DRVINFO:            DSET: 0x7f8de3f05600
DTYP: asynRecordDevice                  ENBL: Enable        EOMR: None         
ERRS: 0x211e1e0     EVNT: 0             F64INP: 0           F64IV: 0           
F64OUT: 0           FCTL: Unknown       FLNK:CONSTANT 0     GPIBIV: 0          
I32INP: 0           I32IV: 0            I32OUT: 0           IEOS:              
IFACE: asynOctet    IFMT: ASCII         IMAX: 80            IPTR: 0x211e120    
IXANY: Unknown      IXOFF: Unknown      IXON: Unknown       LCNT: 0            
LSET: 0x211ea80     MCTL: Unknown      
MLIS: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00              
MLOK: 10 de 11 02 00 00 00 00           NAME: AcroRead      NAWT: 0            
NORD: 2             NOWT: 80            NRRD: 0             NSEV: NO_ALARM     
NSTA: NO_ALARM      OCTETIV: 1          OEOS:               OFMT: ASCII        
OMAX: 80            OPTIONIV: 0         OPTR: 0x211e0c0     PACT: 0            
PCNCT: Connect      PHAS: 0             PINI: NO            PORT: ReadPort     
PPN: (nil)          PPNR: (nil)         PRIO: LOW           PROC: 0            
PRTY: Unknown       PUTF: 0             RDES: 0x208aa60     REASON: 0          
RPRO: 0             RSET: 0x7f8de3f05640                    SBIT: Unknown      
SCAN: 1 second      SDIS:CONSTANT       SEVR: NO_ALARM      SPR: 0             
SPVT: 0x2121b90     STAT: NO_ALARM      TB0: On             TB1: Off           
TB2: Off            TB3: Off            TB4: Off            TFIL: Unknown      
TIB0: Off           TIB1: Off           TIB2: Off          
TIME: 2014-09-05 11:06:56.551352761     TINP: \357\001      TIOM: 0            
TMOD: Write/Read    TMOT: 1             TMSK: 1             TPRO: 0            
TSE: 0              TSEL:CONSTANT       TSIZ: 80            UCMD: None         
UDF: 0              UI32INP: 0          UI32IV: 0           UI32MASK: 4294967295
UI32OUT: 0          VAL: 0

That explanation is very clear. An empty .AOUT field, when processed through the modbusInterposeInterface, translates to a "PSH" command, in TCP language (probably from the mbapHeader).

I inherited this code and was trying to trouble shoot. We previously were reading the .CNCT and .ERRS fields from the asyn record with an empty .AOUT field. I think I had it in my head that this needed to stay in. I had just assumed this was a valid way of checking the communication.  As you pointed out, this doesn't really make sense. I'm not sure if this was even really checking anything (it probably wasn't). Thanks very much for clearing that up.

Our new method is to read the ".STAT" field of a Asyn record setup to read a status register on the Acromag Device. That appears to detect if the Acromag device isn't responding.

Thanks again for that very helpful explanation.

Toby



On 09/05/2014 10:16 AM, Mark Rivers wrote:

Hi Tobin,

 

Can you please send the output of the following command at the IOC prompt:

 

dbpr(“AcroRead”,10)

 

That will show us the content of all the fields of the asyn record.

 

If the only settings of the fields in that record comes from the asynRecord.dbd file and the PortCheck.vdb file you sent, then it should be sending the contents of the AOUT field and reading back into the AINP field.  The AOUT field should be an empty string unless it has somehow been set otherwise.

 

But the asyn record is talking to the port through the modbusInterposeInterface.  This is the code from the write function in the modbusInterpose driver for TCP links:

 

/* asynOctet methods */

static asynStatus writeIt(void *ppvt, asynUser *pasynUser,

                          const char *data, size_t numchars,

                          size_t *nbytesTransfered)

{

    modbusPvt  *pPvt = (modbusPvt *)ppvt;

    asynStatus status = asynSuccess;

    size_t     nbytesActual = 0;

    size_t     nWrite;

    modbusMBAPHeader mbapHeader;

    unsigned short transactId=1;

    unsigned short cmdLength = numchars;

    unsigned short modbusEncoding=0;

    int mbapSize = sizeof(modbusMBAPHeader);

    unsigned char CRC_Hi;

    unsigned char CRC_Lo;

    unsigned char LRC;

    char *pout;

    int i;

 

    if (pPvt->writeDelay > 0.0) epicsThreadSleep(pPvt->writeDelay);

   

    pasynUser->timeout = pPvt->timeout;

 

    switch(pPvt->linkType) {

        case modbusLinkTCP:

            /* Build the MBAP header */

            mbapHeader.transactId    = htons(transactId);

            mbapHeader.protocolType  = htons(modbusEncoding);

            mbapHeader.cmdLength     = htons(cmdLength);

            /* Copy the MBAP header to the local buffer */

            memcpy(pPvt->buffer, &mbapHeader, mbapSize);

 

            /* Copy the Modbus data to the local buffer */

            memcpy(pPvt->buffer + mbapSize, data, numchars);

 

            /* Send the frame with the underlying driver */

            nWrite = numchars + mbapSize;

            status = pPvt->pasynOctet->write(pPvt->octetPvt, pasynUser,

                                             pPvt->buffer, nWrite,

                                             &nbytesActual);

            *nbytesTransfered = (nbytesActual > numchars) ? numchars : nbytesActual;

            break;

 

So the modbusInterpose layer is adding some additional bytes to the start of the message (the mbapHeader).  I suspect those are what you are seeing as “PSH”.

 

You should not need to use Wireshark to diagnose this if indeed the string is coming from the IOC.  You should just be able to do the following in your st.cmd file:

 

# Set the TRACEIO_ESCAPE and ASYN_TRACEIO_HEX bits

asynSetTraceIOMask(“ReadPort,0,6) 

# Turn on ASYN_TRACEIO_DRIVER and ASYN_TRACE_ERROR

asynSetTraceMask(“ReadPort”,0,9)

 

That will show you all of the Modbus I/O as well as the I/O from the asyn record.

 

I don’t really understand how you expected the asyn record to work.  You have not configured it to send valid Modbus commands, so how is it supposed to do port checking?  It seems that it will send data that is not expected by the device because it won’t contain a valid Modbus command.

 

Mark

 

 

 

 

From: [email protected] [mailto:[email protected]] On Behalf Of Tobin Weber
Sent: Friday, September 05, 2014 11:12 AM
To: [email protected]
Subject: Modbus TCP/IP "PSH" Command

 

Hello Colleagues,

We use a type of distributed I/O device that talks Modbus TCP/IP called an Acromag 952EN-4012. We have had re-occurring issues with these devices over the last few years. Most recently, we have experienced the devices losing communication with our EPICS IOC. We believe we have traced the source of this problem down to a Port checking procedure that we were doing. This procedure simply involves processing an asyn record that is linked to the IP Port created for modbus access.

The simplest example of an IOC that produces these errors is created with the following start up file:

drvAsynIPPortConfigure("ReadPort","192.168.0.78:502",0,0,1)

modbusInterposeConfig("ReadPort", 0, 1000,0)

dbLoadRecords("db/PortCheck.vdb")

With PortCheck.vdb being:

record(asyn, AcroRead) {
field(PORT, "ReadPort")
field(TMOD, "Write/Read")
field(SCAN, "1 second")
}

We usually read the .ERRS and .CNCT fields on AcroRead to check the port, but I left that out of the epics code b/c it doesn't appears to make a difference.

When AcroRead processes, we think the CPU (0.182) sends a "PSH" or Push Command to the Acromag Device (0.78) [See attached wirehshark file Acroamg_Port_Check_Tech_Talk]. After acknowledging this packet, the Acromag device responds with an exception. It appears to not understand the "PSH" command. I've spoken with Acromag Engineers and they said their devices will not know how to process this command.

We are fairly certain that this process, when combined with the reads and writes we do, will intermittently cause the Acromag device to stop responding completely to the EPICS IOC.

My question: Is the "PSH" command being sent expected behavior in this situation? What are the origins of this command?

Thanks very much for any help you can provide.

Toby

-- 
Tobin Weber
University of Washington
Fast Neutron Therapy
206-598-0485

-- 
Tobin Weber
University of Washington
Fast Neutron Therapy
206-598-0485

References:
Modbus TCP/IP "PSH" Command Tobin Weber
RE: Modbus TCP/IP "PSH" Command Mark Rivers

Navigate by Date:
Prev: Re: Modbus TCP/IP "PSH" Command Michael Davidsaver
Next: CS-Studio freezes with high value in XY graph Márcio Paduan Donadio
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: Modbus TCP/IP "PSH" Command Mark Rivers
Next: Re: Modbus TCP/IP "PSH" Command Michael Davidsaver
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 17 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·