Experimental Physics and Industrial Control System
Hi Michael,
On 09/29/2017 05:15 PM, Dunning, Michael wrote:
> In the driver there's a thread that periodically does I/O to the
> device, and this thread makes calls to process_record_li() after it
> parses the response from the device. As far as I can tell, the
> process_record_li() routine is the only thing causing the record to
> process.
Okay, well the rest of the code you posted looks pretty standard.
I suspect the problem happens because the driver directly calls the
prset->process() routine instead of going through the IOC's dbProcess()
routine, which does all kinds of extra stuff.
I would recommend that you replace most of the process_record_li()
routine with the standard I/O Interrupt way of triggering record
processing, about which there are many examples and descriptions
available online, for example from slide #21 of
http://www.aps.anl.gov/epics/docs/APS2015/01-EPICS-Device-Support.pdf
HTH,
- Andrew
> The double-processing starts about 10 seconds after iocInit (I/O is
> done approximately once per second). I don't yet understand what is
> going on in the driver for the first 10 seconds, but during that time
> the record appears to process normally, i.e., no double-processing.
>
> This is the longin support from device support:
>
>
> struct {
> long number;
> DEVSUPFUN report;
> DEVSUPFUN init;
> DEVSUPFUN init_record;
> DEVSUPFUN get_ioint_info;
> DEVSUPFUN read_longin;
> }devLiEtherPSC={
> 5,
> NULL,
> NULL,
> init_li_record,
> NULL,
> read_li,
> };
> epicsExportAddress(dset, devLiEtherPSC);
>
>
> static long init_li_record( struct longinRecord *pli )
> {
> struct bitbusio *pb = (struct bitbusio*)&(pli->inp.value);
>
> return ( etherPSCdrvInitRecord( pb, (struct dbCommon*) pli ) );
>
> }
>
>
> static long read_li( struct longinRecord *pli )
> {
> PSCRECORD *PSCRecord;
>
> if ( ! (PSCRecord = pli->dpvt) ) return (2);
>
> if ( PSCRecord->nsta ) recGblSetSevr( pli, PSCRecord->nsta, INVALID_ALARM );
>
> pli->val = PSCRecord->val.li;
> pli->udf = FALSE;
> pli->pact = FALSE;
>
> return(0);
> }
>
>
> Now I see that compared to other non-asyn device support examples,
> this does look like kind of a mess. In addition to making it
> thread-safe and checking pli->pact, does anyone have any suggestions
> on if/how I should restructure this?
> I've attached the driver and device support source files if anyone
> would be willing to take a look.
>
> Thank you!
>
>
>
> Michael Dunning
> SLAC National Accelerator Laboratory
> 2575 Sand Hill Road
> Menlo Park, CA 94025
> (650) 926-5200
>
>
> On Wed, Sep 27, 2017 at 2:43 PM, Andrew Johnson <[email protected]> wrote:
>> Hi Michael,
>>
>> Assuming the process_record_li() routine is for triggering record
>> processing after some I/O has been received, why is it unconditionally
>> setting pli->pact? This looks to me like a cross between an asynchronous
>> I/O completion routine (i.e. part of an asynchronous read_longin()
>> device support method) and something for triggering record processing.
>>
>> It isn't thread-safe; it accesses two pli fields in the second if()
>> condition without holding the record's scan-lock, which has been illegal
>> in all Base versions for quite a long time. Is there an associated
>> longin device support that goes along with this?
>>
>> Is the I/O operation the only thing that causes this record to process?
>> The fact that you're getting SCAN/INVALID alarms suggests that something
>> else is going on as well, but I can't tell what from just the code you
>> showed us.
>>
>> This might have worked in 3.14.12, but since it isn't following the
>> rules so there is no guarantee what it will do in other versions.
>>
>> Sorry to be so blunt,
>>
>> - Andrew
>>
>>
>> On 09/27/2017 03:30 PM, Dunning, Michael wrote:
>>> After upgrading to Base 3.15.5, we are seeing what looks like
>>> double-processing of a certain custom record type. It is from our
>>> device support for Bira Ethernet Power Supply Controllers. The problem
>>> is with this record:
>>>
>>> record(longin, "ESB:BEND:2110:GainADCRaw")
>>> {
>>> field(DESC, "ADC Gain Raw Data")
>>> field(ASG, "Internal")
>>> field(DTYP, "EtherPSC")
>>> field(INP, "#L0 N0 P0 S50 @172.27.248.43")
>>> field(FLNK, "ESB:BEND:2110:GainADC.PROC")
>>> }
>>>
>>>
>>>
>>> When the IOC boots, the record has STAT: SCAN and SEVR: INVALID. If
>>> we camonitor this record, it seems to be processed twice:
>>>
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:15.648796 529
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:15.648796 529 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:16.549097 534
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:16.549097 534 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:17.449359 543
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:17.449359 543 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:18.349763 549
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:18.349763 549 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:19.250071 551
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:19.250071 551 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:20.150256 549
>>> ESB:BEND:2110:GainADCRaw 2017-09-10 20:12:20.150256 549 SCAN INVALID
>>>
>>>
>>>
>>> The double-processing explains the SCAN and INVALID states.
>>>
>>> Here is the record processing routine from device support:
>>>
>>> static void process_record_li( ETHERPSCNODE *node, int signal, long i )
>>> {
>>> PSCRECORD *PSCRecord;
>>> struct longinRecord *pli;
>>> struct rset *prset;
>>>
>>> PSCRecord = &node->record[signal];
>>> if ( ! (pli = (struct longinRecord*) PSCRecord->precord) ) return;
>>>
>>> if ( pli->val != i || pli->udf || PSCRecord->nsta )
>>> {
>>> PSCRecord->nsta = NO_ALARM;
>>> PSCRecord->val.li = i;
>>> prset = (struct rset *) pli->rset;
>>>
>>> dbScanLock( (struct dbCommon*) pli );
>>> pli->pact = TRUE;
>>> (*prset->process)( pli );
>>> dbScanUnlock( (struct dbCommon*) pli );
>>> }
>>> }
>>>
>>>
>>>
>>> I confirmed that this problem doesn't occur with Base 3.14.12.4. Does
>>> anyone have any idea why this record would be processed twice with
>>> Base-3.15?
>>>
>>>
>>>
>>>
>>>
>>> Michael Dunning
>>> SLAC National Accelerator Laboratory
>>> 2575 Sand Hill Road
>>> Menlo Park, CA 94025
>>> (650) 926-5200
>>>
>>
>> --
>> Arguing for surveillance because you have nothing to hide is no
>> different than making the claim, "I don't care about freedom of
>> speech because I have nothing to say." -- Edward Snowdon
--
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon
- References:
- Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
- Re: Record processing twice after upgrading to Base 3.15.5 Andrew Johnson
- Re: Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
- Navigate by Date:
- Prev:
Re: Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
- Next:
RE: Notification of Archiver Appliance interruptions will.rogers
- 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: Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
- Next:
Motor module problem Jörn Dreyer
- 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