Merge branch 'epics-base:7.0' into add-simm-to-ao-records

This commit is contained in:
Evan Daykin
2021-06-09 10:19:01 -04:00
334 changed files with 5850 additions and 2557 deletions

View File

@@ -63,7 +63,7 @@ static long read_lsi(lsiRecord *prec)
prec->val[0] = 0;
prec->len = 1;
prec->udf = TRUE;
recGblSetSevr(prec, UDF_ALARM, prec->udfs);
recGblSetSevrMsg(prec, UDF_ALARM, prec->udfs, "No such ENV");
}
return 0;
@@ -114,7 +114,7 @@ static long read_stringin(stringinRecord *prec)
else {
prec->val[0] = 0;
prec->udf = TRUE;
recGblSetSevr(prec, UDF_ALARM, prec->udfs);
recGblSetSevrMsg(prec, UDF_ALARM, prec->udfs, "No such ENV");
}
return 0;

View File

@@ -16,6 +16,7 @@ dbRecStd_SRCS += dbnd.c
dbRecStd_SRCS += arr.c
dbRecStd_SRCS += sync.c
dbRecStd_SRCS += decimate.c
dbRecStd_SRCS += utag.c
HTMLS += filters.html

View File

@@ -16,6 +16,8 @@ The following filters are available in this release:
=item * L<Decimation|/"Decimation Filter dec">
=item * L<UTag|/"UTag Filter utag">
=back
=head2 Using Filters
@@ -285,3 +287,26 @@ once every minute:
...
=cut
registrar(utagInitialize)
=head3 UTag Filter C<"utag">
This filter applies a test UTAG&M==V to the value taken from the UTAG record field
and drops those updates which evaluate as false.
=head4 Parameters
=over
=item Mask C<"M">
Bit mask.
=item Value C<"V">
Required value.
=back
=cut

View File

@@ -0,0 +1,99 @@
/*************************************************************************\
* Copyright (c) 2020 Michael Davidsaver
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include <stdlib.h>
#include <caeventmask.h>
#include <chfPlugin.h>
#include <dbCommon.h>
#include <epicsStdio.h>
#include <epicsExport.h>
typedef struct {
epicsInt32 mask, value;
int first;
} utagPvt;
static const
chfPluginArgDef opts[] = {
chfInt32(utagPvt, mask, "M", 0, 1),
chfInt32(utagPvt, value, "V", 0, 1),
chfPluginArgEnd
};
static void * allocPvt(void)
{
utagPvt *pvt;
pvt = calloc(1, sizeof(utagPvt));
pvt->mask = 0xffffffff;
return pvt;
}
static void freePvt(void *pvt)
{
free(pvt);
}
static int parse_ok(void *raw)
{
utagPvt *pvt = (utagPvt*)raw;
pvt->first = 1;
return 0;
}
static db_field_log* filter(void* raw, dbChannel *chan, db_field_log *pfl)
{
utagPvt *pvt = (utagPvt*)raw;
epicsUTag utag = pfl->utag;
int drop = (utag&pvt->mask)!=pvt->value;
if(pfl->ctx!=dbfl_context_event || pfl->mask&DBE_PROPERTY) {
/* never drop for reads, or property events */
} else if(pvt->first) {
/* never drop first */
pvt->first = 0;
} else if(drop) {
db_delete_field_log(pfl);
pfl = NULL;
}
return pfl;
}
static void channelRegisterPre(dbChannel *chan, void *pvt,
chPostEventFunc **cb_out, void **arg_out, db_field_log *probe)
{
*cb_out = filter;
*arg_out = pvt;
}
static void channel_report(dbChannel *chan, void *raw, int level, const unsigned short indent)
{
utagPvt *pvt = (utagPvt*)raw;
printf("%*sutag : mask=0x%08x value=0x%08x\n", indent, "", (epicsUInt32)pvt->mask, (epicsUInt32)pvt->value);
}
static const
chfPluginIf pif = {
allocPvt,
freePvt,
NULL, /* parse_error */
parse_ok, /* parse_ok */
NULL, /* channel_open */
channelRegisterPre,
NULL, /* channelRegisterPost */
channel_report,
NULL, /* channel_close */
};
static
void utagInitialize(void)
{
chfPluginRegister("utag", &pif, opts);
}
epicsExportRegistrar(utagInitialize);

