Hi Zen,
> record( longout, "$(P):LO:TEST"){
> field( DTYP, "asynInt32")
> field( OUT, "@asyn($(PORT),0,1)LO_TEST")
> field( EGU, "ms")
> info(asyn:READBACK,"1")
>}
> In the constructor, after createParams calls, I do this:
> setIntegerParam( _loTest,tv);
> callParamCallbacks( 0);
> this results in VAL has the expected value, UDF 0, STAT UDF, SEVR INVALID.
Something is wrong. My results from my previous message indicate that I get STAT=SEVR=NO_ALARM under those conditions.
I just tried another test on the standard testAsynPortDriver application that comes with asyn.
I created the following single-record database, test1.db:
record(longout, "$(P)$(R)VertGainSelect")
{
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))SCOPE_VERT_GAIN_SELECT")
info(asyn:READBACK, "1")
}
I created a new file asyn/iocBoot/ioctestAsynPortDriver/st.cmd.1 that differs from the original st.cmd as follows:
-dbLoadRecords("../../db/testAsynPortDriver.db","P=testAPD:,R=scope1:,PORT=testAPD,ADDR=0,TIMEOUT=1,NPOINTS=1000")
-dbLoadRecords("../../db/asynRecord.db","P=testAPD:,R=asyn1,PORT=testAPD,ADDR=0,OMAX=80,IMAX=80")
+dbLoadRecords("./test1.db","P=testAPD:,R=scope1:,PORT=testAPD,ADDR=0,TIMEOUT=1,NPOINTS=1000")
So it simply loads test1.db rather than the original database files.
When I boot this is the output of dbl:
epics> dbl
testAPD:scope1:VertGainSelect
This is the output of dbpr on that record:
epics> dbpr testAPD:scope1:VertGainSelect 10
ACKS: NO_ALARM ACKT: YES ADEL: 0 ALST: 10
ASG: ASP: (nil) BKPT: 00 DESC:
DISA: 0 DISP: 0 DISS: NO_ALARM DISV: 1
DOL:CONSTANT DPVT: 0x180a2b0 DRVH: 0 DRVL: 0
DSET: 0x7f4f6c350900 DTYP: asynInt32 EGU:
EVNT: 0 FLNK:CONSTANT 0 HHSV: NO_ALARM HIGH: 0
HIHI: 0 HOPR: 0 HSV: NO_ALARM HYST: 0
IVOA: Continue normally IVOV: 0 LALM: 10
LCNT: 0 LLSV: NO_ALARM LOLO: 0 LOPR: 0
LOW: 0 LSET: 0x1817010 LSV: NO_ALARM MDEL: 0
MLIS: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
MLOK: 80 a2 80 01 00 00 00 00 MLST: 10
NAME: testAPD:scope1:VertGainSelect NSEV: NO_ALARM NSTA: NO_ALARM
OMSL: supervisory OUT:INST_IO @asyn(testAPD,0,1)SCOPE_VERT_GAIN_SELECT
PACT: 0 PHAS: 0 PINI: NO PPN: (nil)
PPNR: (nil) PRIO: LOW PROC: 0 PUTF: 0
RDES: 0x17c1a60 RPRO: 0 RSET: 0x7f4f6c0da180
SCAN: Passive SDIS:CONSTANT SEVR: NO_ALARM SIML:CONSTANT
SIMM: NO SIMS: NO_ALARM SIOL:CONSTANT SPVT: (nil)
STAT: NO_ALARM TIME: 2015-03-02 15:20:01.995971112 TPRO: 0
TSE: 0 TSEL:CONSTANT UDF: 0 VAL: 10
Note that it has STAT=SEVR=NO_ALARM. This is different from what you got. Can you please repeat the test I did above with testAsynPortDriver on your system?
> But I still am confused. I see that the longout record is not "really"
> processed; it did not write its VAL to the OUT link.
The record really does "process" but you are correct, it does not write its value to the OUT link. The asyn device support gets the callback from your driver and requests the record to process with scanOnce(). When the device support process() function is called it knows that this processing is due to the callback, so it does not write the value to your driver, it just sets UDF, VAL, and possibly STAT and SEVR. Here is the code:
static long processLo(longoutRecord *pr)
{
devInt32Pvt *pPvt = (devInt32Pvt *)pr->dpvt;
int status;
if (getCallbackValue(pPvt)) {
/* We got a callback from the driver */
if (pPvt->result.status == asynSuccess) {
pr->val = pPvt->result.value;
pr->udf = 0;
}
} else if(pr->pact == 0) {
pPvt->result.value = pr->val;
if(pPvt->canBlock) pr->pact = 1;
status = pasynManager->queueRequest(pPvt->pasynUser, 0, 0);
if((status==asynSuccess) && pPvt->canBlock) return 0;
if(pPvt->canBlock) pr->pact = 0;
if(status != asynSuccess) {
pPvt->result.status = status;
asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
"%s devAsynInt32 queueRequest %s\n",
pr->name,pPvt->pasynUser->errorMessage);
}
}
if(pPvt->result.status != asynSuccess) {
pasynEpicsUtils->asynStatusToEpicsAlarm(pPvt->result.status, WRITE_ALARM, &pPvt->alarmStat,
INVALID_ALARM, &pPvt->alarmSevr);
(void)recGblSetSevr(pr, pPvt->alarmStat, pPvt->alarmSevr);
}
pPvt->result.status = asynSuccess;
return 0;
}
If the record is processing because your driver did a callback, then getCallbackValue(pPvt) will return TRUE. In that case if pPvt->result.status is asynSuccess then it sets UDF, VAL. Later on if pPvt->result.status is not asynSuccess it will set the alarm fields in the record.
pPvt->result.status is set in the callback function to the value in pasynUser->auxStatus. So one possible explanation for what you are setting is that your driver is setting pasynUser->auxStatus to a non-zero value in the callback. But that does not really make sense, because then UDF would not be set to 0 and VAL would not be set to the expected value.
> Anyway, I just need some confirmation that what I am seeing is correct.
What you are seeing with your record originally having STAT=UDF, SEVR=INVALID is not correct. That is not what I expect, nor what I observe in using the test programs that come with asyn. I think you should try to track this down in case it is a bug either in your driver or in asyn.
Mark
-----Original Message-----
From: Zenon Szalata [mailto:[email protected]]
Sent: Monday, March 02, 2015 2:56 PM
To: Mark Rivers; [email protected]
Subject: Re: asyn R4.26
Hi Mark,
I wrote a tiny test IOC which is based on asynPortDriver class. I have
created a record:
record( longout, "$(P):LO:TEST"){
field( DTYP, "asynInt32")
field( OUT, "@asyn($(PORT),0,1)LO_TEST")
field( EGU, "ms")
info(asyn:READBACK,"1")
}
In the constructor, after createParams calls, I do this:
setIntegerParam( _loTest,tv);
callParamCallbacks( 0);
this results in VAL has the expected value, UDF 0, STAT UDF, SEVR INVALID.
I have also implemented a bo record which allows me to execute the two
statements, setIntegerParam( _loTest,tv) and callParamCallbacks() with a
caput command. When I do that, then the STAT and SEVR has NO_ALARM
values. When I set TPRO=1 in the longout record, then when I process my
bo record, I get:
scanOnce: Process CHA:SM:LO:TEST.
So all of that seems to work as you explained.
But I still am confused. I see that the longout record is not "really"
processed; it did not write its VAL to the OUT link. I expected (and
perhaps feared) that if the longout record gets processed as a result of
giving it a new value from the device driver via this newly implemented
mechanism, it would also write out the value to its OUT link. Since
that is not happening, at least in my program, then the record is
processed in some special way.
Anyway, I just need some confirmation that what I am seeing is correct.
Thanks Mark,
Zen
On 02/28/15 06:28, Mark Rivers wrote:
> Hi Zen,
>
> There are two separate ways to get the value from the driver into an output record.
>
> 1) The first way is to have your driver write the value to the parameter library at some point before iocInit. Standard asyn device support always attempts to read the value from the driver in the init_record function at iocInit. If the read returns asynSuccess then the value read is put into the VAL field and UDF is set to 0. The record does not process at iocInit unless the PINI field is YES. This mechanism has existed in asyn since the beginning.
>
> 2) The second way is the new feature added in asyn R4-26. It requires that you set the info tag asyn:READBACK to 1. In this case whenever your driver does a callback to device support the output record will process and get the new value. This was not really intended to initialize the value at iocInit, but rather to update the record later if something other than processing that record cause the value in the driver to change.
>
> I just did a test to verify that I believe things are working as they should. asyn comes with a test application called testErrorsApp. That application sets the values of some parameters in the parameter library in the constructor, and updates them periodically in a driver thread.
>
> I just created a new simple database called testErrors1.db for that application. Here it is:
>
> corvette:~/devel/asyn/db>more testErrors1.db
> record(longout, "$(P)LongoutInt32")
> {
> field(DTYP, "asynInt32")
> field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
> field(VAL, "0")
> }
>
> record(longout, "$(P)LongoutInt32_PINI")
> {
> field(PINI, "1")
> field(DTYP, "asynInt32")
> field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
> field(VAL, "0")
> }
>
> record(longout, "$(P)LongoutInt32_RB")
> {
> field(DTYP, "asynInt32")
> field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
> field(VAL, "0")
> info(asyn:READBACK,"1")
> }
>
> record(longout, "$(P)LongoutInt32_RB_PINI")
> {
> field(PINI, "1")
> field(DTYP, "asynInt32")
> field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_VALUE")
> field(VAL, "0")
> info(asyn:READBACK,"1")
> }
>
> It has 4 longout records.
>
> PINI asyn:READBACK present
> LongoutInt32 No No
>
> LongoutInt32_PINI Yes No
>
> LongoutInt32_RB No Yes
>
> LongoutInt32_RB_PINI Yes Yes
>
> I then loaded this database into an IOC running the testErrorsApp application. This is the output of dbpr for each of those records with level 10 of output.
>
> epics> dbpr testErrors:LongoutInt32 10
> ACKS: NO_ALARM ACKT: YES ADEL: 0 ALST: 1
> ASG: ASP: (nil) BKPT: 00 DESC:
> DISA: 0 DISP: 0 DISS: NO_ALARM DISV: 1
> DOL:CONSTANT DPVT: 0x2578c70 DRVH: 0 DRVL: 0
> DSET: 0x7f61cceaa900 DTYP: asynInt32 EGU:
> EVNT: 0 FLNK:CONSTANT 0 HHSV: NO_ALARM HIGH: 0
> HIHI: 0 HOPR: 0 HSV: NO_ALARM HYST: 0
> IVOA: Continue normally IVOV: 0 LALM: 1
> LCNT: 0 LLSV: NO_ALARM LOLO: 0 LOPR: 0
> LOW: 0 LSET: 0x25887f0 LSV: NO_ALARM MDEL: 0
> MLIS: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> MLOK: f0 8a 57 02 00 00 00 00 MLST: 1
> NAME: testErrors:LongoutInt32 NSEV: NO_ALARM NSTA: NO_ALARM
> OMSL: supervisory OUT:INST_IO @asyn(PORT1,0,1)INT32_VALUE PACT: 0
> PHAS: 0 PINI: NO PPN: (nil) PPNR: (nil)
> PRIO: LOW PROC: 0 PUTF: 0 RDES: 0x2532a30
> RPRO: 0 RSET: 0x7f61ccc34180 SCAN: Passive
> SDIS:CONSTANT SEVR: INVALID SIML:CONSTANT SIMM: NO
> SIMS: NO_ALARM SIOL:CONSTANT SPVT: (nil) STAT: UDF
> TIME: <undefined> TPRO: 0 TSE: 0 TSEL:CONSTANT
> UDF: 0 VAL: 1
>
> epics> dbpr testErrors:LongoutInt32_PINI 10
> ACKS: NO_ALARM ACKT: YES ADEL: 0 ALST: 1
> ASG: ASP: (nil) BKPT: 00 DESC:
> DISA: 0 DISP: 0 DISS: NO_ALARM DISV: 1
> DOL:CONSTANT DPVT: 0x2586350 DRVH: 0 DRVL: 0
> DSET: 0x7f61cceaa900 DTYP: asynInt32 EGU:
> EVNT: 0 FLNK:CONSTANT 0 HHSV: NO_ALARM HIGH: 0
> HIHI: 0 HOPR: 0 HSV: NO_ALARM HYST: 0
> IVOA: Continue normally IVOV: 0 LALM: 1
> LCNT: 0 LLSV: NO_ALARM LOLO: 0 LOPR: 0
> LOW: 0 LSET: 0x2588810 LSV: NO_ALARM MDEL: 0
> MLIS: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> MLOK: 60 8b 57 02 00 00 00 00 MLST: 1
> NAME: testErrors:LongoutInt32_PINI NSEV: NO_ALARM NSTA: NO_ALARM
> OMSL: supervisory OUT:INST_IO @asyn(PORT1,0,1)INT32_VALUE PACT: 0
> PHAS: 0 PINI: YES PPN: (nil) PPNR: (nil)
> PRIO: LOW PROC: 0 PUTF: 0 RDES: 0x2532a30
> RPRO: 0 RSET: 0x7f61ccc34180 SCAN: Passive
> SDIS:CONSTANT SEVR: NO_ALARM SIML:CONSTANT SIMM: NO
> SIMS: NO_ALARM SIOL:CONSTANT SPVT: (nil) STAT: NO_ALARM
> TIME: 2015-02-28 08:04:44.076227816 TPRO: 0 TSE: 0
> TSEL:CONSTANT UDF: 0 VAL: 1
>
> epics> dbpr testErrors:LongoutInt32_RB 10
> ACKS: NO_ALARM ACKT: YES ADEL: 0 ALST: 1
> ASG: ASP: (nil) BKPT: 00 DESC:
> DISA: 0 DISP: 0 DISS: NO_ALARM DISV: 1
> DOL:CONSTANT DPVT: 0x2586c80 DRVH: 0 DRVL: 0
> DSET: 0x7f61cceaa900 DTYP: asynInt32 EGU:
> EVNT: 0 FLNK:CONSTANT 0 HHSV: NO_ALARM HIGH: 0
> HIHI: 0 HOPR: 0 HSV: NO_ALARM HYST: 0
> IVOA: Continue normally IVOV: 0 LALM: 1
> LCNT: 0 LLSV: NO_ALARM LOLO: 0 LOPR: 0
> LOW: 0 LSET: 0x2588830 LSV: NO_ALARM MDEL: 0
> MLIS: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> MLOK: d0 8b 57 02 00 00 00 00 MLST: 1
> NAME: testErrors:LongoutInt32_RB NSEV: NO_ALARM NSTA: NO_ALARM
> OMSL: supervisory OUT:INST_IO @asyn(PORT1,0,1)INT32_VALUE PACT: 0
> PHAS: 0 PINI: NO PPN: (nil) PPNR: (nil)
> PRIO: LOW PROC: 0 PUTF: 0 RDES: 0x2532a30
> RPRO: 0 RSET: 0x7f61ccc34180 SCAN: Passive
> SDIS:CONSTANT SEVR: NO_ALARM SIML:CONSTANT SIMM: NO
> SIMS: NO_ALARM SIOL:CONSTANT SPVT: (nil) STAT: NO_ALARM
> TIME: 2015-02-28 08:04:44.173729522 TPRO: 0 TSE: 0
> TSEL:CONSTANT UDF: 0 VAL: 1
>
> epics> dbpr testErrors:LongoutInt32_RB_PINI 10
> ACKS: NO_ALARM ACKT: YES ADEL: 0 ALST: 1
> ASG: ASP: (nil) BKPT: 00 DESC:
> DISA: 0 DISP: 0 DISS: NO_ALARM DISV: 1
> DOL:CONSTANT DPVT: 0x25879b0 DRVH: 0 DRVL: 0
> DSET: 0x7f61cceaa900 DTYP: asynInt32 EGU:
> EVNT: 0 FLNK:CONSTANT 0 HHSV: NO_ALARM HIGH: 0
> HIHI: 0 HOPR: 0 HSV: NO_ALARM HYST: 0
> IVOA: Continue normally IVOV: 0 LALM: 1
> LCNT: 0 LLSV: NO_ALARM LOLO: 0 LOPR: 0
> LOW: 0 LSET: 0x2588850 LSV: NO_ALARM MDEL: 0
> MLIS: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> MLOK: 40 8c 57 02 00 00 00 00 MLST: 1
> NAME: testErrors:LongoutInt32_RB_PINI NSEV: NO_ALARM NSTA: NO_ALARM
> OMSL: supervisory OUT:INST_IO @asyn(PORT1,0,1)INT32_VALUE PACT: 0
> PHAS: 0 PINI: YES PPN: (nil) PPNR: (nil)
> PRIO: LOW PROC: 0 PUTF: 0 RDES: 0x2532a30
> RPRO: 0 RSET: 0x7f61ccc34180 SCAN: Passive
> SDIS:CONSTANT SEVR: NO_ALARM SIML:CONSTANT SIMM: NO
> SIMS: NO_ALARM SIOL:CONSTANT SPVT: (nil) STAT: NO_ALARM
> TIME: 2015-02-28 08:04:44.173736304 TPRO: 0 TSE: 0
> TSEL:CONSTANT UDF: 0 VAL: 1
>
>
> Here is a summary of the UDR, STAT and SEVR fields of each of those records.
>
> UDF STAT SEVR
> testErrors:LongoutInt32 0 UDF INVALID
> testErrors:LongoutInt32_PINI 0 NO_ALARM NO_ALARM
> testErrors:LongoutInt32_RB 0 NO_ALARM NO_ALARM
> testErrors:LongoutInt32_RB_PINI 0 NO_ALARM NO_ALARM
>
> This is exactly what I expect.
>
> All records have UDF=0 because the value was successfully read from the driver at in init_record in the device support.
>
> For testErrors:LongoutInt32 the record has never processed because PINI=NO and the asyn:READBACK info tag is not present. It thus has STAT=UDF and SEVR=INVALID. All of the other records have processed, either because they have PINI=YES or because they have the asyn:READBACK tag. Because they have processed STAT and SEVR are both NO_ALARM.
>
> I hope this clarifies things.
>
> Mark
>
>
>
> ________________________________________
> From: Zenon Szalata [[email protected]]
> Sent: Friday, February 27, 2015 11:09 PM
> To: Mark Rivers; [email protected]
> Subject: Re: asyn R4.26
>
> Hi Mark,
> I am using asynPortDriver class. The records are initialized after IOC
> init and the record in question looks like this:
>
> epics> dbpr CHA:LO:2531-1-2:CWORD,3
> ACKS: NO_ALARM ACKT: YES ADEL: 0 ALST: 0
> ASG: BKPT: 00 DESC: DISA: 0
> DISP: 0 DISS: NO_ALARM DISV: 1 DOL:CONSTANT
> DRVH: 0 DRVL: 0 DTYP: asynInt32 EGU:
> EVNT: 0 FLNK:CONSTANT 0 HHSV: NO_ALARM HIGH: 0
> HIHI: 0 HOPR: 0 HSV: NO_ALARM HYST: 0
> IVOA: Continue normally IVOV: 0 LALM: 0
> LCNT: 0 LLSV: NO_ALARM LOLO: 0 LOPR: 0
> LOW: 0 LSV: NO_ALARM MDEL: 0 MLST: 0
> NAME: CHA:LO:2531-1-2:CWORD NSEV: NO_ALARM NSTA: NO_ALARM
> OMSL: supervisory OUT:INST_IO @asyn(2531-1,0,1)LO_CWORD PACT: 0
> PHAS: 0 PINI: NO PRIO: LOW PROC: 0
> PUTF: 0 RPRO: 0 SCAN: Passive SDIS:CONSTANT
> SEVR: INVALID SIML:CONSTANT SIMM: NO SIMS: NO_ALARM
> SIOL:CONSTANT STAT: UDF TIME: 2015-02-27 15:41:07.126179705
> TPRO: 0 TSE: 0 TSEL:CONSTANT UDF: 0
> VAL: 0
> epics>
>
> I verified that processing the record, it goes into a healthy state. I
> suppose there is no harm to process the record, since it will write back
> to the hardware which was just read in. The reason I noticed this is
> that the EDM byte monitor widget displays the data as uninitialized...
> The question still remains, since the record should have been processed
> when the value was written to it and yet the record looks like it was
> not processed, so what happened?
> Thanks Mark,
> Zen
>
> On 02/27/15 16:54, Mark Rivers wrote:
>> I think STAT and SEVR only get set when the record processes.
>>
>> When are you doing the callback to device support, before or after iocInit?
>>
>> If you do the callback after iocInit then the callback will cause the record to process, because it calls scanOnce(). However, if you call it before iocInit it will not call scanOnce() because that will crash the IOC.
>>
>> Are you using the asynPortDriver C++ base class? If so that takes care of the problem for you because it has a thread that waits for interruptAccept to be true, and then does all of the callbacks to device support.
>>
>> Mark
>>
>>
>> -----Original Message-----
>> From: Zenon Szalata [mailto:[email protected]]
>> Sent: Friday, February 27, 2015 5:59 PM
>> To: Mark Rivers; [email protected]
>> Subject: asyn R4.26
>>
>> Hi Mark,
>> I am beginning to use asyn R4.26, where the new feature that you have
>> added to allow initialization of output records, is of interest.
>> It works well, except I have noticed one thing.
>> In my case I am initializing a longout record from the device driver.
>> It gets the value correctly, UDF is set to 0 but STAT has UDF and SEVR
>> is INVALID. Do I need to do something else in addition to just push a
>> new value to the record? I don't want to process the record, which most
>> likely would put the record in a good state.
>> Sorry for bugging you and thanks,
>> Zen
- Replies:
- RE: asyn R4.26 Mark Rivers
- References:
- asyn R4.26 Zenon Szalata
- RE: asyn R4.26 Mark Rivers
- Re: asyn R4.26 Zenon Szalata
- RE: asyn R4.26 Mark Rivers
- Re: asyn R4.26 Zenon Szalata
- Navigate by Date:
- Prev:
Re: asyn R4.26 Zenon Szalata
- Next:
"No conversion between src & dest" warning with pcaspy Jameson Graef Rollins
- 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 R4.26 Zenon Szalata
- Next:
RE: asyn R4.26 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
|