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 | 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 |
<== Date ==> | <== Thread ==> |
---|
Subject: | RE: SNL monitor and pvPutComplete |
From: | Emmanuel Mayssat <[email protected]> |
To: | "Pearson, Matthew R." <[email protected]>, EPICS mailing list <[email protected]> |
Date: | Tue, 21 Jan 2014 16:58:19 -0800 |
Although I haven't programmed the seq for a while, here is what I believe is happening
The "monitored" variable is (in concept) similar to a volatile C variable. The variable is automatically updated based on what is in the EPICS database (not the hardware!). If the update of status_pv is completing after pvPutComplete, then you will experience what you describe. If you want to trigger state changes or processing on an update (i.e. monitor) you need to use event flags * efTest check that the flag is at 1 ( a monitor has been received since it was last cleared) * efTestAndClear does the same and reset the flag to 0 Those commands are most often found in test (when) conditions. Otherwise use efClear and efSet sample code: /* Monitored variables */ double voltageAO; assign voltageAO to "{deviceName}:{channelId}VltgAO"; monitor voltageAO; evflag monitorVoltageAO; sync voltageAO monitorVoltageAO; [...] state channel_idleState { entry { seqLog("--> channel_idleState\n"); seqLog("efAO=%d, efMO=%d\n", efTest(monitorVoltageAO), efTest(monitorVoltageMO)); } when(efTest(monitorVoltageAO) ) { efClear(monitorVoltageAO); } state channel_updateVoltageMIState when(!efTest(monitorVoltageAO) && efTest(monitorVoltageMO)) { efClear(monitorVoltageMO); } state channel_updateVoltageAOState exit { seqLog("<-- channel_idleState\n"); } } > From: [email protected] > To: [email protected] > Date: Tue, 21 Jan 2014 17:42:46 -0500 > Subject: SNL monitor and pvPutComplete > > > Hi, > > I'm using SNL to perform a potentially long put_callback, using pvPut with the ASYNC option in one state, followed by the use of pvPutComplete in the following state. Then on completion, I read another PV immediately, which has an SNL monitor on it, something like: > > unsigned short start_pv; assign start_pv to "{RC}:Start"; monitor start_pv; > > unsigned short login_pv; assign login_pv to "{DAS}:Login"; > unsigned short status_pv; assign status_pv to "{DAS}:Stat"; monitor status_pv; > > state idle { > /* When we detect a user start. */ > when (start_pv == 1) { > login_pv = 1; > pvPut(login_pv, ASYNC); > } state login > } > > > state login { > when (pvPutComplete(login_pv)) { > if (status_pv != 1) { > /*handle error here*/ > } else { > /*it worked */ > } > } state thenextstate > } > > > I have a race condition between the completion of the put_callback and the status_pv variable updating due to a monitor. I sometimes read the value the status PV had before the callback completes. I've tested the underlying system quite a bit, so I suspected a problem with my SNL. I added in a pvGet(status_pv) just before I test that variable, and it seems to have solved it (which maybe just due to the extra time taken to execute the pvGet). > > Am I handling this situation incorrectly, or do we know of a problem with monitors in SNL (SEQ Version 2.0.14)? Is the use of pvGet on a monitored variable a bad idea? From reading tech-talk, it might be frowned upon... > > Or, is there a better way of doing this, using event flags? > > Cheers, > Matt > > > > |