Added support for new MSI and MSS link flags

This commit is contained in:
Ralph Lange
2009-04-03 20:54:00 +00:00
parent 2e8595f17f
commit 990ba62e0b
9 changed files with 96 additions and 45 deletions
+13
View File
@@ -12,6 +12,19 @@
<h2 align="center">Changes between 3.14.10 and 3.14.11</h2>
<!-- Insert new items below here ... -->
<h4>New link flags for alarm severity/status inheritance</h4>
<p>Two new link flags have been introduced: MSI (maximize severity INVALID)
and MSS (maximize severity and status).</p>
<p>Through a link flagged as MSI the receiver side inherits the severity
(similar to the MS flag), but only if it is INVALID.</p>
<p>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.</p>
<h4>New behaviour of get_alarm_double() in analog records</h4>
<p>The behavior of get_alarm_double() in several record types, which
+24 -11
View File
@@ -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);
}
+4 -2
View File
@@ -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);
+10 -3
View File
@@ -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;
+5 -3
View File
@@ -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);
+2 -1
View File
@@ -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;
+2 -1
View File
@@ -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);
}
}
+21 -13
View File
@@ -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);
+15 -11
View File
@@ -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)();