Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017 
<== Date ==> <== Thread ==>

Subject: RE: Is it possible for an Asyn output record to be, also, an (I/O Intr - driven) input?
From: Mark Rivers <rivers@cars.uchicago.edu>
To: Ralph Lange <Ralph.Lange@gmx.de>, EPICS Tech-Talk <tech-talk@aps.anl.gov>
Cc: "'Eric Norum'" <wenorum@lbl.gov>
Date: Wed, 7 Jan 2015 23:17:18 +0000

Folks,

 

The implementation of this is now complete, including for devAsynOctet (stringout, waveform out) and devAsynXXXArray (numeric waveform output records).

The test application, testErrorsApp now tests the output record callbacks, including updating STAT and SEVR based on the the status the driver passes in pasynUser->auxStatus.  It has been enhanced to test stringout and waveform out records with callbacks.

This is from the release notes for upcoming R4-26:

devEpics

  • Added capability for output records to update their values with a callback from the driver. This is enabled by adding the following info tag to the output record:
    info(asyn:READBACK, "1")
    The output record value will update any time the driver does a callback with a new value. The output record alarm status and severity will also update to reflect the value passed by the driver in pasynUser->auxStatus. The driver callbacks use the same ring buffer mechanism that input records do. The default ring buffer size is 10 for all records except stringin, stringout, and waveform records, for which the default is 0.
  • Updated the test application testErrorsApp to demonstrate and test output record updates.
  • Added ring buffer support to devAsynOctet. The default ring buffer size is 0 for all records in devAsynOctet, i.e. stringin, stringout, waveform in and out. Non-zero values can be specified with the asyn:FIFO info tag.
  • Changed the info tag that is used to control the size of the ring buffer for driver callbacks. The tag has been changed from FIFO to asyn:FIFO, i.e. adding the asyn: namespace to prevent future conflicts with any other facility. NOTE:This change is not backwards compatible, any databases using the FIFO info tag will need to be changed to asyn:FIFO. It is not expected that this will affect many users, since the default ring buffer size is used in nearly all cases.

asynPortDriver

  • Bug fix: If setParamStatus() was called for an array or generic pointer parameter then callParamCallbacks() could return prematurely and not do the callbacks for all modified parameters.

 

The changes to devAsynOctet were quite substantial so any testing people can do before R4-26 is released would be welcome.  It can be found here:

 

https://svn.aps.anl.gov/epics/asyn/trunk/



Cheers,
Mark


From: Mark Rivers
Sent: Monday, December 22, 2014 7:03 AM
To: Ralph Lange; EPICS Tech-Talk
Subject: RE: Is it possible for an Asyn output record to be, also, an (I/O Intr - driven) input?

 

Hi Ralph,

Thanks for the comments.

The implementation of this is now complete for asynInt32, asynFloat64, and asynUInt32Digital. More work is needed for asynOctet and asynXXXArray.

The test application, testErrorsApp now tests the output record callbacks, including updating STAT and SEVR based on the the status the driver passes in pasynUser->auxStatus.

This is from the release notes for upcoming R4-26:

devEpics

  • Added capability for output records to update their values with a callback from the driver. This is enabled by adding the following info tag to the output record:
    info(asyn:READBACK, "1")
    The output record value will update any time the driver does a callback with a new value. The output record alarm status and severity will also update to reflect the value passed by the driver in pasynUser->auxStatus. The driver callbacks use the same ring buffer mechanism that input records do. The default ring buffer size is 10 for all records except waveform records, for which the default is 0.
    NOTE: Output record updates are not yet implemented for devAsynOctet or devAsynXXXArray, i.e. for stringout records or waveform output records. This will be added before R4-26 is released.
  • Updated the test application testErrorsApp to demonstrate and test output record updates.
  • Added ring buffer support to devAsynOctet. The default ring buffer size is 10 for stringin and stringout records, and 0 for waveform input and output records. 
    NOTE: This is not yet complete, but will be done before R4-26 is released.
  • Changed the info tag that is used to control the size of the ring buffer for driver callbacks. The tag has been changed from FIFO to asyn:FIFO, adding the asyn: namespace to prevent future conflicts with any other facility. NOTE:This change is not backwards compatible, any databases using the FIFO info tag will need to be changed to asyn:FIFO. It is not expected that this will affect many users, since the default ring buffer size is used in nearly all cases.

asynPortDriver

  • Bug fix: If setParamStatus() was called for an array or generic pointer parameter then callParamCallbacks() could return prematurely and not do the callbacks for all modified parameters.

 

Any testing people can do before R4-26 is released would be welcome.  It can be found here:

 



Cheers,
Mark

___
_____________________________________
From: Ralph Lange [lange.ralph@gmail.com] on behalf of Ralph Lange [Ralph.Lange@gmx.de]
Sent: Monday, December 22, 2014 5:54 AM
To: Mark Rivers; EPICS Tech-Talk
Subject: Re: Is it possible for an Asyn output record to be, also, an (I/O Intr - driven) input?

Hi Mark,

On 17/12/2014 01:09, Mark Rivers wrote:
> It is correct that noted that asyn does provide for I/O Intr scanning on output records, but that it has never been implemented. However, there are circumstances that might arise where that would be implemented. For example an output device that generates an interrupt when it is ready for more data, and the EPICS record should process to fetch the next piece of data.

Yup. Devices might generate interrupts for output for different reasons,
and the supported mechanisms should be configurable through the record,
with record instance granularity.

