This was my previous response to them on this topic, which was not copied to tech-talk.
If I have mis-stated anything I hope someone will correct me.
> In my waveform record 3 elements are there and any one of the value changed it will report to change value.
> So for example the set of value is 5,6,1 and then change to 5,6,0 it will report to value change and I/O Intr activate.
>
> The expected camonitor output should be as below
> $ camonitor PV
> PV 5 6 1
> PV 5 6 0
>
>
> But sometime it is
>
> $ camonitor PV
> PV 5 6 0
> PV 5 6 0
This is actually the expected behavior. Here is the order of operations:
1) Driver does callback to waveform record device support
2) Device support callback function:
2a) Locks record
2b) Copies array into record
2c) Unlocks record
2d) Calls scanIORequest to have a callback thread to process the record
3) Callback thread processes the record, sending out Channel Access monitors, etc.
What you are seeing is:
1) Your driver has done a callback, copying [5,6,1] into the record. It has requested a callback to process the record with scanIORequest
2) Before the scanIORequest thread has a chance to process the record in step 3 above, your driver does a second callback. This copies [5,6,0]
into the record and calls scanIORequest again.
3) The first scanIORequest processes the record. The data is now [5,6,0] so it posts a monitor with that.
4) The second scanIORequest processes the record, again posting [5,6,0]
This is normal behavior. EPICS does not guarantee that the record will post new monitors on every change if they happen too close together.
For non-array records the asyn device support has a "ring buffer" that stores a certain number of callback values from the driver. The default
ring buffer size is 10. In this case if several driver callbacks happen faster than the scanIORequest can complete the record will post monitors on all of them. But eventually if the callbacks happen too fast the ring buffer will overflow and values will
be lost.
For array records like you are using there is no ring buffer, because the size could be very large and it would involve copying a large amount
of data. So for arrays if there is a second callback before the first scanIORequest completes you only see the value from the second callback.
The bug that I fixed in asyn 4.21 was that the record was not locked while the data was being copied. This meant that the record could post a
monitor with data that was partly from callback 1 and partly from callback 2. This was a bad behavior, but that has been fixed. Now the record data is guaranteed to either be the complete array from callback 1 or callback 2, and not a mixture.
Mark
From: [email protected] [mailto:[email protected]]
On Behalf Of Vishnu Patel
Sent: Friday, February 21, 2014 12:35 PM
To: techtalk
Subject: Waveform record I/O interrupt. asyn
Hello,
I am facing problem in I/O Interrupt for waveform record in the asyn. If the value of waveform record change very fast then some of the samples missing or same sample repeat twice even if before p_interruptInt32Array->callback ()
function the value is scanned properly by driver. But i think the read value is pushed to the callback but it is not handle that much fast in the callback.
I checked the code for interruptCallbackInput in devAsynXXXArray.h.
In devAsynXXXArray.c dbScanUnlock has been used before scanIoRequest(). Can it create problem for repeating same value?
My assumption is as dbScanUnlock and before scanIoRequest() execute, value change and second time triggers interrupt. This result same value for both interrupts.
I checked interrupt callback code in devAsynInt32.c where epicsMutexUnlock has been used after scanIoRequest().
Get your own
FREE website,
FREE domain &
FREE mobile app with Company email.
|
Know
More >
|