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 Zenon Szalata
- References:
- Initial Value of a BO Record Zenon Szalata
- Navigate by Date:
- Prev:
Initial Value of a BO Record Zenon Szalata
- Next:
Looking for STRUCK SIS3302 device driver Jane Richards
- 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:
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
<2013>
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|