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: | mbboDirect Bx fields don't update on alarm change |
From: | "Kasemir, Kay via Tech-talk" <tech-talk at aps.anl.gov> |
To: | "'tech-talk at aps.anl.gov'" <tech-talk at aps.anl.gov> |
Date: | Tue, 31 Aug 2021 17:03:55 +0000 |
Hi:
I have an mbboDirect that writes to hardware, with each B0, B1, .. bit shown on a display as a checkbox for users to set/clear.
At startup, the record is INVALID, VAL and all B0, B1, .. bit fields defaulting to 0, until device support can once communicate with the hardware and fetch the initial value, i.e., the record correctly initializes from the hardware for 'bumpless' startup.
On the GUI, however, this looks odd because the mbboDirect doesn't send out monitors for the alarm change if the bit field value is still zero. Only bit fields that changed to 1 as a result of the 'bumpless' initialization at startup get updates.
So on the GUI, all those checkboxes with values 0 show an INVALID alarm until the display is closed/re-opened.
The effect can be duplicated with a softIoc running just this:
record(mbboDirect, "test")
{
field(SCAN, "10 second")
}
Start the IOC, then quickly run `camonitor test test.B0 test.B1`.
Initially, they read
test <undefined> 0 UDF INVALID
test.B0 <undefined> 0 UDF INVALID
test.B1 <undefined> 0 UDF INVALID
After about 10 seconds when the record is first scanned, there is one update:
test 2021-08-31 12:54:08.266960 0
There is no monitor for the B0, B1, ... bit fields. When closing the monitor and starting it again, all fields read OK.
I see that behavior with at least base 3.15.9, R7.0.4.1 and 7.0.6.
One way to fix it is to update mbboDirectRecord.c monitor() as shown below, where the "if (events) .." block now sends out monitors on all bit fields. With that in place, the camonitor will see
a time stamp and no alarm as soon as the record processes on all bit fields.
Were these
db_post_events simply missing?
Thanks,
Kay
static void monitor(mbboDirectRecord *prec)
{
epicsUInt16 events = recGblResetAlarms(prec);
if (prec->mlst != prec->val) {
events |= DBE_VALUE | DBE_LOG;
prec->mlst = prec->val;
}
if (events)
{
db_post_events(prec, &prec->val, events);
// Update bit fields
epicsUInt8 *pBn = &prec->b0;
int i;
for (i = 0; i < NUM_BITS; i++, pBn++)
db_post_events(prec, pBn, events);
}
events |= DBE_VALUE | DBE_LOG;
if (prec->oraw != prec->rval) {
db_post_events(prec, &prec->rval, events);
prec->oraw = prec->rval;
}
if (prec->orbv != prec->rbv) {
db_post_events(prec, &prec->rbv, events);
prec->orbv = prec->rbv;
}
}
|