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  <20132014  2015  2016  2017  2018  2019  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019 
<== Date ==> <== Thread ==>

Subject: RE: Initial Value of a BO Record
From: Mark Rivers <rivers@cars.uchicago.edu>
To: "'Zenon Szalata'" <zms@slac.stanford.edu>
Cc: tech-talk <tech-talk@aps.anl.gov>
Date: Thu, 11 Jul 2013 21:26:24 +0000
Hi Zen,

Your table came through hard to read because it wrapped lines.  I've reformatted it here.

   capture in readInt32   readInt32-returns  setIntegerParams VAL
1  yes                      asynSuccess            yes         1
2  yes                      asynError              yes         0
3  no                       asynError              yes         0
4  no                       asynError               no         0
5  yes                      asynSuccess             no         1
6  yes                      asynError               no         0

Can you explain a few things about these tests:

- What does "capture in readInt32" mean.  Does "yes" mean that the readInt32 method in your class handled that parameter, and "no" mean that you called the base class for that parameter?

- Does "setIntegerParams" mean that you called setIntegerParam for that parameter in your constructor, and set the value to 0?

- To explain test 5 your readInt32 function would need to be returning a non-zero value for the *value argument when it is initially called.  Is this true?  The readInt32 method has the following prototype:
    virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
What value are you returning in *value?

- For test 1 it does not matter that you called setIntegerParam with 0.  What matters is what value your readInt32 routine returns for the *value argument.  The parameter library value is irrelevant.

Mark



-----Original Message-----
From: Zenon Szalata [mailto:zms@slac.stanford.edu] 
Sent: Thursday, July 11, 2013 3:36 PM
To: Mark Rivers
Cc: tech-talk
Subject: Re: Initial Value of a BO Record

Thanks Mark,
I redid the tests a bit more carefully and this is what I see:

   capture in readInt32   readInt32-returns  setIntegerParams VAL
1  yes                      asynSuccess            yes         1
2  yes                      asynError              yes         0
3  no                       asynError              yes         0
4  no                       asynError               no         0
5  yes                      asynSuccess             no         1
6  yes                      asynError               no         0

I had a bug which was affecting test 3 and 4 which before the bug was 
fixed, resulted in VAL = 1.
I think that these results are in line with what you said in your last 
email, perhaps with the exception of test 1, where I would expect to get 
VAL = 0 since I was setting the record to value 0 using 
setIntegerParam.  It is possible that I don't really understand how this 
is supposed to work.
Thanks again,
Zen

