Hi Mark,
Comments interspersed with your text.
On 07/11/13 14:26, Mark Rivers wrote:
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?
yes means that the parameter was handled in my readInt32 and it returned
either success or error. No means that the parameter was not handled in
readInt32. My readInt32 does not call asynPortDriver base class.
Should it?
- Does "setIntegerParams" mean that you called setIntegerParam for that parameter in your constructor, and set the value to 0?
Yes to this.
- 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?
I did not assign any value to *value. This then is the important step
that I have not thought to take. I will try to remember this.
Thanks Mark,
Zen
- 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:[email protected]]
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:[email protected]]
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 Mark Rivers
- 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
- RE: Initial Value of a BO Record Mark Rivers
- Navigate by Date:
- Prev:
RE: Initial Value of a BO Record Mark Rivers
- Next:
RE: Initial Value of a BO Record Mark Rivers
- 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: Initial Value of a BO Record Mark Rivers
- Next:
RE: Initial Value of a BO Record Mark Rivers
- 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
|