diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index f9abf8f9b..39375f856 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -15,6 +15,47 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
The fanout record type now has 16 output links LNK0-LNK9 and LNKA-LNKF, plus +two additional fields which make the result backwards compatible with 3.14 +databases, but also allow the link selection to be shifted without having to +process the SELN value through a calc or calcout record first.
+ +Previously there was no LNK0 field, so when SELM is Mask
bit 0 of SELN
+controls whether the LNK1 link field was activated; bit 1 controls LNK2 and so
+on. When SELM is Specified
and SELN is zero no output link would be
+activated at all; LNK1 gets activated when SELN is 1 and so on. Only 6 links
+were provided, LNK1 through LNK6. The updated record type maintains the original
+behavior when the new fields are not configured.
The update involved adding a LNK0 field, as well as fields LNK7 through LNK9 +and LNKA through LNKF. To add flexibility and maintain backwards compatibility, +two additional fields have been added:
+ +Specified. If the resulting value is outside the +range 0 .. 15 the record will go into a SOFT/INVALID alarm state. The default +value of OFFS is zero, so if it is not explicitly set and SELN is 1 the LNK1 +link will be activated.
Maskthe signed field SHFT is used to shift the SELN +value by SHFT bits (positive means right-wards, values outside the range -15 .. +15 will result in a SOFT/INVALID alarm), before using the resulting bit-pattern +to control which links to activate. The default value is -1, so if SHFT is not +explicitly set bit 0 of SELN will be used to control whether LNK1 gets +activated.
The record also now posts monitors on the SELN field if it changes as a +result of record processing (i.e. when read through the SELL link).
+Java has its own build systems now, so we've deleted the rules and associated diff --git a/src/std/rec/fanoutRecord.c b/src/std/rec/fanoutRecord.c index d8b7f732f..b776f411b 100644 --- a/src/std/rec/fanoutRecord.c +++ b/src/std/rec/fanoutRecord.c @@ -1,5 +1,5 @@ /*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne +* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. @@ -26,6 +26,7 @@ #include "dbEvent.h" #include "dbFldTypes.h" #include "errMdef.h" +#include "epicsTypes.h" #include "recSup.h" #include "recGbl.h" #include "dbCommon.h" @@ -34,6 +35,8 @@ #undef GEN_SIZE_OFFSET #include "epicsExport.h" +#define NLINKS 16 + /* Create RSET - Record Support Entry Table*/ #define report NULL #define initialize NULL @@ -53,89 +56,100 @@ static long process(fanoutRecord *); #define get_control_double NULL #define get_alarm_double NULL -rset fanoutRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double +rset fanoutRSET = { + RSETNUMBER, + report, + initialize, + init_record, + process, + special, + get_value, + cvt_dbaddr, + get_array_info, + put_array_info, + get_units, + get_precision, + get_enum_str, + get_enum_strs, + put_enum_str, + get_graphic_double, + get_control_double, + get_alarm_double }; epicsExportAddress(rset,fanoutRSET); static long init_record(fanoutRecord *prec, int pass) { - if (pass==0) return(0); - recGblInitConstantLink(&prec->sell,DBF_USHORT,&prec->seln); - return(0); + if (pass == 0) + return 0; + + recGblInitConstantLink(&prec->sell, DBF_USHORT, &prec->seln); + return 0; } - + static long process(fanoutRecord *prec) { - struct link *plink; - unsigned short state; - short i; + struct link *plink; + epicsUInt16 seln, monitor_mask; + int i; + epicsUInt16 oldn = prec->seln; prec->pact = TRUE; - /* fetch link selection */ - dbGetLink(&(prec->sell),DBR_USHORT,&(prec->seln),0,0); - switch (prec->selm){ - case (fanoutSELM_All): - plink=&(prec->lnk1); - state=prec->seln; - for ( i=0; i<6; i++, state>>=1, plink++) { - if(plink->type!=CONSTANT) dbScanFwdLink(plink); + /* fetch link selection */ + dbGetLink(&prec->sell, DBR_USHORT, &prec->seln, 0, 0); + seln = prec->seln; + + switch (prec->selm) { + case fanoutSELM_All: + plink = &prec->lnk0; + for (i = 0; i < NLINKS; i++, plink++) { + if (plink->type != CONSTANT) + dbScanFwdLink(plink); } break; - case (fanoutSELM_Specified): - if(prec->seln>6) { - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); + + case fanoutSELM_Specified: + i = seln + prec->offs; + if (i < 0 || i >= NLINKS) { + recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); break; } - if(prec->seln==0) { - break; - } - plink=&(prec->lnk1); - plink += (prec->seln-1); dbScanFwdLink(plink); + plink = &prec->lnk0 + i; + dbScanFwdLink(plink); break; - case (fanoutSELM_Mask): - if(prec->seln==0) { + + case fanoutSELM_Mask: + i = prec->shft; + if (i < -15 || i > 15) { + /* Shifting by more than the number of bits in the + * value produces undefined behavior in C */ + recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); break; } - if(prec->seln>63 ) { - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); + seln = (i >= 0) ? seln >> i : seln << -i; + if (seln == 0) break; - } - plink=&(prec->lnk1); - state=prec->seln; - for ( i=0; i<6; i++, state>>=1, plink++) { - if(state & 1 && plink->type!=CONSTANT) dbScanFwdLink(plink); + plink = &prec->lnk0; + for (i = 0; i < NLINKS; i++, seln >>= 1, plink++) { + if (seln & 1 && plink->type != CONSTANT) + dbScanFwdLink(plink); } break; default: - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); + recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); } - prec->udf=FALSE; + prec->udf = FALSE; recGblGetTimeStamp(prec); - /* check monitors*/ - /* get previous stat and sevr and new stat and sevr*/ - recGblResetAlarms(prec); - /* process the forward scan link record */ + + /* post monitors */ + monitor_mask = recGblResetAlarms(prec); + if (prec->seln != oldn) + db_post_events(prec, &prec->seln, monitor_mask | DBE_VALUE | DBE_LOG); + + /* finish off */ recGblFwdLink(prec); - prec->pact=FALSE; - return(0); + prec->pact = FALSE; + return 0; } diff --git a/src/std/rec/fanoutRecord.dbd b/src/std/rec/fanoutRecord.dbd index 6a03079d9..8ad9209fc 100644 --- a/src/std/rec/fanoutRecord.dbd +++ b/src/std/rec/fanoutRecord.dbd @@ -1,10 +1,9 @@ #************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne +# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne # National Laboratory. # Copyright (c) 2002 The Regents of the University of California, as # Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found +# EPICS BASE is distributed subject to a Software License Agreement found # in file LICENSE that is included with this distribution. #************************************************************************* menu(fanoutSELM) { @@ -35,6 +34,21 @@ recordtype(fanout) { promptgroup(GUI_LINKS) interest(1) } + field(OFFS,DBF_SHORT) { + prompt("Offset for Specified") + interest(1) + initial("0") + } + field(SHFT,DBF_SHORT) { + prompt("Shift for Mask mode") + interest(1) + initial("-1") + } + field(LNK0,DBF_FWDLINK) { + prompt("Forward Link 0") + promptgroup(GUI_LINKS) + interest(1) + } field(LNK1,DBF_FWDLINK) { prompt("Forward Link 1") promptgroup(GUI_LINKS) @@ -65,4 +79,49 @@ recordtype(fanout) { promptgroup(GUI_LINKS) interest(1) } + field(LNK7,DBF_FWDLINK) { + prompt("Forward Link 7") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNK8,DBF_FWDLINK) { + prompt("Forward Link 8") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNK9,DBF_FWDLINK) { + prompt("Forward Link 9") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNKA,DBF_FWDLINK) { + prompt("Forward Link 10") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNKB,DBF_FWDLINK) { + prompt("Forward Link 11") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNKC,DBF_FWDLINK) { + prompt("Forward Link 12") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNKD,DBF_FWDLINK) { + prompt("Forward Link 13") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNKE,DBF_FWDLINK) { + prompt("Forward Link 14") + promptgroup(GUI_LINKS) + interest(1) + } + field(LNKF,DBF_FWDLINK) { + prompt("Forward Link 15") + promptgroup(GUI_LINKS) + interest(1) + } }