On 07/11/13 09:44, Mark Rivers wrote:
> Hi Zen,
>
> The concept of the "bumpless reboot" is as follows.
>
> - The init_record function in the asyn device support for the asynInt32 interface attempts to read the value from the driver.  This happens during iocInit.
> - If the driver returns asynSuccess then the value returned by the driver is placed into the RVAL field in the bo record, and it tells the record to convert the RVAL value to the VAL field.  This will make the record agree with the hardware after iocInit.
> - If the driver does not return asynSuccess then the device support does not change the RVAL field of the bo record, and returns 2 (do not convert).
> - If you are using asynPortDriver and you are implementing the readInt32 method then you have control of whether to return asynSuccess or asynError when called during iocInit.  You may need to have a flag indicating whether the value has ever been written by a call to writeInt32, or look at the value of the EPICS global "interruptAccept", etc.
> - If you are using asynPortDriver and you are NOT implementing the readInt32 method then the asynPortDriver::readInt32 base class implementation will be used.  It returns asynSuccess if a value has ever been written to the parameter library with setIntegerParam() for that parameter and address.  If setIntegerParam has not yet been called then it returns asynError.
>
> This is the asyn/devEpics/devAsynInt32.c::initBo function, which is the init_record function for bo records in the asynInt32 device support:
>
> static long initBo(boRecord *pr)
> {
>      devInt32Pvt *pPvt;
>      asynStatus status;
>      epicsInt32 value;
>
>      status = initCommon((dbCommon *)pr,&pr->out,
>          processCallbackOutput,interruptCallbackOutput, interruptCallbackEnumBo,
>          2, (char*)&pr->znam, NULL, &pr->zsv);
>      if (status != asynSuccess) return 0;
>      pPvt = pr->dpvt;
>      /* Read the current value from the device */
>      status = pasynInt32SyncIO->read(pPvt->pasynUserSync,
>                        &value, pPvt->pasynUser->timeout);
>      if (status == asynSuccess) {
>          pr->rval = value;
>          return 0;
>      }
>      return 2;
> }
>
> So it called pasynInt32SyncIO-read to read the value from the driver.  If the read is successful it set rval and returns 0.  If the read fails it returns 2, and does not modify rval.
>
> This is the pasynInt32SyncIO->read function:
>
> static asynStatus readOp(asynUser *pasynUser, epicsInt32 *pvalue, double timeout)
> {
>      ioPvt      *pioPvt = (ioPvt *)pasynUser->userPvt;
>      asynStatus status, unlockStatus;
>
>      pasynUser->timeout = timeout;
>      status = pasynManager->queueLockPort(pasynUser);
>      if(status!=asynSuccess) {
>          return status;
>      }
>      status = pioPvt->pasynInt32->read(pioPvt->int32Pvt, pasynUser, pvalue);
>      if (status==asynSuccess) {
>          asynPrint(pasynUser, ASYN_TRACEIO_DEVICE,
>                    "asynInt32SyncIO read: %d\n", *pvalue);
>      }
>      unlockStatus = pasynManager->queueUnlockPort(pasynUser);
>      if (unlockStatus != asynSuccess) {
>          return unlockStatus;
>      }
>      return(status);
> }
>
> So it returns asynSuccess if and only if your driver's pasynInt32->read function returns asynSuccess.
>
> If your readInt32 routine is returning asynError then the bo record should not be being set to 1.
>
> Are you using autosave?  Is it possible that autosave is restoring 1 from an autosave file?
>
> I cannot explain what you are observing, and I cannot reproduce it.
>
> I just tested with an areaDetector driver.  I deleted all of the autosave files.  I rebooted the IOC and all bo records had the values defined in the database file.  Some were 1, some were 0.  I did not find any discrepancies between the database file and the run time value.  None of these parameters were having their values set with setIntegerParam() in the constructors.
>
> Mark
>
>
> -----Original Message-----
> From: Zenon Szalata [mailto:zms@slac.stanford.edu]
> Sent: Thursday, July 11, 2013 11:08 AM
> To: Mark Rivers; tech-talk
> Subject: Initial Value of a BO Record
>
> Hi Mark,
> I have a handful of bo records, which are intended to initiate some
> action in a device driver sub-classed from asynPortDriver.  I want these
> records to have VAL 0 when the IOC starts.  A typical record looks like
> this:
>
> record( bo,"$(P):BO:$(MOD):CH$(N):STOP"){
>     field( DESC, "Stop:")
>     field( DTYP, "asynInt32")
>     field( OUT,  "@asyn($(PORT) $(ADDR) 1)BO_STOP")
>     field( HIGH, "0.1")
>     field( ZNAM, "Not")
>     field( ONAM, "Yes")
>     field( VAL,  "0")
> }
>
> When the IOC starts, these records have VAL=1, which is undesirable.
> For testing I have created a soft channel bo record and it comes up with
> the state consistent with what is in the VAL field.  I suspect the
> observed behavior has something to do with the "bumpless reboot" that
> you mentioned in your last email to me.  I must confess that I don't
> understand the concept and more importantly how to avoid it, assuming
> that is what is getting me.
> I tried a few things in the device driver.  I have captured the call in
> readInt32 routine and set the return status to either asynSuccess or
> asynError, which did not change the behavior.  I have also added in the
> constructor setIntegerParam( xxxx,0) for these records.  This also did
> not help.  Could you put me on the right track with this?
> Thanks in advance,
> Zen
>



Replies:
Re: Initial Value of a BO Record Zenon Szalata
References:
Initial Value of a BO Record Zenon Szalata
RE: Initial Value of a BO Record Mark Rivers
Re: Initial Value of a BO Record Zenon Szalata

Navigate by Date:
Prev: Newport CONEX-LDS Electronic Autocollimator Kevin Peterson
Next: Re: Initial Value of a BO Record Zenon Szalata
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019 
Navigate by Thread:
Prev: Re: Initial Value of a BO Record Zenon Szalata
Next: Re: Initial Value of a BO Record Zenon Szalata
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·