EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: asyn - interrupts
From: "Mark Rivers" <[email protected]>
To: "Heinrich du Toit" <[email protected]>
Cc: Tech-Talk EPICS <[email protected]>
Date: Thu, 23 Aug 2007 08:49:07 -0500
Heinrich,
 
I am not clear on the structure of your code.  You have your own asyn driver, right?  I think you have said that you are also using a record you developed?  If so, are you actually using devAsynInt32, or just using it as an example for device support you also wrote?
 
In any event, here is how interrpts work, with asynInt32 as an example:
 
- The driver gets new data and calls back the interrupt callback in device support.
- The device support interrupt callback caches the new data in its private structure.  It puts the data in pPvt->value, and sets the flag pPvt->gotValue to indicate that it has new data from the interrupt callback.  It then calls scanIoRequest to tell EPICS to scan the record, so that the new value will be copied to the RVAL field, and monitors and alarms will be posted, etc.
- EPICS processes the record.  This results in devAsynInt32::processAi being called.  Here is that code:
 
static long processAi(aiRecord *pr)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)pr->dpvt;
    int status;
    if(!pPvt->gotValue && !pr->pact) {
        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) {
            asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
                "%s devAsynInt32 queueRequest %s\n",
                pr->name,pPvt->pasynUser->errorMessage);
            recGblSetSevr(pr, READ_ALARM, INVALID_ALARM);
        }
    }
    if(pPvt->status==asynSuccess) {
        pr->rval = pPvt->value; pr->udf=0;
    }
    pPvt->gotValue = 0; pPvt->status = asynSuccess;
    return 0;
}
 
If you follow the logic here you will set that if pPvt->gotValue is non-zero then it does NOT call queueRequest to do a read() operation over the asynInt32 interface.  It simply copies the value from pPvt->value to pr->rval, and resets the gotValue flag.
 
If you are getting asynInt32 read() calls during this record processing as a result of scanIoRequest then I think you have done something wrong.
 
Mark
 

________________________________

From: [email protected] on behalf of Heinrich du Toit
Sent: Thu 8/23/2007 5:17 AM
Cc: Tech-Talk EPICS
Subject: RE: asyn - interrupts



Ok this makes sense... sortoff.
But In my driver I call the callback from a thread I created myself as
such:
 pInt32Interrupt->callback(pInt32Interrupt->userPvt,
pInt32Interrupt->pasynUser,
                                *(epicsInt32*)pPvt->ciPvt->data);
                               

Anyways.
For some or other reason the moment I start calling this interrupt the
the int32 device starts calling my int32read function??
Why is this?

I looked in devAsynInt32.c and inside interruptCallbackInput I see a
scanIoRequest at the end. My guess is it has something to do with this?
I am unable to find where scanIoRequest comes from?

Clearly I don't really understand how interrupts are working.
It is however clear that the int32reads come through the queue and not
directly from the interruptcallback.

Thanks

On Wed, 2007-08-22 at 08:15 -0500, Mark Rivers wrote:
> Heinrich,
> 
> > As the interrupt callback is already called from inside the ASYN thread (true?)
> > then the interrupt callback wouldn't need to go throught queueRequest
> > todo anything and can therefore use the ASYN interface functions
> > directly?
>
> No, that's not true, the interrupt callback is not done from the port thread (if one exists), it is done from another thread that the driver creates just for the callbacks.
> 
> > If callback A is called... then it should be ok if the record reads
> > directly into B and/or C
> 
> I don't think that should be done.  You should either implement 3 interrupts (if A, B, and C can change at different times or are going to different records), or implement asynInt32Array or asynFloat64Array callbacks if they all change at once and the values are all going to the same record.
> 
> Mark
> 
>
> ________________________________
>
> From: [email protected] on behalf of Heinrich du Toit
> Sent: Wed 8/22/2007 12:48 AM
> To: Tech-Talk EPICS
> Subject: RE: asyn - interrupts
>
>
>
> Hi
>
> Ok what you say makes sense but not completely.
> As the interrupt callback is already called from inside the ASYN thread
> (true?)
> then the interrupt callback wouldn't need to go throught queueRequest
> todo anything and can therefore use the ASYN interface functions
> directly?
>
> The reason I'm asking this is for the case of a custom record:
> Say the record is connected to ASYN ports A,B and C. Which could be
> different interfaces or maybe just other settings.
> Anyways.
> If callback A is called... then it should be ok if the record reads
> directly into B and/or C. Because it is already in the ASYN thread and
> therefore there shouldn't be any problems or need for queueRequests and
> so forth.
>
> Or should the record rather install 3 different interrupts?
> Wouldn't that in the end result in a lot of exstra db updates?
>
> I guess my next question will be about what happens when a record starts
> sending db_update floods :)
>
> -Heinrich
>
> On Tue, 2007-08-21 at 09:09 -0500, Mark Rivers wrote:
> > Hi Heinrich,
> >
> > You should use the data value that is passed in the callback.
>
> >  The interrupt callback should never call the read function in the asyn interface directly (it would need
>
> > to go through queueRequest to ensure that the read runs in the port thread in case the driver is asynchronous,
>
> > and to ensure correct locking even for synchronous drivers).  In principle it could call queueRequest, and then
>
> > call read() from the queueRequest callback, but there's really no need to do that.
> >
> > Mark
> >
> >
> > ________________________________
> >
> > From: [email protected] on behalf of Heinrich du Toit
> > Sent: Tue 8/21/2007 8:44 AM
> > To: Tech-Talk EPICS
> > Subject: asyn - interrupts
> >
> >
> >
> > Hi
> >
> > Just want to make sure about something and what is the general practice
> > that should be used.
> >
> > When an interrupt callback is called.
> > Then there is an parameter to send the "new" data in also.
> >
> > Ok so when the record support code's interrupt callback is called it
> > already receive the new data...
> > But it can obviously still call the read command for the asyn interface
> > and get the data that way.
> >
> > So do we assume that the data passed to the interrupt callback is
> > correct and that no further asyn calls is needed. Or can/should it still
> > call the read function to get data?
> >
> > I'm assuming it accepts the data in the callback and go ahead with that
> > as that would make sense to me.
> >
> > -Heinrich
> >
> >
> >
>
>
>





References:
asyn - interrupts Heinrich du Toit
RE: asyn - interrupts Mark Rivers
RE: asyn - interrupts Heinrich du Toit
RE: asyn - interrupts Mark Rivers
RE: asyn - interrupts Heinrich du Toit

Navigate by Date:
Prev: Re: Port of EPICS 3.14.9 to ETRAX CRIS architecture - Strange Data - Optimization issues Peter Zumbruch
Next: ethernet IP John Sinclair
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: asyn - interrupts Heinrich du Toit
Next: ArchiveDataTool converting from freq_directory Rowland, J (James)
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  <20072008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 10 Nov 2011 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·