From 9c1b8ba9521e2aee0b3e78af00b0f56424433bbe Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sat, 6 Oct 2012 21:48:01 -0500 Subject: [PATCH 1/5] rec: Fix problem with NAN in MLST/ALST fields If MLST or ALST became NAN the associated monitor would never trigger. Now a NAN will cause it to always trigger. --- documentation/RELEASE_NOTES.html | 6 ++++++ src/rec/aiRecord.c | 4 ++-- src/rec/aoRecord.c | 4 ++-- src/rec/calcRecord.c | 4 ++-- src/rec/calcoutRecord.c | 17 +++++++++-------- src/rec/dfanoutRecord.c | 4 ++-- src/rec/selRecord.c | 4 ++-- src/rec/subRecord.c | 4 ++-- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 47babb91b..7d1e8b842 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,12 @@ +

Problem with NAN values in MLST/ALST fields

+ +

The ai, ao, calc, calcout, dfanout, sel and sub record types could stop +posting monitors if they got NAN values in their MLST or ALST fields. A change +has been included so this should no longer be the case.

+

MacOS build defaults changed

The default build settings for darwin-x86 targets have been changed to match diff --git a/src/rec/aiRecord.c b/src/rec/aiRecord.c index 343d62126..e6977005f 100644 --- a/src/rec/aiRecord.c +++ b/src/rec/aiRecord.c @@ -385,7 +385,7 @@ static void monitor(aiRecord *prec) /* check for value change */ delta = prec->mlst - prec->val; if(delta<0.0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -395,7 +395,7 @@ static void monitor(aiRecord *prec) /* check for archive change */ delta = prec->alst - prec->val; if(delta<0.0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ diff --git a/src/rec/aoRecord.c b/src/rec/aoRecord.c index 5f8436ab2..bce43e3e4 100644 --- a/src/rec/aoRecord.c +++ b/src/rec/aoRecord.c @@ -484,7 +484,7 @@ static void monitor(aoRecord *prec) /* check for value change */ delta = prec->mlst - prec->val; if(delta<0.0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -493,7 +493,7 @@ static void monitor(aoRecord *prec) /* check for archive change */ delta = prec->alst - prec->val; if(delta<0.0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ diff --git a/src/rec/calcRecord.c b/src/rec/calcRecord.c index 722ce0698..8accf60d9 100644 --- a/src/rec/calcRecord.c +++ b/src/rec/calcRecord.c @@ -310,7 +310,7 @@ static void monitor(calcRecord *prec) /* check for value change */ delta = prec->mlst - prec->val; if (delta < 0.0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -319,7 +319,7 @@ static void monitor(calcRecord *prec) /* check for archive change */ delta = prec->alst - prec->val; if (delta < 0.0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c index 0b7c78323..89265f3cc 100644 --- a/src/rec/calcoutRecord.c +++ b/src/rec/calcoutRecord.c @@ -209,7 +209,7 @@ static long init_record(calcoutRecord *prec, int pass) static long process(calcoutRecord *prec) { rpvtStruct *prpvt = prec->rpvt; - int doOutput = 0; + int doOutput; if (!prec->pact) { prec->pact = TRUE; @@ -231,21 +231,22 @@ static long process(calcoutRecord *prec) doOutput = 1; break; case calcoutOOPT_On_Change: - if (fabs(prec->pval - prec->val) > prec->mdel) doOutput = 1; + doOutput = ! (fabs(prec->pval - prec->val) <= prec->mdel); break; case calcoutOOPT_Transition_To_Zero: - if ((prec->pval != 0.0) && (prec->val == 0.0)) doOutput = 1; + doOutput = ((prec->pval != 0.0) && (prec->val == 0.0)); break; case calcoutOOPT_Transition_To_Non_zero: - if ((prec->pval == 0.0) && (prec->val != 0.0)) doOutput = 1; + doOutput = ((prec->pval == 0.0) && (prec->val != 0.0)); break; case calcoutOOPT_When_Zero: - if (prec->val == 0.0) doOutput = 1; + doOutput = (prec->val == 0.0); break; case calcoutOOPT_When_Non_zero: - if (prec->val != 0.0) doOutput = 1; + doOutput = (prec->val != 0.0); break; default: + doOutput = 0; break; } prec->pval = prec->val; @@ -584,7 +585,7 @@ static void monitor(calcoutRecord *prec) /* check for value change */ delta = prec->mlst - prec->val; if (delta<0.0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -593,7 +594,7 @@ static void monitor(calcoutRecord *prec) /* check for archive change */ delta = prec->alst - prec->val; if (delta<0.0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ diff --git a/src/rec/dfanoutRecord.c b/src/rec/dfanoutRecord.c index 672c1cccd..723d1a59c 100644 --- a/src/rec/dfanoutRecord.c +++ b/src/rec/dfanoutRecord.c @@ -267,7 +267,7 @@ static void monitor(dfanoutRecord *prec) /* check for value change */ delta = prec->mlst - prec->val; if(delta<0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -276,7 +276,7 @@ static void monitor(dfanoutRecord *prec) /* check for archive change */ delta = prec->alst - prec->val; if(delta<0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ diff --git a/src/rec/selRecord.c b/src/rec/selRecord.c index 6bc43c227..6174dab3d 100644 --- a/src/rec/selRecord.c +++ b/src/rec/selRecord.c @@ -300,7 +300,7 @@ static void monitor(selRecord *prec) /* check for value change */ delta = prec->mlst - prec->val; if(delta<0.0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -309,7 +309,7 @@ static void monitor(selRecord *prec) /* check for archive change */ delta = prec->alst - prec->val; if(delta<0.0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ diff --git a/src/rec/subRecord.c b/src/rec/subRecord.c index c07de5692..b16a89c3c 100644 --- a/src/rec/subRecord.c +++ b/src/rec/subRecord.c @@ -353,7 +353,7 @@ static void monitor(subRecord *prec) /* check for value change */ delta = prec->val - prec->mlst; if (delta < 0.0) delta = -delta; - if (delta > prec->mdel) { + if (!(delta <= prec->mdel)) { /* Handles MDEL == NAN */ /* post events for value change */ monitor_mask |= DBE_VALUE; /* update last value monitored */ @@ -362,7 +362,7 @@ static void monitor(subRecord *prec) /* check for archive change */ delta = prec->val - prec->alst; if (delta < 0.0) delta = -delta; - if (delta > prec->adel) { + if (!(delta <= prec->adel)) { /* Handles ADEL == NAN */ /* post events on value field for archive change */ monitor_mask |= DBE_LOG; /* update last archive value monitored */ From 26173c1e0d6015853450ad10b0e015faeb707450 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 10 Oct 2012 15:52:34 -0500 Subject: [PATCH 2/5] devLib: add compatibility typedef for VME table type --- src/libCom/osi/devLibVMEImpl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h index 63d794ca3..e695edeb9 100644 --- a/src/libCom/osi/devLibVMEImpl.h +++ b/src/libCom/osi/devLibVMEImpl.h @@ -94,6 +94,7 @@ epicsShareExtern devLibVME *pdevLibVME; #ifndef NO_DEVLIB_COMPAT # define pdevLibVirtualOS pdevLibVME +typedef devLibVME devLibVirtualOS; #endif From 71079ede4b86af81805d0e26d99533909fdba7ba Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 11 Oct 2012 17:51:00 -0500 Subject: [PATCH 3/5] rec/aSub: Fixes from Michael Davidsaver * Changing the number of elements in a VALx array triggers monitors * Post monitors on the NEVx fields, following EFLG * Remove artificial limit on array sizes --- src/rec/aSubRecord.c | 51 +++++----- src/rec/aSubRecord.dbd | 210 ++++++++++++++++++++++++++++++++--------- 2 files changed, 194 insertions(+), 67 deletions(-) diff --git a/src/rec/aSubRecord.c b/src/rec/aSubRecord.c index 24447cee3..fd96ede20 100644 --- a/src/rec/aSubRecord.c +++ b/src/rec/aSubRecord.c @@ -85,13 +85,12 @@ rset aSubRSET = { epicsExportAddress(rset, aSubRSET); static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, - const char **fldnames, void **pval, void **povl); + epicsUInt32 *pon, const char **fldnames, void **pval, void **povl); static long fetch_values(aSubRecord *prec); static void monitor(aSubRecord *); static long do_sub(aSubRecord *); #define NUM_ARGS 21 -#define MAX_ARRAY_SIZE 10000000 /* These are the names of the Input fields */ static const char *Ifldnames[] = { @@ -117,10 +116,10 @@ static long init_record(aSubRecord *prec, int pass) status = 0; if (pass == 0) { /* Allocate memory for arrays */ - initFields(&prec->fta, &prec->noa, &prec->nea, Ifldnames, - &prec->a, NULL); - initFields(&prec->ftva, &prec->nova, &prec->neva, Ofldnames, - &prec->vala, &prec->ovla); + initFields(&prec->fta, &prec->noa, &prec->nea, NULL, + Ifldnames, &prec->a, NULL); + initFields(&prec->ftva, &prec->nova, &prec->neva, &prec->onva, + Ofldnames, &prec->vala, &prec->ovla); return 0; } @@ -146,12 +145,8 @@ static long init_record(aSubRecord *prec, int pass) struct link *plink = &(&prec->inpa)[i]; switch (plink->type) { case CONSTANT: - if ((&prec->noa)[i] < 2) { - if (recGblInitConstantLink(plink, (&prec->fta)[i], (&prec->a)[i])) { - prec->udf = FALSE; - } else - prec->udf = TRUE; - } + if ((&prec->noa)[i] < 2) + recGblInitConstantLink(plink, (&prec->fta)[i], (&prec->a)[i]); break; case PV_LINK: @@ -218,7 +213,7 @@ static long init_record(aSubRecord *prec, int pass) static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, - const char **fldnames, void **pval, void **povl) + epicsUInt32 *pon, const char **fldnames, void **pval, void **povl) { int i; long status = 0; @@ -235,22 +230,16 @@ static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, flen = dbValueSize(*pft); num = *pno * flen; - - if (num > MAX_ARRAY_SIZE) { - epicsPrintf("Link %s - Array too large! %d Bytes\n", fldnames[i], num); - *pno = num = 0; - status = S_db_errArg; - } else - *pval = (char *)callocMustSucceed(*pno, flen, - "aSubRecord::init_record"); + *pval = callocMustSucceed(*pno, flen, "aSubRecord::init_record"); *pne = *pno; if (povl) { if (num) - *povl = (char *)callocMustSucceed(*pno, flen, + *povl = callocMustSucceed(*pno, flen, "aSubRecord::init_record"); povl++; + *pon++ = *pne; } } return status; @@ -281,6 +270,7 @@ static long process(aSubRecord *prec) /* Push the output link values */ if (!status) { int i; + for (i = 0; i < NUM_ARGS; i++) dbPutLink(&(&prec->outa)[i], (&prec->ftva)[i], (&prec->vala)[i], (&prec->neva)[i]); @@ -359,18 +349,29 @@ static void monitor(aSubRecord *prec) break; case aSubEFLG_ON_CHANGE: for (i = 0; i < NUM_ARGS; i++) { - epicsUInt32 alen = dbValueSize((&prec->ftva)[i]) * (&prec->neva)[i]; void *povl = (&prec->ovla)[i]; void *pval = (&prec->vala)[i]; - if (memcmp(povl, pval, alen)) { + epicsUInt32 *ponv = &(&prec->onva)[i]; + epicsUInt32 *pnev = &(&prec->neva)[i]; + epicsUInt32 onv = *ponv; /* Num Elements in OVLx */ + epicsUInt32 nev = *pnev; /* Num Elements in VALx */ + epicsUInt32 alen = dbValueSize((&prec->ftva)[i]) * nev; + + if (nev != onv || memcmp(povl, pval, alen)) { memcpy(povl, pval, alen); db_post_events(prec, pval, monitor_mask); + if (nev != onv) { + *ponv = nev; + db_post_events(prec, pnev, monitor_mask); + } } } break; case aSubEFLG_ALWAYS: - for (i = 0; i < NUM_ARGS; i++) + for (i = 0; i < NUM_ARGS; i++) { db_post_events(prec, (&prec->vala)[i], monitor_mask); + db_post_events(prec, &(&prec->neva)[i], monitor_mask); + } break; } return; diff --git a/src/rec/aSubRecord.dbd b/src/rec/aSubRecord.dbd index 7c55adea0..23779cd17 100644 --- a/src/rec/aSubRecord.dbd +++ b/src/rec/aSubRecord.dbd @@ -1049,127 +1049,148 @@ recordtype(aSub) { prompt("Old Output A") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovla") + interest(4) + extra("void *ovla") } field(OVLB,DBF_NOACCESS) { prompt("Old Output B") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlb") + interest(4) + extra("void *ovlb") } field(OVLC,DBF_NOACCESS) { prompt("Old Output C") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlc") + interest(4) + extra("void *ovlc") } field(OVLD,DBF_NOACCESS) { prompt("Old Output D") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovld") + interest(4) + extra("void *ovld") } field(OVLE,DBF_NOACCESS) { prompt("Old Output E") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovle") + interest(4) + extra("void *ovle") } field(OVLF,DBF_NOACCESS) { prompt("Old Output F") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlf") + interest(4) + extra("void *ovlf") } field(OVLG,DBF_NOACCESS) { prompt("Old Output G") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlg") + interest(4) + extra("void *ovlg") } field(OVLH,DBF_NOACCESS) { prompt("Old Output H") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlh") + interest(4) + extra("void *ovlh") } field(OVLI,DBF_NOACCESS) { prompt("Old Output I") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovli") + interest(4) + extra("void *ovli") } field(OVLJ,DBF_NOACCESS) { prompt("Old Output J") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlj") + interest(4) + extra("void *ovlj") } field(OVLK,DBF_NOACCESS) { prompt("Old Output K") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlk") + interest(4) + extra("void *ovlk") } field(OVLL,DBF_NOACCESS) { prompt("Old Output L") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovll") + interest(4) + extra("void *ovll") } field(OVLM,DBF_NOACCESS) { prompt("Old Output M") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlm") + interest(4) + extra("void *ovlm") } field(OVLN,DBF_NOACCESS) { prompt("Old Output N") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovln") + interest(4) + extra("void *ovln") } field(OVLO,DBF_NOACCESS) { prompt("Old Output O") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlo") + interest(4) + extra("void *ovlo") } field(OVLP,DBF_NOACCESS) { prompt("Old Output P") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlp") + interest(4) + extra("void *ovlp") } field(OVLQ,DBF_NOACCESS) { prompt("Old Output Q") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlq") + interest(4) + extra("void *ovlq") } field(OVLR,DBF_NOACCESS) { prompt("Old Output R") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlr") + interest(4) + extra("void *ovlr") } field(OVLS,DBF_NOACCESS) { prompt("Old Output S") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovls") + interest(4) + extra("void *ovls") } field(OVLT,DBF_NOACCESS) { prompt("Old Output T") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlt") + interest(4) + extra("void *ovlt") } field(OVLU,DBF_NOACCESS) { prompt("Old Output U") asl(ASL0) special(SPC_NOMOD) - interest(4) extra("void *ovlu") + interest(4) + extra("void *ovlu") } field(FTVA,DBF_MENU) { prompt("Type of VALA") @@ -1488,149 +1509,254 @@ recordtype(aSub) { } field(NEVA,DBF_ULONG) { prompt("Num. elements in VALA") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVB,DBF_ULONG) { prompt("Num. elements in VALB") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVC,DBF_ULONG) { prompt("Num. elements in VALC") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVD,DBF_ULONG) { prompt("Num. elements in VALD") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVE,DBF_ULONG) { prompt("Num. elements in VALE") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVF,DBF_ULONG) { prompt("Num. elements in VALF") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVG,DBF_ULONG) { prompt("Num. elements in VALG") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVH,DBF_ULONG) { prompt("Num. elements in VAlH") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVI,DBF_ULONG) { prompt("Num. elements in VALI") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVJ,DBF_ULONG) { prompt("Num. elements in VALJ") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVK,DBF_ULONG) { prompt("Num. elements in VALK") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVL,DBF_ULONG) { prompt("Num. elements in VALL") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVM,DBF_ULONG) { prompt("Num. elements in VALM") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVN,DBF_ULONG) { prompt("Num. elements in VALN") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVO,DBF_ULONG) { prompt("Num. elements in VALO") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVP,DBF_ULONG) { prompt("Num. elements in VALP") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVQ,DBF_ULONG) { prompt("Num. elements in VALQ") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVR,DBF_ULONG) { prompt("Num. elements in VALR") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVS,DBF_ULONG) { prompt("Num. elements in VALS") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVT,DBF_ULONG) { prompt("Num. elements in VALT") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } field(NEVU,DBF_ULONG) { prompt("Num. elements in VALU") - promptgroup(GUI_WAVE) special(SPC_NOMOD) interest(3) initial("1") } + field(ONVA,DBF_ULONG) { + prompt("Num. elements in OVLA") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVB,DBF_ULONG) { + prompt("Num. elements in OVLB") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVC,DBF_ULONG) { + prompt("Num. elements in OVLC") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVD,DBF_ULONG) { + prompt("Num. elements in OVLD") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVE,DBF_ULONG) { + prompt("Num. elements in OVLE") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVF,DBF_ULONG) { + prompt("Num. elements in OVLF") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVG,DBF_ULONG) { + prompt("Num. elements in OVLG") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVH,DBF_ULONG) { + prompt("Num. elements in VAlH") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVI,DBF_ULONG) { + prompt("Num. elements in OVLI") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVJ,DBF_ULONG) { + prompt("Num. elements in OVLJ") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVK,DBF_ULONG) { + prompt("Num. elements in OVLK") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVL,DBF_ULONG) { + prompt("Num. elements in OVLL") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVM,DBF_ULONG) { + prompt("Num. elements in OVLM") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVN,DBF_ULONG) { + prompt("Num. elements in OVLN") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVO,DBF_ULONG) { + prompt("Num. elements in OVLO") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVP,DBF_ULONG) { + prompt("Num. elements in OVLP") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVQ,DBF_ULONG) { + prompt("Num. elements in OVLQ") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVR,DBF_ULONG) { + prompt("Num. elements in OVLR") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVS,DBF_ULONG) { + prompt("Num. elements in OVLS") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVT,DBF_ULONG) { + prompt("Num. elements in OVLT") + special(SPC_NOMOD) + interest(4) + initial("1") + } + field(ONVU,DBF_ULONG) { + prompt("Num. elements in OVLU") + special(SPC_NOMOD) + interest(4) + initial("1") + } } From 7cac267a4bd67288eceb8e12dd5d4c66673305db Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 11 Oct 2012 18:10:00 -0500 Subject: [PATCH 4/5] db: Fix possible error handling in dbPut --- src/db/dbAccess.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c index 22f4e20e7..94f8a1b79 100644 --- a/src/db/dbAccess.c +++ b/src/db/dbAccess.c @@ -1442,8 +1442,9 @@ long epicsShareAPI dbPut(DBADDR *paddr, short dbrType, else offset = 0; if (no_elements < nRequest) nRequest = no_elements; - status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer, - nRequest, no_elements, offset); + if (!status) + status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer, + nRequest, no_elements, offset); /* update array info */ if (!status && From e889336458c85d69a8d55fc0f51e7f3dc95f9924 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 17 Oct 2012 18:08:39 -0500 Subject: [PATCH 5/5] db: Undefined alarm limits should return NaN Where the record doesn't provide get_alarm_double() or for fields where the default applies, we were still returning 0. --- src/db/dbAccess.c | 70 +++++++++++------------ src/db/recGbl.c | 140 ++++++++++++++++++++++------------------------ 2 files changed, 98 insertions(+), 112 deletions(-) diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c index 94f8a1b79..d3e47062c 100644 --- a/src/db/dbAccess.c +++ b/src/db/dbAccess.c @@ -27,6 +27,7 @@ #include "errlog.h" #include "cantProceed.h" #include "cvtFast.h" +#include "epicsMath.h" #include "epicsTime.h" #include "alarm.h" #include "ellLib.h" @@ -281,48 +282,41 @@ static void get_control(DBADDR *paddr, char **ppbuffer, } static void get_alarm(DBADDR *paddr, char **ppbuffer, - struct rset *prset,long *options) + struct rset *prset, long *options) { - struct dbr_alDouble ald; - int got_data=FALSE; + char *pbuffer = *ppbuffer; + struct dbr_alDouble ald = {epicsNAN, epicsNAN, epicsNAN, epicsNAN}; + long no_data = TRUE; - ald.upper_alarm_limit = ald.upper_warning_limit = 0.0; - ald.lower_warning_limit = ald.lower_alarm_limit = 0.0; - if( prset && prset->get_alarm_double ) { - (*prset->get_alarm_double)(paddr,&ald); - got_data=TRUE; - } - if( (*options) & (DBR_AL_LONG) ) { - char *pbuffer=*ppbuffer; + if (prset && prset->get_alarm_double) + no_data = prset->get_alarm_double(paddr, &ald); - if(got_data) { - struct dbr_alLong *pal=(struct dbr_alLong*)pbuffer; - pal->upper_alarm_limit = (epicsInt32)ald.upper_alarm_limit; - pal->upper_warning_limit = (epicsInt32)ald.upper_warning_limit; - pal->lower_warning_limit = (epicsInt32)ald.lower_warning_limit; - pal->lower_alarm_limit = (epicsInt32)ald.lower_alarm_limit; - } else { - memset(pbuffer,'\0',dbr_alLong_size); - *options = (*options) ^ DBR_AL_LONG; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_alLong_size; - } - if( (*options) & (DBR_AL_DOUBLE) ) { - char *pbuffer=*ppbuffer; + if (*options & DBR_AL_LONG) { + struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer; - if(got_data) { - struct dbr_alDouble *pal=(struct dbr_alDouble*)pbuffer; - pal->upper_alarm_limit = ald.upper_alarm_limit; - pal->upper_warning_limit = ald.upper_warning_limit; - pal->lower_warning_limit = ald.lower_warning_limit; - pal->lower_alarm_limit = ald.lower_alarm_limit; - } else { - memset(pbuffer,'\0',dbr_alDouble_size); - *options = (*options) ^ DBR_AL_DOUBLE; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_alDouble_size; - } - return; + pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit; + pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit; + pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit; + pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit; + + if (no_data) + *options ^= DBR_AL_LONG; /*Turn off option*/ + + *ppbuffer += dbr_alLong_size; + } + if (*options & DBR_AL_DOUBLE) { + struct dbr_alDouble *pal = (struct dbr_alDouble*) pbuffer; + + pal->upper_alarm_limit = ald.upper_alarm_limit; + pal->upper_warning_limit = ald.upper_warning_limit; + pal->lower_warning_limit = ald.lower_warning_limit; + pal->lower_alarm_limit = ald.lower_alarm_limit; + + if (no_data) + *options ^= DBR_AL_DOUBLE; /*Turn off option*/ + + *ppbuffer += dbr_alDouble_size; + } } static void getOptions(DBADDR *paddr,char **poriginal,long *options,void *pflin) diff --git a/src/db/recGbl.c b/src/db/recGbl.c index 7cdf69a19..2d58c9dab 100644 --- a/src/db/recGbl.c +++ b/src/db/recGbl.c @@ -21,6 +21,7 @@ #include #include "dbDefs.h" +#include "epicsMath.h" #include "epicsTime.h" #include "epicsPrint.h" #include "dbBase.h" @@ -107,64 +108,56 @@ void epicsShareAPI recGblRecSupError(long status, const struct dbAddr *paddr, return; } -void epicsShareAPI recGblGetPrec(const struct dbAddr *paddr,long *precision) +void epicsShareAPI recGblGetPrec(const struct dbAddr *paddr, long *precision) { dbFldDes *pdbFldDes = paddr->pfldDes; - switch(pdbFldDes->field_type){ - case(DBF_SHORT): - *precision = 0; - break; - case(DBF_USHORT): - *precision = 0; - break; - case(DBF_LONG): - *precision = 0; - break; - case(DBF_ULONG): - *precision = 0; - break; - case(DBF_FLOAT): - case(DBF_DOUBLE): - if(*precision<0 || *precision>15) *precision=15; - break; + switch (pdbFldDes->field_type) { + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_USHORT: + case DBF_LONG: + case DBF_ULONG: + *precision = 0; + break; + + case DBF_FLOAT: + case DBF_DOUBLE: + if (*precision < 0 || *precision > 15) + *precision = 15; + break; + default: break; } - return; } -void epicsShareAPI recGblGetGraphicDouble( - const struct dbAddr *paddr,struct dbr_grDouble *pgd) +void epicsShareAPI recGblGetGraphicDouble(const struct dbAddr *paddr, + struct dbr_grDouble *pgd) { dbFldDes *pdbFldDes = paddr->pfldDes; - getMaxRangeValues(pdbFldDes->field_type,&pgd->upper_disp_limit, - &pgd->lower_disp_limit); - - return; + getMaxRangeValues(pdbFldDes->field_type, + &pgd->upper_disp_limit, &pgd->lower_disp_limit); } -void epicsShareAPI recGblGetAlarmDouble( - const struct dbAddr *paddr,struct dbr_alDouble *pad) +void epicsShareAPI recGblGetAlarmDouble(const struct dbAddr *paddr, + struct dbr_alDouble *pad) { - pad->upper_alarm_limit = 0; - pad->upper_warning_limit = 0; - pad->lower_warning_limit = 0; - pad->lower_alarm_limit = 0; - - return; + pad->upper_alarm_limit = epicsNAN; + pad->upper_warning_limit = epicsNAN; + pad->lower_warning_limit = epicsNAN; + pad->lower_alarm_limit = epicsNAN; } -void epicsShareAPI recGblGetControlDouble( - const struct dbAddr *paddr,struct dbr_ctrlDouble *pcd) +void epicsShareAPI recGblGetControlDouble(const struct dbAddr *paddr, + struct dbr_ctrlDouble *pcd) { - dbFldDes *pdbFldDes=paddr->pfldDes; + dbFldDes *pdbFldDes = paddr->pfldDes; - getMaxRangeValues(pdbFldDes->field_type,&pcd->upper_ctrl_limit, - &pcd->lower_ctrl_limit); - - return; + getMaxRangeValues(pdbFldDes->field_type, + &pcd->upper_ctrl_limit, &pcd->lower_ctrl_limit); } int epicsShareAPI recGblInitConstantLink( @@ -319,40 +312,39 @@ static void getMaxRangeValues(short field_type, double *pupper_limit, double *plower_limit) { switch(field_type){ - case(DBF_CHAR): - *pupper_limit = -128.0; - *plower_limit = 127.0; - break; - case(DBF_UCHAR): - *pupper_limit = 255.0; - *plower_limit = 0.0; - break; - case(DBF_SHORT): - *pupper_limit = (double)SHRT_MAX; - *plower_limit = (double)SHRT_MIN; - break; - case(DBF_ENUM): - case(DBF_USHORT): - *pupper_limit = (double)USHRT_MAX; - *plower_limit = (double)0; - break; - case(DBF_LONG): - /* long did not work using cast to double */ - *pupper_limit = 2147483647.; - *plower_limit = -2147483648.; - break; - case(DBF_ULONG): - *pupper_limit = (double)ULONG_MAX; - *plower_limit = (double)0; - break; - case(DBF_FLOAT): - *pupper_limit = (double)1e+30; - *plower_limit = (double)-1e30; - break; - case(DBF_DOUBLE): - *pupper_limit = (double)1e+30; - *plower_limit = (double)-1e30; - break; + case DBF_CHAR: + *pupper_limit = -128.0; + *plower_limit = 127.0; + break; + case DBF_UCHAR: + *pupper_limit = 255.0; + *plower_limit = 0.0; + break; + case DBF_SHORT: + *pupper_limit = (double) SHRT_MAX; + *plower_limit = (double) SHRT_MIN; + break; + case DBF_ENUM: + case DBF_USHORT: + *pupper_limit = (double) USHRT_MAX; + *plower_limit = 0.0; + break; + case DBF_LONG: + *pupper_limit = 2147483647.0; + *plower_limit = -2147483648.0; + break; + case DBF_ULONG: + *pupper_limit = (double) 0xffffffffU; + *plower_limit = 0.0; + break; + case DBF_FLOAT: + *pupper_limit = 1e30; + *plower_limit = -1e30; + break; + case DBF_DOUBLE: + *pupper_limit = 1e300; + *plower_limit = -1e300; + break; } return; }