From 990ba62e0be51fe76eb8aeab5dc221c1f8c334df Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Fri, 3 Apr 2009 20:54:00 +0000 Subject: [PATCH] Added support for new MSI and MSS link flags --- documentation/RELEASE_NOTES.html | 13 ++++++++++++ src/db/dbAccess.c | 35 ++++++++++++++++++++++---------- src/db/dbAccessDefs.h | 6 ++++-- src/db/dbCa.c | 13 +++++++++--- src/db/dbCa.h | 8 +++++--- src/db/dbCaPvt.h | 3 ++- src/db/dbLock.c | 3 ++- src/dbStatic/dbStaticLib.c | 34 +++++++++++++++++++------------ src/dbStatic/link.h | 26 ++++++++++++++---------- 9 files changed, 96 insertions(+), 45 deletions(-) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 484edbbc6..56ec64251 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -12,6 +12,19 @@

Changes between 3.14.10 and 3.14.11

+

New link flags for alarm severity/status inheritance

+ +

Two new link flags have been introduced: MSI (maximize severity INVALID) +and MSS (maximize severity and status).

+ +

Through a link flagged as MSI the receiver side inherits the severity +(similar to the MS flag), but only if it is INVALID.

+ +

Through a link flagged as MSS the receiver side inherits as well the +severity (similar to the MS flag) as the alarm status, thereby preserving +the alarm status through MS chains instead of setting the status to LINK +unconditionally.

+

New behaviour of get_alarm_double() in analog records

