2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 <2019> 2020 2021 2022 2023 2024 | Index | 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 <2019> 2020 2021 2022 2023 2024 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: Strange behavior of async calcout with CPP input link |
From: | "Johnson, Andrew N. via Core-talk" <[email protected]> |
To: | "[email protected]" <[email protected]> |
Date: | Mon, 26 Aug 2019 21:13:39 +0000 |
Hi Ben, On 8/26/19 12:42 PM, Michael Davidsaver via Core-talk wrote: I concur with Michael. I think your use of a CPP link to trigger an asynchronous record is the source of the problem, and I believe that you would still see the problem even when running it on Base-7.0.3.This might be https://bugs.launchpad.net/epics-base/+bug/1745039 Any chance you can try to reproduce with Base 7.0.3?(2) if a record (here: DEV1:trgOn) is active (PACT=1) when an event arrives, it gets processed again, after completing.This was only true when a record was processed directly by dbPutField() (eg. via channel access). "CPP" links use dbProcess(), which didn't do this. A CPP link adds its the record to the scanOnce queue to perform the processing. If the record happens to be busy (PACT=TRUE) when the onceTask() gets to it that trigger will be lost. To confirm, try setting DEV1:trgOn.TPRO and you should see something like scanOnce: Active: DEV1:trgOninstead of scanOnce: Process: DEV1:trgOnat the times when you end up with a seemingly impossible state. If you were to change DEV1:st into a calcout record and make its OUT field "DEV1:trgOn.B PP" (removing the INPB field setting from DEV1:trgOn) this should enable the RPRO behaviour that you're looking for, although I'm not sure if it will fix the problem completely. HTH, - Andrew On 8/26/19 9:46 AM, Benjamin Franksen via Core-talk wrote:I am using base-3.15.6. This is a part of a larger database, running on a soft IOC on Linux: record(calc,"DEV1:st") { # the field details are irrelevant here, # just note this is a simple soft record # that gets processed via CPP input links field(INPA,"DEV1:stZ CPP") field(INPB,"DEV1:stS CPP") field(CALC,"A<<4|B&0xf") } record(calcout,"DEV1:trgOn") { field(INPA,"DEV1:sel") # trigger processing on change of readback field(INPB,"DEV1:st CPP") field(CALC,"A==B") field(DOPT,"Transition to non-zero") field(DTYP,"Async Soft Channel") field(OUT,"DEV2:switch CA") } The values involved are all integers. DEV1:sel is the setpoint, DEV1:st is the (soft) readback, which gets triggered by writing DEV1.sel via a chain of FLNKs, OUT PP links and CPP input links. The idea is to write a "1" to the DEV2:switch (which is a different device controlled by another IOC) when the readback has settled to the same value as the setpoint. The device DEV1 is complex and requires various separate commands to effect the change, and the readback can go through 2 or 3 different values before finally coinciding with the setpoint. When I set DEV1:sel (using caput) to different values, I can sometimes get into a situation where the database has the following (persistent) state: DEV1:sel.VAL=0 DEV1:st.VAL=0 DEV1:trgOn.A=0 DEV1:trgOn.B=8 DEV1:trgOn.VAL=0 I think this should not be possible, assuming that (1) the value of the last monitor event (here: from DEV1:st) always wins over previous events, and (2) if a record (here: DEV1:trgOn) is active (PACT=1) when an event arrives, it gets processed again, after completing. Either this is a bug or at least one of my assumptions is wrong. I wonder which. Cheers Ben -- Complexity comes for free, Simplicity you have to work for. |