View File

@@ -53,6 +53,7 @@ typedef struct calc_link {
} pstate;
epicsEnum16 stat;
epicsEnum16 sevr;
char amsg[DB_AMSG_SIZE];
short prec;
char *expr;
char *major;
@@ -66,6 +67,7 @@ typedef struct calc_link {
struct link out;
double arg[CALCPERFORM_NARGS];
epicsTimeStamp time;
epicsUTag utag;
double val;
} calc_link;
@@ -385,9 +387,10 @@ static void lnkCalc_report(const jlink *pjlink, int level, int indent)
if (level > 0) {
if (clink->sevr)
printf("%*s Alarm: %s, %s\n", indent, "",
printf("%*s Alarm: %s, %s, \"%s\"\n", indent, "",
epicsAlarmSeverityStrings[clink->sevr],
epicsAlarmConditionStrings[clink->stat]);
epicsAlarmConditionStrings[clink->stat],
clink->amsg);
if (clink->post_major)
printf("%*s Major expression: \"%s\"\n", indent, "",
@@ -532,6 +535,7 @@ static long lnkCalc_getElements(const struct link *plink, long *nelements)
struct lcvt {
double *pval;
epicsTimeStamp *ptime;
epicsUTag *ptag;
};
static long readLocked(struct link *pinp, void *vvt)
@@ -541,7 +545,7 @@ static long readLocked(struct link *pinp, void *vvt)
long status = dbGetLink(pinp, DBR_DOUBLE, pvt->pval, NULL, &nReq);
if (!status && pvt->ptime)
dbGetTimeStamp(pinp, pvt->ptime);
dbGetTimeStampTag(pinp, pvt->ptime, pvt->ptag);
return status;
}
@@ -567,7 +571,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
long nReq = 1;
if (i == clink->tinp) {
struct lcvt vt = {&clink->arg[i], &clink->time};
struct lcvt vt = {&clink->arg[i], &clink->time, &clink->utag};
status = dbLinkDoLocked(child, readLocked, &vt);
if (status == S_db_noLSET)
@@ -576,6 +580,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
if (dbLinkIsConstant(&prec->tsel) &&
prec->tse == epicsTimeEventDeviceTime) {
prec->time = clink->time;
prec->utag = clink->utag;
}
}
else
@@ -583,6 +588,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
}
clink->stat = 0;
clink->sevr = 0;
clink->amsg[0] = '\0';
if (clink->post_expr) {
status = calcPerform(clink->arg, &clink->val, clink->post_expr);
@@ -604,7 +610,8 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
if (!status && alval) {
clink->stat = LINK_ALARM;
clink->sevr = MAJOR_ALARM;
recGblSetSevr(prec, clink->stat, clink->sevr);
strcpy(clink->amsg, "post_major error");
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_major error");
}
}
@@ -615,7 +622,8 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
if (!status && alval) {
clink->stat = LINK_ALARM;
clink->sevr = MINOR_ALARM;
recGblSetSevr(prec, clink->stat, clink->sevr);
strcpy(clink->amsg, "post_minor error");
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_minor error");
}
}
@@ -643,7 +651,7 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
long nReq = 1;
if (i == clink->tinp) {
struct lcvt vt = {&clink->arg[i], &clink->time};
struct lcvt vt = {&clink->arg[i], &clink->time, &clink->utag};
status = dbLinkDoLocked(child, readLocked, &vt);
if (status == S_db_noLSET)
@@ -652,6 +660,7 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
if (dbLinkIsConstant(&prec->tsel) &&
prec->tse == epicsTimeEventDeviceTime) {
prec->time = clink->time;
prec->utag = clink->utag;
}
}
else
@@ -659,6 +668,7 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
}
clink->stat = 0;
clink->sevr = 0;
clink->amsg[0] = '\0';
/* Get the value being output as VAL */
status = conv(pbuffer, &clink->val, NULL);
@@ -673,7 +683,8 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
if (!status && alval) {
clink->stat = LINK_ALARM;
clink->sevr = MAJOR_ALARM;
recGblSetSevr(prec, clink->stat, clink->sevr);
strcpy(clink->amsg, "post_major error");
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_major error");
}
}
@@ -684,7 +695,8 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
if (!status && alval) {
clink->stat = LINK_ALARM;
clink->sevr = MINOR_ALARM;
recGblSetSevr(prec, clink->stat, clink->sevr);
strcpy(clink->amsg, "post_major error");
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_minor error");
}
}
@@ -718,8 +730,8 @@ static long lnkCalc_getUnits(const struct link *plink, char *units, int len)
return 0;
}
static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity)
static long lnkCalc_getAlarmMsg(const struct link *plink, epicsEnum16 *status,
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen)
{
calc_link *clink = CONTAINER(plink->value.json.jlink,
struct calc_link, jlink);
@@ -728,17 +740,23 @@ static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status,
*status = clink->stat;
if (severity)
*severity = clink->sevr;
if (msgbuf && msgbuflen) {
strncpy(msgbuf, clink->amsg, msgbuflen-1);
msgbuf[msgbuflen-1] = '\0';
}
return 0;
}
static long lnkCalc_getTimestamp(const struct link *plink, epicsTimeStamp *pstamp)
static long lnkCalc_getTimestampTag(const struct link *plink, epicsTimeStamp *pstamp, epicsUTag *ptag)
{
calc_link *clink = CONTAINER(plink->value.json.jlink,
struct calc_link, jlink);
if (clink->tinp >= 0) {
*pstamp = clink->time;
if(ptag)
*ptag = clink->utag;
return 0;
}
@@ -761,9 +779,11 @@ static lset lnkCalc_lset = {
lnkCalc_getValue,
NULL, NULL, NULL,
lnkCalc_getPrecision, lnkCalc_getUnits,
lnkCalc_getAlarm, lnkCalc_getTimestamp,
NULL, NULL,
lnkCalc_putValue, NULL,
NULL, doLocked
NULL, doLocked,
lnkCalc_getAlarmMsg,
lnkCalc_getTimestampTag,
};
static jlif lnkCalcIf = {

View File

@@ -432,7 +432,7 @@ static void convert(aiRecord *prec)
default: /* must use breakpoint table */
if (cvtRawToEngBpt(&val,prec->linr,prec->init,(void *)&prec->pbrk,&prec->lbrk)!=0) {
recGblSetSevr(prec,SOFT_ALARM,MAJOR_ALARM);
recGblSetSevrMsg(prec,SOFT_ALARM,MAJOR_ALARM, "BPT Error");
}
}

View File

@@ -236,7 +236,7 @@ static long process(struct dbCommon *pcommon)
}
if (fetch_values(prec) == 0) {
if (calcPerform(&prec->a, &prec->val, prec->rpcl)) {
recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM);
recGblSetSevrMsg(prec, CALC_ALARM, INVALID_ALARM, "calcPerform");
} else {
prec->udf = isnan(prec->val);
}
@@ -610,7 +610,7 @@ static void execOutput(calcoutRecord *prec)
break;
case calcoutDOPT_Use_OVAL:
if (calcPerform(&prec->a, &prec->oval, prec->orpc)) {
recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM);
recGblSetSevrMsg(prec, CALC_ALARM, INVALID_ALARM, "OCAL calcPerform");
} else {
prec->udf = isnan(prec->oval);
}
@@ -770,7 +770,7 @@ static long writeValue(calcoutRecord *prec)
if (!pcalcoutDSET || !pcalcoutDSET->write) {
errlogPrintf("%s DSET write does not exist\n", prec->name);
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
recGblSetSevrMsg(prec, SOFT_ALARM, INVALID_ALARM, "DSET write does not exist");
prec->pact = TRUE;
return(-1);
}

View File

@@ -28,7 +28,5 @@ softIoc_LIBS = $(EPICS_BASE_IOC_LIBS)
DB += softIocExit.db
FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
CLEANS += epicsInstallDir.h

View File

@@ -249,7 +249,10 @@ int main(int argc, char *argv[])
} else {
if (loadedDb || ranScript) {
epicsThreadExitMain();
// non-interactive IOC. spin forever
while(true) {
epicsThreadSleep(1000.0);
}
} else {
usage(argv[0], dbd_file);