> However, what Peter and Ralph really want is for the output record to update its VAL field to reflect the state of the device when it has changed for whatever reason. I agree that we definitely should add this to asyn. The solution we have been using is a database kluge using the _RBV record (which is I/O Intr scanned) to process the output record, but using SDIS to prevent actually writing to the hardware if the output record is processing because the RBV_ record processed.

Yes. Correct. Thanks a lot for this response!

> We want this new behavior to be user-selectable option, so that existing IOCs don't change how they work. I can think of 2 ways to select it:
>
> 1) A new device support name for output records that should have this new behavior. For example for the asynInt32 interface the device support would be changed from "asynInt32" to "asynInt32Update" or "asynInt32Callback".
>
> 2) Use a record info tag like "Update" or "Callback" which causes the new behavior if it is set to 1. I like this solution better, since it is just one new "keyword" that would be used for all device support (asynInt32, asynFloat64, etc.)

Logically this is part of I/O configuration, so it would belong to the
OUT link. On the other hand, blowing up the INP/OUT link field syntax in
a compatible way will add a lot of complexity. As long as asyn does not
support run-time I/O link changes, the INFO field is as good as an
INP/OUT option, minus visibility.

> We need to be able to handle the following situations:
>
> I assume the following:
> - asyn driver is asynchronous, i.e. ASYN_CANBLOCK was 1.
> - asyn device support registers for callbacks from the driver when the value has changed. This is done now for input records with SCAN=I/O Intr.
>
> The first case is simple:
>
> 1) Output record is processed.
> 2) asyn device support queues a request to asynManager, sets PACT and returns
> 3) asynManager callback writes to the driver, and requests second phase of record processing.
> 4) Record processes again, calls device support. PACT is true, so it completes record processing and sets PACT=false.
>
> Some time later the driver gets a new value for that output:
> 1) Driver does a callback to device support passing the new value
> 2) asyn device support stores the new value, sets PACT, sets a flag saying there was a driver callback, and requests record processing
> 3) Record processes and calls device support. Device supports sees that both PACT and the flag are set, copies data to the record and sets PACT=false.

Correct.

> However, there is a more complicated situation where the driver callback happens in the middle of asynchronous record processing:
> 1) Output record is processed.
> 2) asyn device support queues a request to asynManager, sets PACT and returns
> 3) Driver does a callback to device support passing the new value
> 4) asyn device support stores the new value, sets PACT, sets a flag saying there was a driver callback, and requests record processing
> 5) asynManager callback writes to the driver, and requests second phase of record processing.
> 6) Record processes again, calls device support. PACT is true, so it completes record processing and sets PACT=false.
>
> However, after step 5 above second phase record processing has been requested twice, once because of the normal output record asynchronous processing, and once because of a driver callback that happened to occur when a new output transaction was in progress.
>
> How should this be handled?
>
> One option would seem to be that in step 4) the device support could notice that PACT is already true, so it knows that the record will process again anyway so it does not request processing.
>
> Another option would be that in step 5) it sees that the flag saying a driver callback has occurred is true, and so it does not request record processing.

I would keep it simple, and not handle this case different at all.
After all, the device saw the value change twice (else it wouldn't have
sent two updates), so the IOC should transparently get both updates.
Even more, the updates should be queued in the asyn driver together with
device-set timestamps (in such cases), so that the record processing
takes place once for every update the device sends, with the correct
pair of value/timestamp that was sent. Maybe the queuing should be
configurable, but it is mandatory when you are interested in e.g. all
state changes with correct timestamp
While suppressing one of the processing requests sounds reasonable at
first, in the end it leads to - say - an archiver connected to the
record to miss updates that it should see, making it hard to correlate
happenings (e.g. actions on local and remote GUI) to the archived events.

When you try to sort out all kinds of race conditions between a local
controller and the IOC both writing values to the device at the same
time, I would think the simplest approach is the only fully transparent
one: any write to the record should be sent to the device, any update
from the device should be written to the record.
We will never be able to solve the race between two masters sending: we
only know that one will eventually win. As long as the device sends any
change, and the record processes each of them, this is perfectly fine:
All transactions are transparent, and every player is well aware of
everything all the time.

> We also need to support the case where the asyn driver is synchronous (ASYN_CANBLOCK is 0). But I think this case is easy, it is just:
>
> 1) Output record is processed.
> 2) asyn device support calls pasynManager->queueRequest, does not set PACT, and the queue request callback is called immediately in the same thread
> 3) asynManager callback writes to the driver and returns. Record processing is complete.
>
> Some time later the driver gets a new value for that output:
> 1) Driver does a callback to device support passing the new value
> 2) asyn device support stores the new value, sets PACT, sets a flag saying there was a driver callback, and requests record processing
> 3) Record processes and calls device support. Device supports sees that both PACT and the flag are set, copies data to the record and sets PACT=false.

Yup. That should do it.

Again, thanks for jumping on this issue. Awesome!
~Ralph


Navigate by Date:
Prev: RE: Problem building asyn R4-25 on Mac OSX Yosemite Mark Rivers
Next: areadetector dbExpand.pl error: Braces must be closed in the same file they open in. Heinz Junkes
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017 
Navigate by Thread:
Prev: send css browser data to web l123173
Next: areadetector dbExpand.pl error: Braces must be closed in the same file they open in. Heinz Junkes
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017 
ANJ, 16 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·