The behavior of get_alarm_double() in several record types, which diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c index db2cdaa42..641f2905d 100644 --- a/src/db/dbAccess.c +++ b/src/db/dbAccess.c @@ -90,6 +90,17 @@ static short mapDBFToDBR[DBF_NTYPES] = { /* The following is to handle SPC_AS */ static SPC_ASCALLBACK spcAsCallback = 0; +static void inherit_severity(const struct pv_link *ppv_link, + dbCommon *pdest, epicsEnum16 stat, epicsEnum16 sevr) +{ + switch(ppv_link->pvlMask&pvlOptMsMode) { + case pvlOptNMS: break; + case pvlOptMSI: if (sevr < INVALID_ALARM) break; + case pvlOptMS: recGblSetSevr(pdest,LINK_ALARM,sevr); break; + case pvlOptMSS: recGblSetSevr(pdest,stat,sevr); break; + } +} + void epicsShareAPI dbSpcAsRegisterCallback(SPC_ASCALLBACK func) { spcAsCallback = func; @@ -837,8 +848,9 @@ long epicsShareAPI dbGetLinkValue(struct link *plink, short dbrType, precord->pact = pact; if (status) return status; } - if (ppv_link->pvlMask & pvlOptMS && precord != paddr->precord) - recGblSetSevr(precord, LINK_ALARM, paddr->precord->sevr); + if(precord!= paddr->precord) { + inherit_severity(ppv_link,precord,paddr->precord->stat,paddr->precord->sevr); + } if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) { status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); @@ -873,13 +885,13 @@ long epicsShareAPI dbGetLinkValue(struct link *plink, short dbrType, } else if (plink->type == CA_LINK) { struct dbCommon *precord = plink->value.pv_link.precord; const struct pv_link *pcalink = &plink->value.pv_link; - unsigned short sevr; + epicsEnum16 sevr, stat; - status = dbCaGetLink(plink, dbrType, pbuffer, &sevr, pnRequest); + status=dbCaGetLink(plink,dbrType,pbuffer,&stat,&sevr,pnRequest); if (status) { recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM); - } else if (pcalink->pvlMask & pvlOptMS) { - recGblSetSevr(precord, LINK_ALARM, sevr); + } else { + inherit_severity(pcalink,precord,stat,sevr); } if (poptions) *poptions = 0; } else { @@ -900,8 +912,7 @@ long epicsShareAPI dbPutLinkValue(struct link *plink, short dbrType, dbCommon *pdest = paddr->precord; status = dbPut(paddr, dbrType, pbuffer, nRequest); - if (ppv_link->pvlMask & pvlOptMS) - recGblSetSevr(pdest, LINK_ALARM, psource->nsev); + inherit_severity(ppv_link,pdest,psource->nsta,psource->nsev); if (status) return status; if (paddr->pfield == (void *)&pdest->proc || @@ -1567,14 +1578,16 @@ long epicsShareAPI dbGetUnits( return(0); } -long epicsShareAPI dbGetSevr(const struct link *plink,short *severity) +long epicsShareAPI dbGetAlarm(const struct link *plink, + epicsEnum16 *status,epicsEnum16 *severity) { DBADDR *paddr; - if(plink->type == CA_LINK) return(dbCaGetSevr(plink,severity)); + if(plink->type == CA_LINK) return(dbCaGetAlarm(plink,status,severity)); if(plink->type !=DB_LINK) return(S_db_notFound); paddr = (DBADDR *)plink->value.pv_link.pvt; - *severity = paddr->precord->sevr; + if (status) *status = paddr->precord->stat; + if (severity) *severity = paddr->precord->sevr; return(0); } diff --git a/src/db/dbAccessDefs.h b/src/db/dbAccessDefs.h index b4997c60b..15f7d49a4 100644 --- a/src/db/dbAccessDefs.h +++ b/src/db/dbAccessDefs.h @@ -215,6 +215,8 @@ struct dbr_alDouble {DBRalDouble}; ( ( (PLNK)->type != DB_LINK ) \ ? 0 \ : ( ( (struct dbAddr *)( (PLNK)->value.pv_link.pvt) ) ) ) +#define dbGetSevr(PLINK,PSEVERITY) \ + dbGetAlarm((PLINK),NULL,(PSEVERITY)); epicsShareFunc long epicsShareAPI dbPutSpecial(struct dbAddr *paddr,int pass); epicsShareFunc struct rset * epicsShareAPI dbGetRset(const struct dbAddr *paddr); @@ -262,8 +264,8 @@ epicsShareFunc long epicsShareAPI dbGetPrecision( const struct link *plink,short *precision); epicsShareFunc long epicsShareAPI dbGetUnits( const struct link *plink,char *units,int unitsSize); -epicsShareFunc long epicsShareAPI dbGetSevr( - const struct link *plink,short *severity); +epicsShareFunc long epicsShareAPI dbGetAlarm( + const struct link *plink, epicsEnum16 *status,epicsEnum16 *severity); epicsShareFunc long epicsShareAPI dbGetTimeStamp( const struct link *plink,epicsTimeStamp *pstamp); diff --git a/src/db/dbCa.c b/src/db/dbCa.c index cb18171ea..a62e09ea0 100644 --- a/src/db/dbCa.c +++ b/src/db/dbCa.c @@ -246,7 +246,7 @@ void epicsShareAPI dbCaRemoveLink(struct link *plink) } long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest, - unsigned short *psevr,long *nelements) + epicsEnum16 *pstat, epicsEnum16 *psevr, long *nelements) { caLink *pca = (caLink *)plink->value.pv_link.pvt; long status = 0; @@ -258,6 +258,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest, assert(pca->plink); if (!pca->isConnected || !pca->hasReadAccess) { pca->sevr = INVALID_ALARM; + pca->stat = LINK_ALARM; status = -1; goto done; } @@ -271,6 +272,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest, } if (!pca->gotInString) { pca->sevr = INVALID_ALARM; + pca->stat = LINK_ALARM; status = -1; goto done; } @@ -285,6 +287,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest, } if (!pca->gotInNative){ pca->sevr = INVALID_ALARM; + pca->stat = LINK_ALARM; status = -1; goto done; } @@ -315,6 +318,7 @@ long epicsShareAPI dbCaGetLink(struct link *plink,short dbrType, void *pdest, aConvert(&dbAddr, pdest, ntoget, ntoget, 0); } done: + if (pstat) *pstat = pca->stat; if (psevr) *psevr = pca->sevr; if (link_action) addAction(pca, link_action); epicsMutexUnlock(pca->lock); @@ -423,12 +427,14 @@ long epicsShareAPI dbCaGetNelements(const struct link *plink, long *nelements) return 0; } -long epicsShareAPI dbCaGetSevr(const struct link *plink, short *severity) +long epicsShareAPI dbCaGetAlarm(const struct link *plink, + epicsEnum16 *pstat, epicsEnum16 *psevr) { caLink *pca; pcaGetCheck - *severity = pca->sevr; + if (pstat) *pstat = pca->stat; + if (psevr) *psevr = pca->sevr; epicsMutexUnlock(pca->lock); return 0; } @@ -677,6 +683,7 @@ static void eventCallback(struct event_handler_args arg) } pdbr_time_double = (struct dbr_time_double *)arg.dbr; pca->sevr = pdbr_time_double->severity; + pca->stat = pdbr_time_double->status; memcpy(&pca->timeStamp, &pdbr_time_double->stamp, sizeof(epicsTimeStamp)); if (precord) { struct pv_link *ppv_link = &plink->value.pv_link; diff --git a/src/db/dbCa.h b/src/db/dbCa.h index c919c18de..d4a37819d 100644 --- a/src/db/dbCa.h +++ b/src/db/dbCa.h @@ -33,7 +33,7 @@ epicsShareFunc void epicsShareAPI dbCaAddLinkCallback(struct link *plink, epicsShareFunc void epicsShareAPI dbCaRemoveLink(struct link *plink); epicsShareFunc long epicsShareAPI dbCaGetLink( struct link *plink,short dbrType,void *pbuffer, - unsigned short *psevr,long *nRequest); + epicsEnum16 *pstat,epicsEnum16 *psevr,long *nRequest); epicsShareFunc long epicsShareAPI dbCaPutLinkCallback( struct link *plink,short dbrType,const void *pbuffer,long nRequest, dbCaCallback callback,void *userPvt); @@ -43,8 +43,10 @@ epicsShareFunc int epicsShareAPI dbCaIsLinkConnected(const struct link *plink); /* The following are available after the link is connected*/ epicsShareFunc long epicsShareAPI dbCaGetNelements( const struct link *plink,long *nelements); -epicsShareFunc long epicsShareAPI dbCaGetSevr( - const struct link *plink,short *severity); +#define dbCaGetSevr(plink,severity) \ + dbCaGetAlarm((plink),NULL,(severity)) +epicsShareFunc long epicsShareAPI dbCaGetAlarm(const struct link *plink, + epicsEnum16 *status,epicsEnum16 *severity); epicsShareFunc long epicsShareAPI dbCaGetTimeStamp( const struct link *plink,epicsTimeStamp *pstamp); epicsShareFunc int epicsShareAPI dbCaGetLinkDBFtype(const struct link *plink); diff --git a/src/db/dbCaPvt.h b/src/db/dbCaPvt.h index cc6999736..9625bfbd6 100644 --- a/src/db/dbCaPvt.h +++ b/src/db/dbCaPvt.h @@ -40,7 +40,8 @@ typedef struct caLink chid chid; short link_action; /* The following have new values after each data event*/ - unsigned short sevr; + epicsEnum16 sevr; + epicsEnum16 stat; epicsTimeStamp timeStamp; /* The following have values after connection*/ short dbrType; diff --git a/src/db/dbLock.c b/src/db/dbLock.c index 8f29c8469..65befe8d7 100644 --- a/src/db/dbLock.c +++ b/src/db/dbLock.c @@ -82,6 +82,7 @@ static ELLLIST lockSetList[nlistType]; static epicsMutexId globalLock; static epicsMutexId lockSetModifyLock; static unsigned long id = 0; +static char *msstring[4]={"NMS","MS","MSI","MSS"}; typedef enum { lockSetStateFree=0, lockSetStateScanLock, lockSetStateRecordLock @@ -546,7 +547,7 @@ long epicsShareAPI dblsr(char *recordname,int level) } printf(" %s %s", ((plink->value.pv_link.pvlMask&pvlOptPP)?" PP":"NPP"), - ((plink->value.pv_link.pvlMask&pvlOptMS)?" MS":"NMS")); + msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]); printf(" %s\n",pdbAddr->precord->name); } } diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c index b9063e520..b13912cc6 100644 --- a/src/dbStatic/dbStaticLib.c +++ b/src/dbStatic/dbStaticLib.c @@ -48,7 +48,7 @@ static char *pNullString = ""; #define RPCL_LEN 184 static char *ppstring[5]={"NPP","PP","CA","CP","CPP"}; -static char *msstring[2]={"NMS","MS"}; +static char *msstring[4]={"NMS","MS","MSI","MSS"}; epicsShareDef maplinkType pamaplinkType[LINK_NTYPES] = { {"CONSTANT",CONSTANT}, @@ -91,7 +91,7 @@ static char *promptCONSTANT[] = { static char *promptINLINK[] = { " PV Name:", "NPP PP CA CP CPP:", - " NMS or MS:"}; + " NMS MS MSI MSS:"}; static char *promptOUTLINK[] = { " PV Name:", "NPP PP CA:", @@ -2032,7 +2032,7 @@ char * epicsShareAPI dbGetString(DBENTRY *pdbentry) strcat(message," "); strcat(message,ppstring[ppind]); strcat(message," "); - strcat(message,msstring[pvlMask&pvlOptMS]); + strcat(message,msstring[pvlMask&pvlOptMsMode]); break; } case VME_IO: @@ -2290,8 +2290,10 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring) else if(strstr(end,"CA")) ppOpt = pvlOptCA; else if(strstr(end,"CP")) ppOpt = pvlOptCP; else ppOpt = 0; - if(strstr(end,"NMS")) msOpt = 0; - else if(strstr(end,"MS")) msOpt = pvlOptMS; + if(strstr(end,"NMS")) msOpt = pvlOptNMS; + else if(strstr(end,"MSI")) msOpt = pvlOptMSI; + else if(strstr(end,"MSS")) msOpt = pvlOptMSS; +/*must be the last one:*/ else if(strstr(end,"MS")) msOpt = pvlOptMS; else msOpt = 0; *end = 0; } @@ -2301,8 +2303,10 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring) else if(strstr(end,"PP")) ppOpt = pvlOptPP; else if(strstr(end,"CA")) ppOpt = pvlOptCA; else ppOpt = 0; - if(strstr(end,"NMS")) msOpt = 0; - else if(strstr(end,"MS")) msOpt = pvlOptMS; + if(strstr(end,"NMS")) msOpt = pvlOptNMS; + else if(strstr(end,"MSI")) msOpt = pvlOptMSI; + else if(strstr(end,"MSS")) msOpt = pvlOptMSS; +/*must be the last one:*/ else if(strstr(end,"MS")) msOpt = pvlOptMS; else msOpt = 0; *end = 0; } @@ -3104,8 +3108,7 @@ char ** epicsShareAPI dbGetFormValue(DBENTRY *pdbentry) else if(pvlMask&pvlOptCPP) strcpy(*value,"CPP"); else strcpy(*value,"NPP"); value++; - if(pvlMask&pvlOptMS) strcpy(*value,"MS"); - else strcpy(*value,"NMS"); + strcpy(*value, msstring[pvlMask&pvlOptMsMode]); value++; } break; @@ -3121,8 +3124,7 @@ char ** epicsShareAPI dbGetFormValue(DBENTRY *pdbentry) else if(pvlMask&pvlOptCA) strcpy(*value,"CA"); else strcpy(*value,"NPP"); value++; - if(pvlMask&pvlOptMS) strcpy(*value,"MS"); - else strcpy(*value,"NMS"); + strcpy(*value, msstring[pvlMask&pvlOptMsMode]); value++; } break; @@ -3295,7 +3297,10 @@ long epicsShareAPI dbPutForm(DBENTRY *pdbentry,char **value) value++; verify++; **verify = 0; /*Initialize verify to NULL*/ if((*value==NULL) || (strcmp(*value,"")==0)) msOpt = 0; - else if(strstr(*value,"NMS")) msOpt = 0; + else if(strstr(*value,"NMS")) msOpt = pvlOptNMS; + else if(strstr(*value,"MSI")) msOpt = pvlOptMSI; + else if(strstr(*value,"MSS")) msOpt = pvlOptMSS; + /*must be the last one:*/ else if(strstr(*value,"MS")) msOpt = pvlOptMS; else strcpy(*verify,"Illegal. Chose a value"); dbCopyEntryContents(pdbentry,plinkentry); @@ -3329,7 +3334,10 @@ long epicsShareAPI dbPutForm(DBENTRY *pdbentry,char **value) value++; verify++; **verify = 0; /*Initialize verify to NULL*/ if((*value==NULL) || (strcmp(*value,"")==0)) msOpt = 0; - else if(strstr(*value,"NMS")) msOpt = 0; + else if(strstr(*value,"NMS")) msOpt = pvlOptNMS; + else if(strstr(*value,"MSI")) msOpt = pvlOptMSI; + else if(strstr(*value,"MSS")) msOpt = pvlOptMSS; + /*must be the last one:*/ else if(strstr(*value,"MS")) msOpt = pvlOptMS; else strcpy(*verify,"Illegal. Chose a value"); dbCopyEntryContents(pdbentry,plinkentry); diff --git a/src/dbStatic/link.h b/src/dbStatic/link.h index fb8c97512..a43c5711e 100644 --- a/src/dbStatic/link.h +++ b/src/dbStatic/link.h @@ -54,17 +54,21 @@ epicsShareExtern maplinkType pamaplinkType[]; /* structure of a PV_LINK DB_LINK and a CA_LINK */ /*Options defined by pvlMask */ -#define pvlOptMS 0x1 /*Maximize Severity*/ -#define pvlOptPP 0x2 /*Process Passive*/ -#define pvlOptCA 0x4 /*Always make it a CA link*/ -#define pvlOptCP 0x8 /*CA + process on monitor*/ -#define pvlOptCPP 0x10 /*CA + process passive record on monitor*/ -#define pvlOptFWD 0x20 /*Generate ca_put for forward link*/ -#define pvlOptInpNative 0x40 /*Input native*/ -#define pvlOptInpString 0x80 /*Input as string*/ -#define pvlOptOutNative 0x100 /*Output native*/ -#define pvlOptOutString 0x200 /*Output as string*/ -#define pvlOptTSELisTime 0x400 /*Field TSEL is getting timeStamp*/ +#define pvlOptMsMode 0x3 /*Maximize Severity mode selection*/ +#define pvlOptNMS 0 /*Dont Maximize Severity*/ +#define pvlOptMS 1 /*Maximize Severity allways*/ +#define pvlOptMSI 2 /*Maximize Severity if INVALID*/ +#define pvlOptMSS 3 /*Maximize Severity and copy Status*/ +#define pvlOptPP 0x4 /*Process Passive*/ +#define pvlOptCA 0x8 /*Always make it a CA link*/ +#define pvlOptCP 0x10 /*CA + process on monitor*/ +#define pvlOptCPP 0x20 /*CA + process passive record on monitor*/ +#define pvlOptFWD 0x40 /*Generate ca_put for forward link*/ +#define pvlOptInpNative 0x80 /*Input native*/ +#define pvlOptInpString 0x100 /*Input as string*/ +#define pvlOptOutNative 0x200 /*Output native*/ +#define pvlOptOutString 0x400 /*Output as string*/ +#define pvlOptTSELisTime 0x800 /*Field TSEL is getting timeStamp*/ typedef long (*LINKCVT)();