Merge branch '7.0'
This commit is contained in:
@@ -805,7 +805,7 @@ int dbLoadRecords(const char* file, const char* subs)
|
||||
if(dbLoadRecordsHook)
|
||||
dbLoadRecordsHook(file, subs);
|
||||
} else {
|
||||
fprintf(stderr, ERL_ERROR " failed to load '%s'\n", file);
|
||||
fprintf(stderr, ERL_ERROR ": Failed to load '%s'\n", file);
|
||||
if(status==-2)
|
||||
fprintf(stderr, " Records cannot be loaded after iocInit!\n");
|
||||
}
|
||||
@@ -1095,7 +1095,7 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
return S_db_badDbrtype;
|
||||
}
|
||||
|
||||
status = dbParseLink(pstring, pfldDes->field_type, &link_info);
|
||||
status = dbParseLink(pstring, pfldDes->field_type, &link_info, precord->name, pfldDes->name);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
||||
@@ -557,6 +557,40 @@ static void event_remove ( struct event_que *ev_que,
|
||||
pevent->npend--;
|
||||
}
|
||||
|
||||
/* synchronize with worker thread.
|
||||
*
|
||||
* On return, any previously pending events or extra labor have been handled.
|
||||
*
|
||||
* caller must lock evUser->lock
|
||||
*/
|
||||
static
|
||||
void db_sync_event (struct event_user * const evUser)
|
||||
{
|
||||
/* grab current cycle counter, then wait for it to change */
|
||||
epicsUInt32 curSeq = evUser->pflush_seq;
|
||||
event_waiter wait;
|
||||
wait.wake = epicsEventCreate(epicsEventEmpty); /* failure allowed */
|
||||
|
||||
ellAdd(&evUser->waiters, &wait.node);
|
||||
do {
|
||||
epicsMutexUnlock( evUser->lock );
|
||||
/* ensure worker will cycle at least once */
|
||||
epicsEventMustTrigger(evUser->ppendsem);
|
||||
|
||||
if(wait.wake) {
|
||||
epicsEventMustWait(wait.wake);
|
||||
} else {
|
||||
epicsThreadSleep(0.01); /* ick. but better than cantProceed() */
|
||||
}
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
} while(curSeq == evUser->pflush_seq);
|
||||
ellDelete(&evUser->waiters, &wait.node);
|
||||
/* destroy under lock to ensure epicsEventMustTrigger() has returned */
|
||||
if(wait.wake)
|
||||
epicsEventDestroy(wait.wake);
|
||||
}
|
||||
|
||||
/*
|
||||
* DB_CANCEL_EVENT()
|
||||
*
|
||||
@@ -594,34 +628,9 @@ void db_cancel_event (dbEventSubscription event)
|
||||
UNLOCKEVQUE (que);
|
||||
|
||||
if(sync) {
|
||||
/* cycle through worker */
|
||||
struct event_user *evUser = que->evUser;
|
||||
epicsUInt32 curSeq;
|
||||
event_waiter wait;
|
||||
wait.wake = epicsEventCreate(epicsEventEmpty); /* may fail */
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
ellAdd(&evUser->waiters, &wait.node);
|
||||
/* grab current cycle counter, then wait for it to change */
|
||||
curSeq = evUser->pflush_seq;
|
||||
do {
|
||||
epicsMutexUnlock( evUser->lock );
|
||||
/* ensure worker will cycle at least once */
|
||||
epicsEventMustTrigger(evUser->ppendsem);
|
||||
|
||||
if(wait.wake) {
|
||||
epicsEventMustWait(wait.wake);
|
||||
} else {
|
||||
epicsThreadSleep(0.01); /* ick. but better than cantProceed() */
|
||||
}
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
} while(curSeq == evUser->pflush_seq);
|
||||
ellDelete(&evUser->waiters, &wait.node);
|
||||
/* destroy under lock to ensure epicsEventMustTrigger() has returned */
|
||||
if(wait.wake)
|
||||
epicsEventDestroy(wait.wake);
|
||||
epicsMutexUnlock( evUser->lock );
|
||||
epicsMutexMustLock ( que->evUser->lock );
|
||||
db_sync_event(que->evUser);
|
||||
epicsMutexUnlock( que->evUser->lock );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,10 +644,10 @@ void db_flush_extra_labor_event (dbEventCtx ctx)
|
||||
struct event_user * const evUser = (struct event_user *) ctx;
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
while ( evUser->extraLaborBusy ) {
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
epicsThreadSleep(0.1);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
if ( evUser->extraLaborBusy || (evUser->extra_labor && evUser->extralabor_sub) ) {
|
||||
db_sync_event(evUser);
|
||||
// At this point, original labor completed.
|
||||
// Do not wait for any additional labor queued afterwards.
|
||||
}
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
}
|
||||
@@ -1027,9 +1036,7 @@ static void event_task (void *pParm)
|
||||
* labor to this task
|
||||
*/
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->extraLaborBusy = TRUE;
|
||||
if ( evUser->extra_labor && evUser->extralabor_sub ) {
|
||||
evUser->extra_labor = FALSE;
|
||||
pExtraLaborSub = evUser->extralabor_sub;
|
||||
pExtraLaborArg = evUser->extralabor_arg;
|
||||
}
|
||||
@@ -1037,12 +1044,14 @@ static void event_task (void *pParm)
|
||||
pExtraLaborSub = NULL;
|
||||
pExtraLaborArg = NULL;
|
||||
}
|
||||
evUser->extra_labor = FALSE;
|
||||
if ( pExtraLaborSub ) {
|
||||
evUser->extraLaborBusy = TRUE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
(*pExtraLaborSub)(pExtraLaborArg);
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->extraLaborBusy = FALSE;
|
||||
}
|
||||
evUser->extraLaborBusy = FALSE;
|
||||
|
||||
for ( ev_que = &evUser->firstque; ev_que; ev_que = ev_que->nextque ) {
|
||||
/* unlock during iteration is safe as event_que will not be free'd */
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "errSymTbl.h"
|
||||
#include "iocshRegisterCommon.h"
|
||||
|
||||
#define DBR_NAME(dbrType) (VALID_DB_REQ(dbrType) ? pamapdbfType[dbrType].strvalue+3 : "???")
|
||||
|
||||
static dbEventCtx testEvtCtx;
|
||||
static epicsMutexId testEvtLock;
|
||||
static ELLLIST testEvtList; /* holds testMonitor::node */
|
||||
@@ -153,8 +155,8 @@ long testdbVPutField(const char* pv, short dbrType, va_list ap)
|
||||
OP(DBR_ENUM, int, enum16);
|
||||
#undef OP
|
||||
default:
|
||||
testFail("invalid DBR: dbPutField(\"%s\", %d, ...)",
|
||||
dbChannelName(chan), dbrType);
|
||||
testFail("invalid DBR: dbPutField(\"%s\", DBR%s, ...)",
|
||||
dbChannelName(chan), DBR_NAME(dbrType));
|
||||
ret = S_db_badDbrtype;
|
||||
break;
|
||||
}
|
||||
@@ -174,7 +176,8 @@ void testdbPutFieldOk(const char* pv, int dbrType, ...)
|
||||
ret = testdbVPutField(pv, dbrType, ap);
|
||||
va_end(ap);
|
||||
|
||||
testOk(ret==0, "dbPutField(\"%s\", %d, ...) -> %#lx (%s)", pv, dbrType, ret, errSymMsg(ret));
|
||||
testOk(ret==0, "dbPutField(\"%s\", DBR%s, ...) -> %#lx (%s)",
|
||||
pv, DBR_NAME(dbrType), ret, errSymMsg(ret));
|
||||
}
|
||||
|
||||
void testdbPutFieldFail(long status, const char* pv, int dbrType, ...)
|
||||
@@ -186,8 +189,8 @@ void testdbPutFieldFail(long status, const char* pv, int dbrType, ...)
|
||||
ret = testdbVPutField(pv, dbrType, ap);
|
||||
va_end(ap);
|
||||
|
||||
testOk(ret==status, "dbPutField(\"%s\", %d, ...) -> %#lx (%s) == %#lx (%s)",
|
||||
pv, dbrType, status, errSymMsg(status), ret, errSymMsg(ret));
|
||||
testOk(ret==status, "dbPutField(\"%s\", DBR%s, ...) -> %#lx (%s) == %#lx (%s)",
|
||||
pv, DBR_NAME(dbrType), status, errSymMsg(status), ret, errSymMsg(ret));
|
||||
}
|
||||
|
||||
void testdbGetFieldEqual(const char* pv, int dbrType, ...)
|
||||
@@ -213,10 +216,12 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
|
||||
|
||||
status = dbChannelGetField(chan, dbrType, pod.bytes, NULL, &nReq, NULL);
|
||||
if (status) {
|
||||
testFail("dbGetField(\"%s\", %d, ...) -> %#lx (%s)", pv, dbrType, status, errSymMsg(status));
|
||||
testFail("dbGetField(\"%s\", DBR%s, ...) -> %#lx (%s)",
|
||||
pv, DBR_NAME(dbrType), status, errSymMsg(status));
|
||||
goto done;
|
||||
} else if(nReq==0) {
|
||||
testFail("dbGetField(\"%s\", %d, ...) -> zero length", pv, dbrType);
|
||||
testFail("dbGetField(\"%s\", DBR%s, ...) -> zero length",
|
||||
pv, DBR_NAME(dbrType));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -224,13 +229,14 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
|
||||
case DBR_STRING: {
|
||||
const char *expect = va_arg(ap, char*);
|
||||
testOk(strcmp(expect, pod.valStr)==0,
|
||||
"dbGetField(\"%s\", %d) -> \"%s\" == \"%s\"",
|
||||
pv, dbrType, expect, pod.valStr);
|
||||
"dbGetField(\"%s\", DBR%s) -> \"%s\" == \"%s\"",
|
||||
pv, DBR_NAME(dbrType), expect, pod.valStr);
|
||||
break;
|
||||
}
|
||||
#define OP(DBR,Type,mem,pat) case DBR: {Type expect = va_arg(ap,Type); \
|
||||
testOk(expect==pod.val.mem, "dbGetField(\"%s\", %d) -> " pat " == " pat, \
|
||||
pv, dbrType, expect, (Type)pod.val.mem); break;}
|
||||
testOk(expect==pod.val.mem||((expect!=expect)&&(pod.val.mem!=pod.val.mem)), \
|
||||
"dbGetField(\"%s\", DBR%s) -> " pat " == " pat, \
|
||||
pv, DBR_NAME(dbrType), expect, (Type)pod.val.mem); break;}
|
||||
|
||||
OP(DBR_CHAR, int, int8, "%d");
|
||||
OP(DBR_UCHAR, int, uInt8, "%d");
|
||||
@@ -240,12 +246,12 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
|
||||
OP(DBR_ULONG, unsigned int, uInt32, "%u");
|
||||
OP(DBR_INT64, long long, int64, "%lld");
|
||||
OP(DBR_UINT64, unsigned long long, uInt64, "%llu");
|
||||
OP(DBR_FLOAT, double, float32, "%e");
|
||||
OP(DBR_DOUBLE, double, float64, "%e");
|
||||
OP(DBR_ENUM, int, enum16, "%d");
|
||||
OP(DBR_FLOAT, double, float32, "%g");
|
||||
OP(DBR_DOUBLE, double, float64, "%g");
|
||||
#undef OP
|
||||
default:
|
||||
testFail("dbGetField(\"%s\", %d) -> unsupported dbf", pv, dbrType);
|
||||
testFail("dbGetField(\"%s\", DBR%s) -> unsupported dbf", pv, DBR_NAME(dbrType));
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -265,7 +271,7 @@ void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long count, con
|
||||
|
||||
status = dbChannelPutField(chan, dbrType, pbuf, count);
|
||||
|
||||
testOk(status==0, "dbPutField(\"%s\", dbr=%d, count=%lu, ...) -> %ld", pv, dbrType, count, status);
|
||||
testOk(status==0, "dbPutField(\"%s\", DBR%s, count=%lu, ...) -> %ld", pv, DBR_NAME(dbrType), count, status);
|
||||
|
||||
done:
|
||||
if(chan)
|
||||
@@ -294,7 +300,7 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
|
||||
|
||||
status = dbChannelGetField(chan, dbfType, gbuf, NULL, &nRequest, NULL);
|
||||
if (status) {
|
||||
testFail("dbGetField(\"%s\", %d, ...) -> %#lx", pv, dbfType, status);
|
||||
testFail("dbGetField(\"%s\", DBR%s, ...) -> %#lx", pv, DBR_NAME(dbfType), status);
|
||||
|
||||
} else {
|
||||
unsigned match = nRequest==cnt;
|
||||
@@ -327,14 +333,14 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
|
||||
OP(DBR_ULONG, unsigned int, "%u");
|
||||
OP(DBR_INT64, long long, "%lld");
|
||||
OP(DBR_UINT64, unsigned long long, "%llu");
|
||||
OP(DBR_FLOAT, float, "%e");
|
||||
OP(DBR_DOUBLE, double, "%e");
|
||||
OP(DBR_FLOAT, float, "%g");
|
||||
OP(DBR_DOUBLE, double, "%g");
|
||||
OP(DBR_ENUM, int, "%d");
|
||||
#undef OP
|
||||
}
|
||||
}
|
||||
|
||||
testOk(match, "dbGetField(\"%s\", dbrType=%d, nRequest=%ld ...) match", pv, dbfType, nRequest);
|
||||
testOk(match, "dbGetField(\"%s\", DBR%s, nRequest=%ld ...) match", pv, DBR_NAME(dbfType), nRequest);
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -428,6 +434,17 @@ void testMonitorWait(testMonitor *mon)
|
||||
}
|
||||
}
|
||||
|
||||
static void dummylabor(void* unused) {(void)unused;}
|
||||
|
||||
void testMonitorSync(testMonitor *mon)
|
||||
{
|
||||
// db_flush_extra_labor_event() only blocks if there is actual labor pending
|
||||
(void)db_add_extra_labor_event(testEvtCtx, dummylabor, NULL);
|
||||
(void)db_post_extra_labor(testEvtCtx);
|
||||
db_flush_extra_labor_event(testEvtCtx);
|
||||
(void)db_add_extra_labor_event(testEvtCtx, NULL, NULL);
|
||||
}
|
||||
|
||||
unsigned testMonitorCount(testMonitor *mon, unsigned reset)
|
||||
{
|
||||
unsigned count;
|
||||
|
||||
@@ -139,21 +139,45 @@ DBCORE_API dbCommon* testdbRecordPtr(const char* pv);
|
||||
|
||||
typedef struct testMonitor testMonitor;
|
||||
|
||||
/** Setup monitoring the named PV for changes */
|
||||
/** Setup monitoring the named PV for changes
|
||||
*
|
||||
* @param[in] pvname Requested PV name. Must be valid for dbChannelCreate().
|
||||
* @param[in] dbe_mask A bitwise or of DBE_VALUE and friends.
|
||||
* @param[in] opt Currently unused. Set to zero.
|
||||
* @returns Newly allocated testMonitor object, which caller must testMonitorDestroy()
|
||||
*
|
||||
* Calls testAbort() on failure. Will never return NULL.
|
||||
*
|
||||
* @since 3.16.0.1
|
||||
*/
|
||||
DBCORE_API testMonitor* testMonitorCreate(const char* pvname, unsigned dbe_mask, unsigned opt);
|
||||
/** Stop monitoring */
|
||||
/** Stop monitoring
|
||||
*
|
||||
* @since 3.16.0.1
|
||||
*/
|
||||
DBCORE_API void testMonitorDestroy(testMonitor*);
|
||||
/** Return immediately if it has been updated since create, last wait,
|
||||
* or reset (count w/ reset=1).
|
||||
* Otherwise, block until the value of the target PV is updated.
|
||||
*
|
||||
* @since 3.16.0.1
|
||||
*/
|
||||
DBCORE_API void testMonitorWait(testMonitor*);
|
||||
/** Synchronize with dbEvent working for subscription.
|
||||
*
|
||||
* On return, any updates previously posted for this subscriptions have been delivered.
|
||||
*
|
||||
* @since UNRELEASED
|
||||
*/
|
||||
DBCORE_API void testMonitorSync(testMonitor*);
|
||||
/** Return the number of monitor events which have occured since create,
|
||||
* or a previous reset (called reset=1).
|
||||
* Calling w/ reset=0 only returns the count.
|
||||
* Calling w/ reset=1 resets the count to zero and ensures that the next
|
||||
* wait will block unless subsequent events occur. Returns the previous
|
||||
* count.
|
||||
*
|
||||
* @since 3.16.0.1
|
||||
*/
|
||||
DBCORE_API unsigned testMonitorCount(testMonitor*, unsigned reset);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbStaticPvt.h"
|
||||
#include "epicsExport.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "link.h"
|
||||
#include "special.h"
|
||||
#include "iocInit.h"
|
||||
@@ -237,6 +238,8 @@ static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
errlogInit(0); /* Initialize the errSymTable */
|
||||
|
||||
if(*ppdbbase == 0) *ppdbbase = dbAllocBase();
|
||||
savedPdbbase = *ppdbbase;
|
||||
if(path && strlen(path)>0) {
|
||||
@@ -351,14 +354,18 @@ cleanup:
|
||||
return(status);
|
||||
}
|
||||
|
||||
long dbReadDatabase(DBBASE **ppdbbase,const char *filename,
|
||||
const char *path,const char *substitutions)
|
||||
{return (dbReadCOM(ppdbbase,filename,0,path,substitutions));}
|
||||
long dbReadDatabase(DBBASE **ppdbbase, const char *filename,
|
||||
const char *path, const char *substitutions)
|
||||
{
|
||||
return dbReadCOM(ppdbbase, filename, 0, path, substitutions);
|
||||
}
|
||||
|
||||
long dbReadDatabaseFP(DBBASE **ppdbbase, FILE *fp,
|
||||
const char *path, const char *substitutions)
|
||||
{
|
||||
return dbReadCOM(ppdbbase, 0, fp, path, substitutions);
|
||||
}
|
||||
|
||||
long dbReadDatabaseFP(DBBASE **ppdbbase,FILE *fp,
|
||||
const char *path,const char *substitutions)
|
||||
{return (dbReadCOM(ppdbbase,0,fp,path,substitutions));}
|
||||
|
||||
static int db_yyinput(char *buf, int max_size)
|
||||
{
|
||||
size_t l,n;
|
||||
@@ -1190,6 +1197,37 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
dbVisibleRecord(pdbentry);
|
||||
}
|
||||
|
||||
/* For better suggestions for wrong field names
|
||||
the following array contains pairs of often
|
||||
confused fields. Thus, the number of elements
|
||||
must be even.
|
||||
For the last character, ranges like A-F are
|
||||
allowed as a shortcut. Pairs must have matching
|
||||
range size.
|
||||
If extending this map, please add only field names
|
||||
found in record types from base.
|
||||
Each array element (i.e. both sides of a pair)
|
||||
is tested against the faulty field name.
|
||||
The first match (considering ranges) where the
|
||||
other side of the pair is an existing field name
|
||||
(after adjusting for ranges) will be suggested
|
||||
as a replacement.
|
||||
If no such match is found, the suggestion falls
|
||||
back to weighted lexical similarity with existing
|
||||
field names.
|
||||
*/
|
||||
|
||||
static const char* const dbFieldConfusionMap [] = {
|
||||
"INP","OUT",
|
||||
"DOL","INP",
|
||||
"ZNAM","ZRST",
|
||||
"ONAM","ONST",
|
||||
"INPA-J","DOL0-9",
|
||||
"INPK-P","DOLA-F",
|
||||
"INP0-9","INPA-J"
|
||||
};
|
||||
STATIC_ASSERT(NELEMENTS(dbFieldConfusionMap)%2==0);
|
||||
|
||||
static void dbRecordField(char *name,char *value)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
@@ -1206,18 +1244,140 @@ static void dbRecordField(char *name,char *value)
|
||||
dbGetRecordTypeName(pdbentry), dbGetRecordName(pdbentry), name);
|
||||
if(dbGetRecordName(pdbentry)) {
|
||||
DBENTRY temp;
|
||||
double bestSim = -1.0;
|
||||
const dbFldDes *bestFld = NULL;
|
||||
int i;
|
||||
dbCopyEntryContents(pdbentry, &temp);
|
||||
for(status = dbFirstField(&temp, 0); !status; status = dbNextField(&temp, 0)) {
|
||||
double sim = epicsStrSimilarity(name, temp.pflddes->name);
|
||||
if(!bestFld || sim > bestSim) {
|
||||
bestSim = sim;
|
||||
for(i = 0; i < NELEMENTS(dbFieldConfusionMap); i++) {
|
||||
const char* fieldname = dbFieldConfusionMap[i];
|
||||
const char* replacement = dbFieldConfusionMap[i^1]; /* swap even with odd indices */
|
||||
const char* guess = NULL;
|
||||
char buf[8]; /* no field name is so long */
|
||||
size_t l = strlen(fieldname);
|
||||
if (l >= 3 && fieldname[l-2] == '-' &&
|
||||
strncmp(name, fieldname, l-3) == 0 &&
|
||||
name[l-3] >= fieldname[l-3] &&
|
||||
name[l-3] <= fieldname[l-1])
|
||||
{
|
||||
/* range map (like XXXA-Z) */
|
||||
size_t l2 = strlen(replacement);
|
||||
strncpy(buf, replacement, sizeof(buf)-1);
|
||||
buf[l2-3] += name[l-3] - fieldname[l-3];
|
||||
buf[l2-2] = 0;
|
||||
guess = buf;
|
||||
} else if (strcmp(name, fieldname) == 0) {
|
||||
/* simple map */
|
||||
guess = replacement;
|
||||
}
|
||||
if (guess && dbFindFieldPart(&temp, &guess) == 0) {
|
||||
/* guessed field exists */
|
||||
bestFld = temp.pflddes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bestFld) {
|
||||
/* no map found, use weighted lexical similarity
|
||||
the weights are a bit arbitrary */
|
||||
double bestSim = -1.0;
|
||||
char quote = 0;
|
||||
if (*value == '"' || *value == '\'')
|
||||
quote = *value++;
|
||||
for (status = dbFirstField(&temp, 0); !status; status = dbNextField(&temp, 0)) {
|
||||
if (temp.pflddes->special == SPC_NOMOD ||
|
||||
temp.pflddes->special == SPC_DBADDR) /* cannot be configured */
|
||||
continue;
|
||||
double sim = epicsStrSimilarity(name, temp.pflddes->name);
|
||||
if (!temp.pflddes->promptgroup)
|
||||
sim *= 0.5; /* no prompt: unlikely */
|
||||
if (temp.pflddes->interest)
|
||||
sim *= 1.0 - 0.1 * temp.pflddes->interest; /* 10% less likely per interest level */
|
||||
if (sim == 0)
|
||||
continue;
|
||||
if (*value != quote) {
|
||||
/* value given, check match to field type */
|
||||
long status = 0;
|
||||
char* end = "e;
|
||||
|
||||
switch (temp.pflddes->field_type) {
|
||||
epicsAny dummy;
|
||||
case DBF_CHAR:
|
||||
status = epicsParseInt8(value, &dummy.int8, 0, &end);
|
||||
break;
|
||||
case DBF_UCHAR:
|
||||
status = epicsParseUInt8(value, &dummy.uInt8, 0, &end);
|
||||
break;
|
||||
case DBF_SHORT:
|
||||
status = epicsParseInt16(value, &dummy.int16, 0, &end);
|
||||
break;
|
||||
case DBF_USHORT:
|
||||
case DBF_ENUM:
|
||||
status = epicsParseUInt16(value, &dummy.uInt16, 0, &end);
|
||||
break;
|
||||
case DBF_LONG:
|
||||
status = epicsParseInt32(value, &dummy.int32, 0, &end);
|
||||
break;
|
||||
case DBF_ULONG:
|
||||
status = epicsParseUInt32(value, &dummy.uInt32, 0, &end);
|
||||
break;
|
||||
case DBF_INT64:
|
||||
status = epicsParseInt64(value, &dummy.int64, 0, &end);
|
||||
break;
|
||||
case DBF_UINT64:
|
||||
status = epicsParseUInt64(value, &dummy.uInt64, 0, &end);
|
||||
break;
|
||||
case DBF_FLOAT:
|
||||
status = epicsParseFloat(value, &dummy.float32, &end);
|
||||
break;
|
||||
case DBF_DOUBLE:
|
||||
status = epicsParseDouble(value, &dummy.float64, &end);
|
||||
break;
|
||||
case DBF_MENU:
|
||||
case DBF_DEVICE: {
|
||||
char** choices;
|
||||
int nChoice;
|
||||
int choice;
|
||||
|
||||
if (temp.pflddes->field_type == DBF_MENU) {
|
||||
dbMenu* menu = (dbMenu*)temp.pflddes->ftPvt;
|
||||
choices = menu->papChoiceValue;
|
||||
nChoice = menu->nChoice;
|
||||
} else {
|
||||
dbDeviceMenu* menu = (dbDeviceMenu*)temp.pflddes->ftPvt;
|
||||
choices = menu->papChoice;
|
||||
nChoice = menu->nChoice;
|
||||
}
|
||||
status = epicsParseUInt16(value, &dummy.uInt16, 0, &end);
|
||||
if (!status && *end == quote && dummy.uInt16 < nChoice) {
|
||||
if (temp.pflddes->field_type == DBF_DEVICE)
|
||||
sim *= 0.5; /* numeric device type index is uncommon */
|
||||
break;
|
||||
}
|
||||
for (choice = 0; choice < nChoice; choice++) {
|
||||
size_t len = strlen(choices[choice]);
|
||||
end = value + len;
|
||||
if (strncmp(value, choices[choice], len) == 0 && *end == quote) {
|
||||
sim *= 1.5; /* boost for matching choice string */
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (choice == nChoice)
|
||||
status = S_stdlib_noConversion;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (status || *end != quote)
|
||||
sim *= 0.1; /* value type does not match field type: unlikely */
|
||||
}
|
||||
if (sim > bestSim) {
|
||||
bestSim = sim;
|
||||
bestFld = temp.pflddes;
|
||||
}
|
||||
}
|
||||
}
|
||||
dbFinishEntry(&temp);
|
||||
if(bestSim>0.0) {
|
||||
if (bestFld) {
|
||||
fprintf(stderr, " Did you mean \"%s\"?", bestFld->name);
|
||||
if(bestFld->prompt)
|
||||
fprintf(stderr, " (%s)", bestFld->prompt);
|
||||
|
||||
@@ -2212,7 +2212,7 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
|
||||
if(!plink->text)
|
||||
continue;
|
||||
|
||||
if(dbParseLink(plink->text, pflddes->field_type, &link_info)!=0) {
|
||||
if(dbParseLink(plink->text, pflddes->field_type, &link_info, prec->name, pflddes->name)!=0) {
|
||||
/* This was already parsed once when ->text was set.
|
||||
* Any syntax error messages were printed at that time.
|
||||
*/
|
||||
@@ -2241,7 +2241,7 @@ void dbFreeLinkInfo(dbLinkInfo *pinfo)
|
||||
pinfo->target = NULL;
|
||||
}
|
||||
|
||||
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, const char *recname, const char *fieldname)
|
||||
{
|
||||
char *pstr;
|
||||
size_t len;
|
||||
@@ -2378,7 +2378,13 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
/* filter modifiers based on link type */
|
||||
switch(ftype) {
|
||||
case DBF_INLINK: /* accept all */ break;
|
||||
case DBF_OUTLINK: pinfo->modifiers &= ~pvlOptCPP; break;
|
||||
case DBF_OUTLINK:
|
||||
if(pinfo->modifiers & (pvlOptCPP|pvlOptCP)){
|
||||
errlogPrintf(ERL_WARNING ": Discarding CP/CPP modifier in CA output link from %s.%s to %s.\n",
|
||||
recname, fieldname, pinfo->target);
|
||||
}
|
||||
pinfo->modifiers &= ~(pvlOptCPP|pvlOptCP);
|
||||
break;
|
||||
case DBF_FWDLINK: pinfo->modifiers &= pvlOptCA; break;
|
||||
}
|
||||
}
|
||||
@@ -2616,7 +2622,7 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
dbLinkInfo link_info;
|
||||
DBLINK *plink = (DBLINK *)pfield;
|
||||
|
||||
status = dbParseLink(pstring, pflddes->field_type, &link_info);
|
||||
status = dbParseLink(pstring, pflddes->field_type, &link_info, dbGetRecordName(pdbentry), dbGetFieldName(pdbentry));
|
||||
if (status) break;
|
||||
|
||||
if (plink->type==CONSTANT && plink->value.constantStr==NULL) {
|
||||
@@ -3600,7 +3606,7 @@ void dbReportDeviceConfig(dbBase *pdbbase, FILE *report)
|
||||
if (plink->text) { /* Not yet parsed */
|
||||
dbLinkInfo linfo;
|
||||
|
||||
if (dbParseLink(plink->text, pdbentry->pflddes->field_type, &linfo))
|
||||
if (dbParseLink(plink->text, pdbentry->pflddes->field_type, &linfo, dbGetRecordName(pdbentry), dbGetFieldName(pdbentry)))
|
||||
continue;
|
||||
|
||||
linkType = linfo.ltype;
|
||||
|
||||
@@ -74,7 +74,7 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec);
|
||||
/* Parse link string. no record locks needed.
|
||||
* on success caller must free pinfo->target
|
||||
*/
|
||||
DBCORE_API long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo);
|
||||
DBCORE_API long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, const char *recordname, const char *fieldname);
|
||||
/* Check if link type allow the parsed link value pinfo
|
||||
* to be assigned to the given link.
|
||||
* Record containing plink must be locked.
|
||||
|
||||
@@ -9,7 +9,14 @@
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#if defined(vxWorks) && \
|
||||
(_WRS_VXWORKS_MAJOR+0 <= 6) && (_WRS_VXWORKS_MINOR+0 < 9)
|
||||
typedef int intptr_t;
|
||||
typedef unsigned int uintptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ documentation is now being published.
|
||||
|
||||
=over
|
||||
|
||||
=item * L<Introduction to EPICS|https://docs.epics-controls.org/en/latest/guides/EPICS_Intro.html>
|
||||
=item * L<Introduction to EPICS|https://docs.epics-controls.org/en/latest/getting-started/EPICS_Intro.html>
|
||||
|
||||
=item * L<Process Database Concepts|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html>
|
||||
=item * L<Process Database Concepts|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html>
|
||||
|
||||
=back
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ input links, and returns a double-precision floating-point result. The
|
||||
expression is evaluated by the EPICS Calc engine, and the result is returned as
|
||||
the value of the link.
|
||||
|
||||
Since UNRELEASED the number of inputs has been increased from 12 to 21.
|
||||
|
||||
Two additional expressions may also be provided and are evaluated to determine
|
||||
whether the record owning the link should be placed in alarm state. In both
|
||||
cases the result of the main calculation is available to these expressions as
|
||||
@@ -126,7 +128,7 @@ An optional expression that returns non-zero to raise a minor alarm.
|
||||
|
||||
=item args
|
||||
|
||||
A JSON list of up to 12 input arguments for the expression, which are assigned
|
||||
A JSON list of up to 24 input arguments for the expression, which are assigned
|
||||
to the inputs C<A>, C<B>, C<C>, ... C<U>. Each input argument may be either a
|
||||
numeric literal or an embedded JSON link inside C<{}> braces. The same input
|
||||
values are provided to the two alarm expressions as to the primary expression.
|
||||
|
||||
@@ -198,7 +198,7 @@ Except when it doesn't.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
|
||||
=head3 Output Event Flag
|
||||
|
||||
@@ -319,7 +319,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
@@ -331,19 +331,19 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
@@ -351,6 +351,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
|
||||
@@ -45,7 +45,7 @@ its output. It can be a hardware address, a channel access or database link, or
|
||||
a constant. Only in records that use soft device support can the OUT field be a
|
||||
channel access link, a database link, or a constant. Otherwise, the OUT field
|
||||
must be a hardware address. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of hardware addresses and database links.
|
||||
|
||||
=head4 Fields related to array writing
|
||||
@@ -341,7 +341,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(OUT,DBF_OUTLINK) {
|
||||
prompt("Output Specification")
|
||||
@@ -364,19 +364,19 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
@@ -384,6 +384,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
|
||||
@@ -46,7 +46,7 @@ input data should come from.
|
||||
The format for the INP field value depends on the device support layer that is
|
||||
selected by the DTYP field.
|
||||
See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for a description of the various hardware address formats supported.
|
||||
|
||||
=head3 Units Conversion
|
||||
@@ -212,7 +212,7 @@ positive number of seconds will delay the record going into or out of a minor
|
||||
alarm severity or from minor to major severity until the input signal has been
|
||||
in the alarm range for that number of seconds.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
@@ -265,7 +265,7 @@ monitoring functionality.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(LINR,DBF_MENU) {
|
||||
prompt("Linearization")
|
||||
@@ -294,19 +294,19 @@ monitoring functionality.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(AOFF,DBF_DOUBLE) {
|
||||
prompt("Adjustment Offset")
|
||||
@@ -331,35 +331,35 @@ monitoring functionality.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -367,7 +367,7 @@ monitoring functionality.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -375,7 +375,7 @@ monitoring functionality.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -383,7 +383,7 @@ monitoring functionality.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
|
||||
@@ -162,7 +162,7 @@ OUT field. For analog outputs that write their values to devices, the
|
||||
OUT field must specify the address of the I/O card. In addition, the
|
||||
DTYP field must contain the name of the device support module. Be aware
|
||||
that the address format differs according to the I/O bus used. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of hardware addresses.
|
||||
|
||||
For soft records the output link can be a database link, a channel
|
||||
@@ -328,7 +328,7 @@ for more information on simulation mode and its fields.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(LINR,DBF_MENU) {
|
||||
prompt("Linearization")
|
||||
@@ -357,7 +357,7 @@ for more information on simulation mode and its fields.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(ROFF,DBF_ULONG) {
|
||||
prompt("Raw Offset")
|
||||
@@ -382,26 +382,26 @@ for more information on simulation mode and its fields.
|
||||
promptgroup("30 - Action")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_control_double
|
||||
}
|
||||
field(DRVL,DBF_DOUBLE) {
|
||||
prompt("Drive Low Limit")
|
||||
promptgroup("30 - Action")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_control_double
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double
|
||||
}
|
||||
field(AOFF,DBF_DOUBLE) {
|
||||
prompt("Adjustment Offset")
|
||||
@@ -420,35 +420,35 @@ for more information on simulation mode and its fields.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -456,7 +456,7 @@ for more information on simulation mode and its fields.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -464,7 +464,7 @@ for more information on simulation mode and its fields.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -472,7 +472,7 @@ for more information on simulation mode and its fields.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) #get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
|
||||
@@ -47,13 +47,13 @@ field contains the address from where device support retrieves the value.
|
||||
If the binary input record gets its value from hardware, the address of the
|
||||
card must be entered in the INP field, and the name of the device support
|
||||
module must be entered in the DTYP field. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of the hardware address.
|
||||
|
||||
For records that specify C<Soft Channel> or C<Raw Soft Channel> device
|
||||
support routines, the INP field can be a channel or a database link, or a
|
||||
constant. If a constant, VAL can be changed directly by dbPuts. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of database and
|
||||
channel access addresses. Also, see L<Device Support for Soft Records> in
|
||||
this chapter for information on soft device support.
|
||||
@@ -107,7 +107,7 @@ C<MAJOR>. The ZSV field holds the severity for the zero state; OSV, for
|
||||
the one state. COSV causes an alarm whenever the state changes between
|
||||
0 and 1 and the severity is configured as MINOR or MAJOR.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
@@ -186,7 +186,7 @@ is not equal to VAL.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ONAM,DBF_STRING) {
|
||||
prompt("One Name")
|
||||
@@ -194,7 +194,7 @@ is not equal to VAL.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_Str
|
||||
}
|
||||
field(RVAL,DBF_ULONG) {
|
||||
prompt("Raw Value")
|
||||
|
||||
@@ -45,7 +45,7 @@ continuous control, a database link to a control algorithm record should be
|
||||
entered in the DOL field.
|
||||
|
||||
See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on hardware addresses and links.
|
||||
|
||||
=fields DOL, OMSL
|
||||
@@ -105,13 +105,13 @@ It must specify the address of an I/O card if the record sends its output
|
||||
to hardware, and the DTYP field must contain the corresponding device
|
||||
support module. Be aware that the address format differs according to the
|
||||
I/O bus used. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of hardware addresses.
|
||||
|
||||
Otherwise, if the record is configured to use the soft device support modules,
|
||||
then it can be either a database link, a channel access link, or a constant. Be
|
||||
aware that nothing will be written when OUT is a constant. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of the database and channel access addresses.
|
||||
Also, see L<Device Support For Soft Records> in this chapter for more on output
|
||||
to other records.
|
||||
@@ -239,7 +239,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ONAM,DBF_STRING) {
|
||||
prompt("One Name")
|
||||
@@ -247,7 +247,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(RVAL,DBF_ULONG) {
|
||||
prompt("Raw Value")
|
||||
|
||||
@@ -14,6 +14,8 @@ and logical operations on values retrieved from other records. The result
|
||||
of its operations can then be accessed by another record so that it can
|
||||
then be used.
|
||||
|
||||
Since UNRELEASED the number of inputs has been increased from 12 to 21.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
@@ -35,45 +37,49 @@ These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
=head3 Read Parameters
|
||||
|
||||
The read parameters for the Calc record consist of 21 input links INPA -
|
||||
INPU. The fields can be database links, channel access links, or
|
||||
constants. If they are links, they must specify another record's field or a
|
||||
INPU. The fields can be database links, channel access links, or constants.
|
||||
If they are links, they must specify another record's field or a
|
||||
channel access link. If they are constants, they will be initialized with
|
||||
the value they are configured with and can be changed via C<dbPuts>. They
|
||||
cannot be hardware addresses.
|
||||
|
||||
See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on how to specify database links.
|
||||
|
||||
=fields INPA - INPU
|
||||
|
||||
=head3 Expression
|
||||
|
||||
At the core of the Calc record lies the CALC and RPCL fields. The CALC field
|
||||
contains the infix expresion which the record routine will use when it
|
||||
processes the record. The resulting value is placed in the VAL field and
|
||||
can be accessed from there. The CALC expression is actually converted to
|
||||
opcode and stored as Reverse Polish Notation in the RPCL field. It is this
|
||||
expression which is actually used to calculate VAL. The Reverse Polish
|
||||
expression is evaluated more efficiently during run-time than an infix
|
||||
expression. CALC can be changed at run-time, and a special record routine
|
||||
calls a function to convert it to Reverse Polish Notation.
|
||||
At the core of the Calc record lies the CALC and RPCL fields.
|
||||
The CALC field holds an infix expression to be evaluated whenever the record is
|
||||
processed.
|
||||
The calculated value is placed in the VAL field and can be accessed from there.
|
||||
|
||||
The CALC expression gets compiled into a stream of Reverse Polish Notation (RPN)
|
||||
opcodes for a stack-based machine, and stored in the RPCL field.
|
||||
The RPN opcodes are used to calculate VAL at run-time, and are more efficient
|
||||
than evaluating the infix expression.
|
||||
The CALC expression can be replaced at run-time, triggering a special record
|
||||
routine to compile the new expression into Reverse Polish Notation.
|
||||
|
||||
The infix expressions that can be used are very similar to the C expression
|
||||
syntax, but with some additions and subtle differences in operator meaning
|
||||
and precedence. The string may contain a series of expressions separated by
|
||||
a semi-colon character ";" any one of which may actually provide the
|
||||
calculation result; however, all of the other expressions included must
|
||||
assign their result to a variable. All alphabetic elements described below
|
||||
are case independent, so upper and lower case letters may be used and mixed
|
||||
in the variable and function names as desired. Spaces may be used anywhere
|
||||
within an expression except between characters that make up a single
|
||||
expression element.
|
||||
syntax, but with some additions and subtle differences in operator meaning and
|
||||
precedence.
|
||||
The string may contain a series of expressions separated by a semi-colon
|
||||
character C<;>, any one of which may provide the calculation result.
|
||||
All other expressions included in the string must assign their result to a
|
||||
variable.
|
||||
All alphabetic elements described below are case independent, so upper and lower
|
||||
case letters may be used and mixed in the variable and function names as
|
||||
desired.
|
||||
Spaces may be used anywhere within an expression except between characters that
|
||||
make up a single expression element.
|
||||
|
||||
The range of expressions supported by the calculation record are separated
|
||||
into literals, constants, operands, algebraic operators, trigonometric operators,
|
||||
relational operators, logical operators, the assignment operator,
|
||||
parentheses and commas, and the question mark or '?:' operator.
|
||||
The range of expressions supported by the calculation record are separated into
|
||||
literals, constants, operands, algebraic operators, trigonometric operators,
|
||||
relational operators, logical operators, the assignment operator, parentheses
|
||||
and commas, and the question mark colon or C<?:> operator.
|
||||
|
||||
=fields CALC, RPCL
|
||||
|
||||
@@ -85,10 +91,10 @@ parentheses and commas, and the question mark or '?:' operator.
|
||||
Standard double precision floating point numbers
|
||||
|
||||
=item *
|
||||
Inf: Infinity
|
||||
C<Inf>: Infinity
|
||||
|
||||
=item *
|
||||
Nan: Not a Number
|
||||
C<NaN>: Not a Number
|
||||
|
||||
=back
|
||||
|
||||
@@ -97,14 +103,14 @@ Nan: Not a Number
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
PI: returns the mathematical constant E<pi>
|
||||
C<PI>: returns the mathematical constant E<pi>
|
||||
|
||||
=item *
|
||||
D2R: evaluates to E<pi>/180 which, when used as a multiplier, converts an
|
||||
C<D2R>: evaluates to E<pi>/180 which, when used as a multiplier, converts an
|
||||
angle from degrees to radians
|
||||
|
||||
=item *
|
||||
R2D: evaluates to 180/E<pi> which as a multiplier converts an angle from
|
||||
C<R2D>: evaluates to 180/E<pi> which as a multiplier converts an angle from
|
||||
radians to degrees
|
||||
|
||||
=back
|
||||
@@ -127,112 +133,205 @@ The keyword VAL returns the current contents of the VAL field (which can be
|
||||
written to by a CA put, so it might I<not> be the result from the last time
|
||||
the expression was evaluated).
|
||||
|
||||
=head3 Algebraic Operators
|
||||
=head3 Arithmetic Operators
|
||||
|
||||
Except for unary minus these are infix binary operators.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
ABS: Absolute value (unary)
|
||||
C<+> : Addition
|
||||
|
||||
=item *
|
||||
SQR: Square root (unary)
|
||||
C<-> : Subtraction
|
||||
|
||||
=item *
|
||||
MIN: Minimum (any number of args)
|
||||
C<-> : Minus (unary)
|
||||
|
||||
=item *
|
||||
MAX: Maximum (any number of args)
|
||||
C<*> : Multiplication
|
||||
|
||||
=item *
|
||||
FINITE: returns non-zero if none of the arguments are NaN or Inf (any
|
||||
number of args)
|
||||
C</> : Division
|
||||
|
||||
=item *
|
||||
ISNAN: returns non-zero if any of the arguments is NaN or Inf (any number
|
||||
of args)
|
||||
C<%> : Modulo
|
||||
|
||||
=item *
|
||||
CEIL: Ceiling (unary)
|
||||
C<^> : Exponential
|
||||
|
||||
=item *
|
||||
FLOOR: Floor (unary)
|
||||
|
||||
=item *
|
||||
FMOD: Floating point modulo (binary) Added in 7.0.8
|
||||
|
||||
=item *
|
||||
LOG: Log base 10 (unary)
|
||||
|
||||
=item *
|
||||
LOGE: Natural log (unary)
|
||||
|
||||
=item *
|
||||
LN: Natural log (unary)
|
||||
|
||||
=item *
|
||||
EXP: Exponential function (unary)
|
||||
|
||||
=item *
|
||||
^ : Exponential (binary)
|
||||
|
||||
=item *
|
||||
** : Exponential (binary)
|
||||
|
||||
=item *
|
||||
+ : Addition (binary)
|
||||
|
||||
=item *
|
||||
- : Subtraction (binary)
|
||||
|
||||
=item *
|
||||
* : Multiplication (binary)
|
||||
|
||||
=item *
|
||||
/ : Division (binary)
|
||||
|
||||
=item *
|
||||
% : Modulo (binary)
|
||||
|
||||
=item *
|
||||
NOT: Negate (unary)
|
||||
C<**> : Exponential
|
||||
|
||||
=back
|
||||
|
||||
=head3 Trigonometric Operators
|
||||
=head3 Algebraic Functions
|
||||
|
||||
When functions take more than one argument, a comma separator must appear
|
||||
between them.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
SIN: Sine
|
||||
C<ABS (arg)> : Absolute value
|
||||
|
||||
=item *
|
||||
SINH: Hyperbolic sine
|
||||
C<EXP (arg)> : Exponential function
|
||||
|
||||
=item *
|
||||
ASIN: Arc sine
|
||||
C<FMOD (num, den)> : Floating point modulo. Added in 7.0.8
|
||||
|
||||
=item *
|
||||
COS: Cosine
|
||||
C<LN (arg)> : Natural log
|
||||
|
||||
=item *
|
||||
COSH: Hyperbolic cosine
|
||||
C<LOG (arg)> : Log base 10
|
||||
|
||||
=item *
|
||||
ACOS: Arc cosine
|
||||
C<LOGE (arg)> : Natural log
|
||||
|
||||
=item *
|
||||
TAN: Tangent
|
||||
C<MIN (any number of args)> : Minimum
|
||||
|
||||
=item *
|
||||
TANH: Hyperbolic tangent
|
||||
C<MAX (any number of args)> : Maximum
|
||||
|
||||
=item *
|
||||
ATAN: Arc tangent
|
||||
C<SQR (arg)> : Square root
|
||||
|
||||
=item *
|
||||
C<SQRT (arg)> : Square root
|
||||
|
||||
=back
|
||||
|
||||
=head3 Trigonometric Functions
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<SIN (arg)> : Sine
|
||||
|
||||
=item *
|
||||
C<ASIN (arg)> : Arc sine
|
||||
|
||||
=item *
|
||||
C<COS (arg)> : Cosine
|
||||
|
||||
=item *
|
||||
C<ACOS (arg)> : Arc cosine
|
||||
|
||||
=item *
|
||||
C<TAN (arg)> : Tangent
|
||||
|
||||
=item *
|
||||
C<ATAN (arg)> : Arc tangent
|
||||
|
||||
=item *
|
||||
C<ATAN2 (den, num)> : 2-parameter Arc tangent. Arg's are reversed to ANSI C
|
||||
|
||||
=back
|
||||
|
||||
=head3 Hyperbolic Trigonometry Functions
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<SINH (arg)> : Hyperbolic sine
|
||||
|
||||
=item *
|
||||
C<COSH (arg)> : Hyperbolic cosine
|
||||
|
||||
=item *
|
||||
C<TANH (arg)> : Hyperbolic tangent
|
||||
|
||||
=back
|
||||
|
||||
=head3 Numeric Functions
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<CEIL (arg)> : Ceiling
|
||||
|
||||
=item *
|
||||
C<FLOOR (arg)> : Floor
|
||||
|
||||
=item *
|
||||
C<NINT (arg)> : Round to nearest integer
|
||||
|
||||
=item *
|
||||
C<ISINF (arg)> : returns non-zero if any argument is Inf
|
||||
|
||||
=item *
|
||||
C<ISNAN (any number of args)> : returns non-zero (true) if any argument is NaN
|
||||
or Inf
|
||||
|
||||
=item *
|
||||
C<FINITE (any number of args)> : returns non-zero (true) if none of the
|
||||
arguments are NaN or Inf
|
||||
|
||||
=back
|
||||
|
||||
=head3 Boolean/Logical Operators
|
||||
|
||||
These operators use their arguments as a true (non-zero) or false (zero) value.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<&&> : And, infix binary
|
||||
|
||||
=item *
|
||||
C<||> : Or, infix binary
|
||||
|
||||
=item *
|
||||
C<!> : Not, unary prefix
|
||||
|
||||
=back
|
||||
|
||||
=head3 Bitwise Operators
|
||||
|
||||
Mostly infix binary, the arguments are converted to a 32-bit integer, the
|
||||
operator is applied, and the result converted back into a double.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<&> : Bitwise and
|
||||
|
||||
=item *
|
||||
C<|> : Bitwise or
|
||||
|
||||
=item *
|
||||
C<~> : Bitwise not or one's complement, unary prefix
|
||||
|
||||
=item *
|
||||
C<<< << >>> : Arithmetic shift left
|
||||
|
||||
=item *
|
||||
C<<< >> >>> : Arithmetic shift right
|
||||
|
||||
=item *
|
||||
C<<<< >>> >>>> : Logical shift right
|
||||
|
||||
=item *
|
||||
C<AND> : Bitwise and
|
||||
|
||||
=item *
|
||||
C<OR> : Bitwise or
|
||||
|
||||
=item *
|
||||
C<XOR> : Bitwise exclusive or
|
||||
|
||||
=item *
|
||||
C<NOT> : Bitwise not or one's complement, unary prefix
|
||||
|
||||
=back
|
||||
|
||||
=head3 Relational Operators
|
||||
|
||||
These are all infix binary operators.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
@@ -247,59 +346,17 @@ C<<< <= >>> : Less than or equal to
|
||||
=item *
|
||||
C<<< < >>> : Less than
|
||||
|
||||
=item *
|
||||
C<<< != >>> : Not equal to
|
||||
|
||||
=item *
|
||||
C<<< # >>> : Not equal to
|
||||
|
||||
=item *
|
||||
C<<< = >>> : Equal to
|
||||
|
||||
=back
|
||||
|
||||
=head3 Logical Operators
|
||||
|
||||
=over 1
|
||||
C<<< == >>> : Equal to
|
||||
|
||||
=item *
|
||||
C<&&> : And
|
||||
|
||||
=item *
|
||||
C<||> : Or
|
||||
|
||||
=item *
|
||||
C<!> : Not
|
||||
|
||||
=back
|
||||
|
||||
=head3 Bitwise Operators
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<|> : Bitwise Or
|
||||
|
||||
=item *
|
||||
C<&> : Bitwise And
|
||||
|
||||
=item *
|
||||
OR : Bitwise Or
|
||||
|
||||
=item *
|
||||
AND : Bitwise And
|
||||
|
||||
=item *
|
||||
XOR : Bitwise Exclusive Or
|
||||
|
||||
=item *
|
||||
C<~> : One's Complement
|
||||
|
||||
=item *
|
||||
C<<< << >>> : Arithmetic Left Shift
|
||||
|
||||
=item *
|
||||
C<<< >> >>> : Arithmetic Right Shift
|
||||
|
||||
=item *
|
||||
C<<<< >>> >>>> : Logical Right Shift
|
||||
C<<< = >>> : Equal to (not assignment)
|
||||
|
||||
=back
|
||||
|
||||
@@ -312,24 +369,26 @@ C<:=> : assigns a value (right hand side) to a variable (i.e. field)
|
||||
|
||||
=back
|
||||
|
||||
=head3 Parantheses, Comma, and Semicolon
|
||||
=head3 Parentheses, Comma, and Semicolon
|
||||
|
||||
The open and close parentheses are supported. Nested parentheses are
|
||||
supported.
|
||||
The open C<(> and close parentheses C<)> are supported to override precedence
|
||||
rules in a sub-expression.
|
||||
Nested parentheses are supported to significant depth.
|
||||
|
||||
The comma is supported when used to separate the arguments of a binary
|
||||
function.
|
||||
The comma C<,> is required to separate the arguments of a function.
|
||||
|
||||
The semicolon is used to separate expressions. Although only one
|
||||
traditional calculation expression is allowed, multiple assignment
|
||||
expressions are allowed.
|
||||
The semicolon C<;> is used to value separate expressions.
|
||||
Exactly one value expression must be present, but multiple assignment
|
||||
expressions may be included before and/or after the value expression.
|
||||
|
||||
=head3 Conditional Expression
|
||||
=head3 Conditional Operator
|
||||
|
||||
The C language's question mark operator is supported. The format is:
|
||||
C<condition ? True result : False result>
|
||||
The C language's question mark colon C<?:> ternary operator is supported.
|
||||
The format is:
|
||||
|
||||
=head3 Expression Examples
|
||||
I<condition> C<?> I<true-expression> C<:> I<false-expression>
|
||||
|
||||
=head2 Expression Examples
|
||||
|
||||
=head3 Algebraic
|
||||
|
||||
@@ -370,21 +429,21 @@ Result is C<F + L + 10> if C<<< (A + B) >= (C + D) >>>
|
||||
|
||||
=back
|
||||
|
||||
Prior to Base 3.14.9 it was legal to omit the : and the second (else) part
|
||||
of the conditional, like this:
|
||||
Prior to Base 3.14.9 it was legal to omit the colon C<:> and the second (else)
|
||||
part of the conditional, like this:
|
||||
|
||||
C<(A + B)<(C + D) ? E>
|
||||
C<<< (A + B)<(C + D) ? E >>>
|
||||
|
||||
=over 1
|
||||
|
||||
=item
|
||||
Result is E if (A + B)<(C + D)
|
||||
=item *
|
||||
Result is C<E> if C<<< (A + B)<(C + D) >>>
|
||||
|
||||
=item
|
||||
Result is unchanged if (A + B)>=(C + D)
|
||||
=item *
|
||||
Result is unchanged if C<<< (A + B)>=(C + D) >>>
|
||||
|
||||
From 3.14.9 onwards, this expresion must be written as
|
||||
C<(A + B) < (C + D) ? E : VAL>
|
||||
C<<< (A + B) < (C + D) ? E : VAL >>>
|
||||
|
||||
=back
|
||||
|
||||
@@ -406,7 +465,7 @@ Convert A to integer
|
||||
Convert B to integer
|
||||
|
||||
=item *
|
||||
Bitwise And A and B
|
||||
Bitwise A C<and> B
|
||||
|
||||
=item *
|
||||
Convert result to floating point
|
||||
@@ -465,7 +524,7 @@ reporting of limit alarms until the signal has been within the alarm range for
|
||||
that number of seconds (the default AFTC value of zero retains the previous
|
||||
behavior).
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
@@ -634,60 +693,60 @@ manner for the VAL field.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Rng")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_dpuble, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_dpuble, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -695,7 +754,7 @@ manner for the VAL field.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -703,7 +762,7 @@ manner for the VAL field.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -711,7 +770,7 @@ manner for the VAL field.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(AFTC, DBF_DOUBLE) {
|
||||
@@ -1018,23 +1077,25 @@ Routine process implements the following algorithm:
|
||||
=over 1
|
||||
|
||||
=item 1.
|
||||
|
||||
Fetch all arguments.
|
||||
|
||||
=item 2.
|
||||
|
||||
Call routine C<calcPerform>, which calculates VAL from the postfix version of
|
||||
the expression given in CALC. If C<calcPerform> returns success UDF is set to
|
||||
FALSE.
|
||||
|
||||
=item 3.
|
||||
|
||||
Check alarms. This routine checks to see if the new VAL causes the alarm
|
||||
status and severity to change. If so, NSEV, NSTA, and LALM are set. It also
|
||||
honors the alarm hysteresis factor (HYST). Thus the value must change by
|
||||
at least HYST before the alarm status and severity changes.
|
||||
|
||||
=item 4.
|
||||
Check to see if monitors should be invoked.
|
||||
|
||||
=back
|
||||
Check to see if monitors should be invoked.
|
||||
|
||||
=over 1
|
||||
|
||||
@@ -1053,9 +1114,8 @@ NSEV and NSTA are reset to 0.
|
||||
|
||||
=back
|
||||
|
||||
=over
|
||||
|
||||
=item 5.
|
||||
|
||||
Scan forward link if necessary, set PACT FALSE, and return.
|
||||
|
||||
=back
|
||||
|
||||
@@ -20,6 +20,8 @@ rather than the DBF_STRING fields used in the Wait record. For new
|
||||
databases, it is recommended that the Calcout record be used instead of the
|
||||
Wait record.
|
||||
|
||||
Since UNRELEASED the number of inputs has been increased from 12 to 21.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
@@ -58,8 +60,8 @@ These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
=head3 Read Parameters
|
||||
|
||||
The read parameters for the Calcout record consists of 21 input links INPA -
|
||||
INPU. The fields can be database links, channel access links, or
|
||||
constants. If they are links, they must specify another record's field. If
|
||||
INPU. The fields can be database links, channel access links, or constants.
|
||||
If they are links, they must specify another record's field. If
|
||||
they are constants, they will be initialized with the value they are
|
||||
configured with and can be changed via C<dbPuts>. These fields cannot be
|
||||
hardware addresses. In addition, the Calcout record contains the INAV -
|
||||
@@ -70,38 +72,45 @@ fields.
|
||||
|
||||
=fields INPA - INPU
|
||||
|
||||
=head3 Expression
|
||||
=head3 Expressions
|
||||
|
||||
Like the Calc record, the Calcout record has a CALC field in which the
|
||||
developer can enter an infix expression which the record routine will
|
||||
evaluate when it processes the record. The resulting value is placed in the
|
||||
VAL field. This value can then be used by the OOPT field (see
|
||||
L<Output Parameters>) to determine whether or not to write to the output
|
||||
link or post an output event. It can also be the value that is written to
|
||||
the output link. The CALC expression is actually converted to opcode and
|
||||
stored in Reverse Polish Notation in the RPCL field. It is this expression
|
||||
which is actually used to calculate VAL. The Reverse Polish expression is
|
||||
evaluated more efficiently during run-time than an infix expression. CALC
|
||||
can be changes at run-time, and a special record routine will call a
|
||||
function to convert it to Reverse Polish Notation.
|
||||
Like the Calc record, the Calcout record's CALC field holds an infix expression
|
||||
to be evaluated whenever the record is processed.
|
||||
The resulting value is placed in the VAL field.
|
||||
|
||||
The OOPT field condition is applied to VAL (see L<Output Parameters>) and
|
||||
controls whether to write to the output link (or post a named event), and the
|
||||
DOPT field selects whether VAL should be written, or another expression from
|
||||
the OCAL field should be evaluated and used instead.
|
||||
|
||||
The CALC and OCAL expressions get compiled into streams of Reverse Polish
|
||||
Notation (RPN) opcodes for a stack-based machine, and stored in the RPCL and
|
||||
ORPC fields respectively.
|
||||
|
||||
The RPN opcodes are used to calculate VAL at run-time, and are more efficient
|
||||
than evaluating the infix expression.
|
||||
The CALC and OCAL expressions can be replaced at run-time, triggering a special
|
||||
record routine to compile the new expression into Reverse Polish Notation.
|
||||
|
||||
The infix expressions that can be used are very similar to the C expression
|
||||
syntax, but with some additions and subtle differences in operator meaning
|
||||
and precedence. The string may contain a series of expressions separated by
|
||||
a semi-colon character ';' any one of which may actually provide the
|
||||
calculation result; however all of the other expressions included must
|
||||
assign their result to a variable. All alphabetic elements described below
|
||||
are case independent, so upper and lower case letters may be used and mixed
|
||||
in the variable and function names as desired. Spaces may be used anywhere
|
||||
within an expression except between the characters that make up a single
|
||||
expression element.
|
||||
syntax, but with some additions and subtle differences in operator meaning and
|
||||
precedence.
|
||||
The string may contain a series of expressions separated by a semi-colon
|
||||
character C<;>, any one of which may provide the calculation result.
|
||||
All other expressions included in the string must assign their result to a
|
||||
variable.
|
||||
All alphabetic elements described below are case independent, so upper and lower
|
||||
case letters may be used and mixed in the variable and function names as
|
||||
desired.
|
||||
Spaces may be used anywhere within an expression except between characters that
|
||||
make up a single expression element.
|
||||
|
||||
The range of expressions supported by the calculation record are separated into
|
||||
literals, constants, operands, algebraic operators, trigonometric operators,
|
||||
relational operators, logical operator, the assignment operator,
|
||||
parentheses and commas, and the question mark or '?:' operator.
|
||||
relational operators, logical operators, the assignment operator, parentheses
|
||||
and commas, and the question mark colon or C<?:> operator.
|
||||
|
||||
=fields CALC, VAL, RPCL
|
||||
=fields CALC, VAL, OVAL, RPCL, ORPC
|
||||
|
||||
=head3 Literals
|
||||
|
||||
@@ -111,10 +120,10 @@ parentheses and commas, and the question mark or '?:' operator.
|
||||
Standard double precision floating point numbers
|
||||
|
||||
=item *
|
||||
Inf: Infinity
|
||||
C<Inf>: Infinity
|
||||
|
||||
=item *
|
||||
Nan: Not a Number
|
||||
C<NaN>: Not a Number
|
||||
|
||||
=back
|
||||
|
||||
@@ -123,14 +132,14 @@ Nan: Not a Number
|
||||
=over
|
||||
|
||||
=item *
|
||||
PI: returns the mathematical constant E<pi>
|
||||
C<PI>: returns the mathematical constant E<pi>
|
||||
|
||||
=item *
|
||||
D2R: evaluates to E<pi>/180 which, when used as a multiplier, converts an
|
||||
C<D2R>: evaluates to E<pi>/180 which, when used as a multiplier, converts an
|
||||
angle from degrees to radians
|
||||
|
||||
=item *
|
||||
R2D: evaluates to 180/E<pi> which, when used as a multiplier, converts an
|
||||
C<R2D>: evaluates to 180/E<pi> which, when used as a multiplier, converts an
|
||||
angle from radians to degrees
|
||||
|
||||
=back
|
||||
@@ -153,112 +162,205 @@ field, i.e. the VAL field for the CALC expression and the OVAL field for
|
||||
the OCAL expression. (These fields can be written to by CA put, so it might
|
||||
I<not> be the result from the last time the expression was evaluated).
|
||||
|
||||
=head3 Algebraic Operations
|
||||
=head3 Arithmetic Operators
|
||||
|
||||
Except for unary minus these are infix binary operators.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
ABS: Absolute value (unary)
|
||||
C<+> : Addition
|
||||
|
||||
=item *
|
||||
SQR: Square root (unary)
|
||||
C<-> : Subtraction
|
||||
|
||||
=item *
|
||||
MIN: Minimum (any number of args)
|
||||
C<-> : Minus (unary)
|
||||
|
||||
=item *
|
||||
MAX: Maximum (any number of args)
|
||||
C<*> : Multiplication
|
||||
|
||||
=item *
|
||||
FINITE: returns non-zero if none of the arguments are NaN or Inf (any
|
||||
number of args)
|
||||
C</> : Division
|
||||
|
||||
=item *
|
||||
ISNAN: returns non-zero if any of the arguments is NaN or Inf (any number
|
||||
of args)
|
||||
C<%> : Modulo
|
||||
|
||||
=item *
|
||||
CEIL: Ceiling (unary)
|
||||
C<^> : Exponential
|
||||
|
||||
=item *
|
||||
FLOOR: Floor (unary)
|
||||
|
||||
=item *
|
||||
FMOD: Floating point modulo (binary) Added in 7.0.8
|
||||
|
||||
=item *
|
||||
LOG: Log base 10 (unary)
|
||||
|
||||
=item *
|
||||
LOGE: Natural log (unary)
|
||||
|
||||
=item *
|
||||
LN: Natural log (unary)
|
||||
|
||||
=item *
|
||||
EXP: Exponential function (unary)
|
||||
|
||||
=item *
|
||||
^ : Exponential (binary)
|
||||
|
||||
=item *
|
||||
** : Exponential (binary)
|
||||
|
||||
=item *
|
||||
+ : Addition (binary)
|
||||
|
||||
=item *
|
||||
- : Subtraction (binary)
|
||||
|
||||
=item *
|
||||
* : Multiplication (binary)
|
||||
|
||||
=item *
|
||||
/ : Division (binary)
|
||||
|
||||
=item *
|
||||
% : Modulo (binary)
|
||||
|
||||
=item *
|
||||
NOT: Negate (unary)
|
||||
C<**> : Exponential
|
||||
|
||||
=back
|
||||
|
||||
=head3 Trigonometric Operators
|
||||
=head3 Algebraic Functions
|
||||
|
||||
When functions take more than one argument, a comma separator must appear
|
||||
between them.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
SIN: Sine
|
||||
C<ABS (arg)> : Absolute value
|
||||
|
||||
=item *
|
||||
SINH: Hyperbolic sine
|
||||
C<EXP (arg)> : Exponential function
|
||||
|
||||
=item *
|
||||
ASIN: Arc sine
|
||||
C<FMOD (num, den)> : Floating point modulo. Added in 7.0.8
|
||||
|
||||
=item *
|
||||
COS: Cosine
|
||||
C<LN (arg)> : Natural log
|
||||
|
||||
=item *
|
||||
COSH: Hyperbolic cosine
|
||||
C<LOG (arg)> : Log base 10
|
||||
|
||||
=item *
|
||||
ACOS: Arc cosine
|
||||
C<LOGE (arg)> : Natural log
|
||||
|
||||
=item *
|
||||
TAN: Tangent
|
||||
C<MIN (any number of args)> : Minimum
|
||||
|
||||
=item *
|
||||
TANH: Hyperbolic tangent
|
||||
C<MAX (any number of args)> : Maximum
|
||||
|
||||
=item *
|
||||
ATAN: Arc tangent
|
||||
C<SQR (arg)> : Square root
|
||||
|
||||
=item *
|
||||
C<SQRT (arg)> : Square root
|
||||
|
||||
=back
|
||||
|
||||
=head3 Trigonometric Functions
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<SIN (arg)> : Sine
|
||||
|
||||
=item *
|
||||
C<ASIN (arg)> : Arc sine
|
||||
|
||||
=item *
|
||||
C<COS (arg)> : Cosine
|
||||
|
||||
=item *
|
||||
C<ACOS (arg)> : Arc cosine
|
||||
|
||||
=item *
|
||||
C<TAN (arg)> : Tangent
|
||||
|
||||
=item *
|
||||
C<ATAN (arg)> : Arc tangent
|
||||
|
||||
=item *
|
||||
C<ATAN2 (den, num)> : 2-parameter Arc tangent. Arg's are reversed to ANSI C
|
||||
|
||||
=back
|
||||
|
||||
=head3 Hyperbolic Trigonometry Functions
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<SINH (arg)> : Hyperbolic sine
|
||||
|
||||
=item *
|
||||
C<COSH (arg)> : Hyperbolic cosine
|
||||
|
||||
=item *
|
||||
C<TANH (arg)> : Hyperbolic tangent
|
||||
|
||||
=back
|
||||
|
||||
=head3 Numeric Functions
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<CEIL (arg)> : Ceiling
|
||||
|
||||
=item *
|
||||
C<FLOOR (arg)> : Floor
|
||||
|
||||
=item *
|
||||
C<NINT (arg)> : Round to nearest integer
|
||||
|
||||
=item *
|
||||
C<ISINF (arg)> : returns non-zero if any argument is Inf
|
||||
|
||||
=item *
|
||||
C<ISNAN (any number of args)> : returns non-zero (true) if any argument is NaN
|
||||
or Inf
|
||||
|
||||
=item *
|
||||
C<FINITE (any number of args)> : returns non-zero (true) if none of the
|
||||
arguments are NaN or Inf
|
||||
|
||||
=back
|
||||
|
||||
=head3 Boolean/Logical Operators
|
||||
|
||||
These operators use their arguments as a true (non-zero) or false (zero) value.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<&&> : And, infix binary
|
||||
|
||||
=item *
|
||||
C<||> : Or, infix binary
|
||||
|
||||
=item *
|
||||
C<!> : Not, unary prefix
|
||||
|
||||
=back
|
||||
|
||||
=head3 Bitwise Operators
|
||||
|
||||
Mostly infix binary, the arguments are converted to a 32-bit integer, the
|
||||
operator is applied, and the result converted back into a double.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<&> : Bitwise and
|
||||
|
||||
=item *
|
||||
C<|> : Bitwise or
|
||||
|
||||
=item *
|
||||
C<~> : Bitwise not or one's complement, unary prefix
|
||||
|
||||
=item *
|
||||
C<<< << >>> : Arithmetic shift left
|
||||
|
||||
=item *
|
||||
C<<< >> >>> : Arithmetic shift right
|
||||
|
||||
=item *
|
||||
C<<<< >>> >>>> : Logical shift right
|
||||
|
||||
=item *
|
||||
C<AND> : Bitwise and
|
||||
|
||||
=item *
|
||||
C<OR> : Bitwise or
|
||||
|
||||
=item *
|
||||
C<XOR> : Bitwise exclusive or
|
||||
|
||||
=item *
|
||||
C<NOT> : Bitwise not or one's complement, unary prefix
|
||||
|
||||
=back
|
||||
|
||||
=head3 Relational Operators
|
||||
|
||||
These are all infix binary operators.
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
@@ -273,59 +375,17 @@ C<<< <= >>> : Less than or equal to
|
||||
=item *
|
||||
C<<< < >>> : Less than
|
||||
|
||||
=item *
|
||||
C<<< != >>> : Not equal to
|
||||
|
||||
=item *
|
||||
C<<< # >>> : Not equal to
|
||||
|
||||
=item *
|
||||
C<<< = >>> : Equal to
|
||||
|
||||
=back
|
||||
|
||||
=head3 Logical Operators
|
||||
|
||||
=over 1
|
||||
C<<< == >>> : Equal to
|
||||
|
||||
=item *
|
||||
&& : And
|
||||
|
||||
=item *
|
||||
|| : Or
|
||||
|
||||
=item *
|
||||
! : Not
|
||||
|
||||
=back
|
||||
|
||||
=head3 Bitwise Operators
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
C<|> : Bitwise Or
|
||||
|
||||
=item *
|
||||
C<&> : Bitwise And
|
||||
|
||||
=item *
|
||||
OR : Bitwise Or
|
||||
|
||||
=item *
|
||||
AND : Bitwise And
|
||||
|
||||
=item *
|
||||
XOR : Bitwise Exclusive Or
|
||||
|
||||
=item *
|
||||
C<~> : One's Complement
|
||||
|
||||
=item *
|
||||
C<<< << >>> : Arithmetic Left Shift
|
||||
|
||||
=item *
|
||||
C<<< >> >>> : Arithmetic Right Shift
|
||||
|
||||
=item *
|
||||
C<<<< >>> >>>> : Logical Right Shift
|
||||
C<<< = >>> : Equal to (not assignment)
|
||||
|
||||
=back
|
||||
|
||||
@@ -340,22 +400,24 @@ C<:=> : assigns a value (right hand side) to a variable (i.e. field)
|
||||
|
||||
=head3 Parentheses, Comma, and Semicolon
|
||||
|
||||
The open and close parentheses are supported. Nested parentheses are
|
||||
supported.
|
||||
The open C<(> and close parentheses C<)> are supported to override precedence
|
||||
rules in a sub-expression.
|
||||
Nested parentheses are supported to significant depth.
|
||||
|
||||
The comma is supported when used to separate the arguments of a binary
|
||||
function.
|
||||
The comma C<,> is required to separate the arguments of a function.
|
||||
|
||||
The semicolon is used to separate expressions. Although only one
|
||||
traditional calculation expression is allowed, multiple assignment
|
||||
expressions are allowed.
|
||||
The semicolon C<;> is used to value separate expressions.
|
||||
Exactly one value expression must be present, but multiple assignment
|
||||
expressions may be included before and/or after the value expression.
|
||||
|
||||
=head3 Conditional Expression
|
||||
=head3 Conditional Operator
|
||||
|
||||
The C language's question mark operator is supported. The format is:
|
||||
C<condition ? True result : False result>
|
||||
The C language's question mark colon C<?:> ternary operator is supported.
|
||||
The format is:
|
||||
|
||||
=head3 Expression Examples
|
||||
I<condition> C<?> I<true-expression> C<:> I<false-expression>
|
||||
|
||||
=head2 Expression Examples
|
||||
|
||||
=head3 Algebraic
|
||||
|
||||
@@ -396,21 +458,21 @@ Result is C<F + L + 10> if C<<< (A + B) >= (C + D) >>>
|
||||
|
||||
=back
|
||||
|
||||
Prior to Base 3.14.9 it was legal to omit the : and the second (else) part
|
||||
of the conditional, like this:
|
||||
Prior to Base 3.14.9 it was legal to omit the colon C<:> and the second (else)
|
||||
part of the conditional, like this:
|
||||
|
||||
C<(A + B)<(C + D) ? E>
|
||||
C<<< (A + B)<(C + D) ? E >>>
|
||||
|
||||
=over 1
|
||||
|
||||
=item
|
||||
Result is E if (A + B)<(C + D)
|
||||
=item *
|
||||
Result is E if C<<< (A + B)<(C + D) >>>
|
||||
|
||||
=item
|
||||
Result is unchanged if (A + B)>=(C + D)
|
||||
=item *
|
||||
Result is unchanged if C<<< (A + B)>=(C + D) >>>
|
||||
|
||||
From 3.14.9 onwards, this expression must be written as
|
||||
C<(A + B) < (C + D) ? E : VAL>
|
||||
C<<< (A + B) < (C + D) ? E : VAL >>>
|
||||
|
||||
=back
|
||||
|
||||
@@ -432,7 +494,7 @@ Convert A to integer
|
||||
Convert B to integer
|
||||
|
||||
=item *
|
||||
Bitwise And A and B
|
||||
Bitwise A C<and> B
|
||||
|
||||
=item *
|
||||
Convert result to floating point
|
||||
@@ -511,13 +573,14 @@ necessary, the record can use the result of the CALC expression to
|
||||
determine if data should be written and can use the result of the OCAL
|
||||
expression as the data to write.
|
||||
|
||||
If the OEVT field specifies a non-zero integer and the condition in the
|
||||
OOPT field is met, the record will post a corresponding event. If the ODLY
|
||||
field is non-zero, the record pauses for the specified number of seconds
|
||||
before executing the OUT link or posting the output event. During this
|
||||
waiting period the record is "active" and will not be processed again until
|
||||
the wait is over. The field DLYA is equal to 1 during the delay period. The
|
||||
resolution of the delay entry system dependent.
|
||||
If the OEVT field isn't empty and the condition in the OOPT field is met, the
|
||||
record will post the corresponding named event.
|
||||
If the ODLY field is non-zero, the record pauses for the specified number of
|
||||
seconds before executing the OUT link or posting the output event.
|
||||
During this waiting period the record is "active" and will not be processed
|
||||
again until the wait is over.
|
||||
The field DLYA is equal to 1 during the delay period. The resolution of the
|
||||
delay entry system dependent.
|
||||
|
||||
The IVOA field specifies what action to take with the OUT link if the
|
||||
Calcout record enters an INVALID alarm status. The options are
|
||||
@@ -595,7 +658,7 @@ conditions.
|
||||
|
||||
The HYST field defines an alarm deadband for each limit.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
@@ -1017,60 +1080,60 @@ manner for the VAL field.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Rng")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -1078,7 +1141,7 @@ manner for the VAL field.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -1086,7 +1149,7 @@ manner for the VAL field.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -1094,7 +1157,7 @@ manner for the VAL field.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
@@ -1407,26 +1470,31 @@ The C<process()> routine implements the following algorithm:
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
Fetch all arguments.
|
||||
|
||||
=item 2.
|
||||
|
||||
Call routine C<calcPerform()>, which calculates VAL from the prefix version
|
||||
of the expression given in CALC. If C<calcPerform()> returns success, UDF
|
||||
is set to FALSE.
|
||||
|
||||
=item 3.
|
||||
|
||||
Check alarms. This routine checks to see if the new VAL causes the alarm
|
||||
status and severity to change. If so, NSEV, NSTA and LALM are set. If also
|
||||
honors the alarm hysteresis factor (HYST). Thus the value must change by at
|
||||
least HYST before the alarm status and severity changes.
|
||||
|
||||
=item 4.
|
||||
|
||||
Determine if the Output Execution Option (OOPT) is met. If met, either
|
||||
execute the output link (and output event) immediately (if ODLY = 0), or
|
||||
schedule a callback after the specified interval. See the explanation for
|
||||
the C<execOutput()> routine below.
|
||||
|
||||
=item 5.
|
||||
|
||||
Check to see if monitors should be invoked.
|
||||
|
||||
=over
|
||||
@@ -1447,6 +1515,7 @@ NSEV and NSTA are reset to 0
|
||||
=back
|
||||
|
||||
=item 6.
|
||||
|
||||
If no output delay was specified, scan forward link if necessary, set PACT
|
||||
FALSE, and return.
|
||||
|
||||
@@ -1457,19 +1526,23 @@ FALSE, and return.
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
If DOPT field specifies the use of OCAL, call the routine C<calcPerform()>
|
||||
for the postfix version of the expression in OCAL. Otherwise, use VAL.
|
||||
|
||||
=item 2.
|
||||
|
||||
If the Alarm Severity is INVALID, follow the option as designated by the
|
||||
field IVOA.
|
||||
|
||||
=item 3.
|
||||
|
||||
The Alarm Severity is not INVALID or IVOA specifies "Continue Normally",
|
||||
put the value of OVAL to the OUT link and post the event in OEVT (if
|
||||
non-zero).
|
||||
put the value of OVAL to the OUT link and post the event named in OEVT (if
|
||||
not empty).
|
||||
|
||||
=item 4.
|
||||
|
||||
If an output delay was implemented, process the forward link.
|
||||
|
||||
=back
|
||||
|
||||
@@ -88,7 +88,7 @@ As stated above, the ALG field specifies which algorithm to be performed on the
|
||||
The INP should be a database or channel access link. Though INP can be a
|
||||
constant, the data compression algorithms are supported only when INP is a
|
||||
database link. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on specifying links.
|
||||
|
||||
|
||||
@@ -449,26 +449,26 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(OFF,DBF_ULONG) {
|
||||
prompt("Offset")
|
||||
|
||||
@@ -11,9 +11,12 @@
|
||||
|
||||
The Data Fanout or "dfanout" record is used to forward data to up to
|
||||
16 other records. It's similar to the fanout record except that the
|
||||
capability to forward data has been added to it. If has no associated
|
||||
capability to forward data has been added to it. It has no associated
|
||||
device support.
|
||||
|
||||
Since UNRELEASED the number of output links has been increased
|
||||
from 8 to 16 and IVOA and IVOV fields have been added.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
@@ -60,7 +63,7 @@ undergoes no conversions before it is sent out to the output links.
|
||||
|
||||
The OUTA-OUTP fields specify where VAL is to be sent. Each field that is to
|
||||
forward data must specify an address to another record. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on specifying links.
|
||||
|
||||
The SELL, SELM, and SELN fields specify which output links are to be
|
||||
@@ -140,7 +143,7 @@ in the corresponding field (HHSV, LLSV, HSV, LSV) and can be either
|
||||
NO_ALARM, MINOR, or MAJOR. In the hysteresis field (HYST) can be entered a
|
||||
number which serves as the deadband on the limit alarms.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
@@ -194,82 +197,82 @@ hysteresis factors for monitor callbacks.
|
||||
}
|
||||
field(OUTA,DBF_OUTLINK) {
|
||||
prompt("Output Spec A")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTB,DBF_OUTLINK) {
|
||||
prompt("Output Spec B")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTC,DBF_OUTLINK) {
|
||||
prompt("Output Spec C")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTD,DBF_OUTLINK) {
|
||||
prompt("Output Spec D")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTE,DBF_OUTLINK) {
|
||||
prompt("Output Spec E")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTF,DBF_OUTLINK) {
|
||||
prompt("Output Spec F")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTG,DBF_OUTLINK) {
|
||||
prompt("Output Spec G")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTH,DBF_OUTLINK) {
|
||||
prompt("Output Spec H")
|
||||
promptgroup("50 - Outputs A-H")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTI,DBF_OUTLINK) {
|
||||
prompt("Output Spec I")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTJ,DBF_OUTLINK) {
|
||||
prompt("Output Spec J")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTK,DBF_OUTLINK) {
|
||||
prompt("Output Spec K")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTL,DBF_OUTLINK) {
|
||||
prompt("Output Spec L")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTM,DBF_OUTLINK) {
|
||||
prompt("Output Spec M")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTN,DBF_OUTLINK) {
|
||||
prompt("Output Spec N")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTO,DBF_OUTLINK) {
|
||||
prompt("Output Spec O")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(OUTP,DBF_OUTLINK) {
|
||||
prompt("Output Spec P")
|
||||
promptgroup("51 - Outputs I-P")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(DOL,DBF_INLINK) {
|
||||
@@ -288,60 +291,60 @@ hysteresis factors for monitor callbacks.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -349,7 +352,7 @@ hysteresis factors for monitor callbacks.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -357,7 +360,7 @@ hysteresis factors for monitor callbacks.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -365,7 +368,7 @@ hysteresis factors for monitor callbacks.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
@@ -404,7 +407,7 @@ hysteresis factors for monitor callbacks.
|
||||
interest(2)
|
||||
menu(menuIvoa)
|
||||
}
|
||||
field(IVOV,DBF_LONG) {
|
||||
field(IVOV,DBF_DOUBLE) {
|
||||
prompt("INVALID output value")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
@@ -487,6 +490,7 @@ Alarms ranges are checked against the contents of the VAL field.
|
||||
|
||||
Check severity and then send the value through the OUTA-OUTP links, depending
|
||||
on the setting of SELM and the value in SELN.
|
||||
|
||||
See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>
|
||||
for information on how INVALID alarms affect output records.
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
|
||||
=title Event Record (event)
|
||||
|
||||
The normal use for this record type is to post an event and/or process a
|
||||
forward link. Device support for this record can provide a hardware interrupt
|
||||
handler routine for I/O Event-scanned records.
|
||||
The normal use for this record type is to post a soft-event and/or process a
|
||||
forward link.
|
||||
C<Soft Channel> device support is provided to allow the soft-event name to be
|
||||
read from an input link.
|
||||
Hardware device support for this record can provide an interrupt handler routine
|
||||
to trigger processing of the record when an I/O Intr event occurs.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
@@ -37,18 +40,31 @@ recordtype(event) {
|
||||
=head3 Scan Parameters
|
||||
|
||||
The event record has the standard fields for specifying under what circumstances
|
||||
it will be processed.
|
||||
it should be processed.
|
||||
These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=fields SCAN, PHAS, EVNT, PRIO, PINI
|
||||
|
||||
=head3 Event Number Parameters
|
||||
=head3 Event Name Parameters
|
||||
|
||||
The VAL field contains the event number read by the device support routines. It
|
||||
is this number which is posted. For records that use C<Soft Channel> device
|
||||
support, it can be configured before run-time or set via dbPuts.
|
||||
The VAL field is a string (prior to the Base-3.15.1 release it was a short
|
||||
integer) providing the name of an IOC soft-event.
|
||||
This named soft-event gets posted whenever the record is processed.
|
||||
|
||||
=fields VAL
|
||||
When the soft-event name is known at design time, the VAL field should be set to
|
||||
the name in a loaded database file.
|
||||
Soft-event names do not have to be registered before use, a handle for the name
|
||||
is automatically created and stored when a name is first seen and the same
|
||||
handle returned later if the same name is re-used.
|
||||
|
||||
The EPVT field holds the handle for the soft-event named in the VAL field.
|
||||
Looking up the handle for a soft-event name is fast and uses a hash table.
|
||||
|
||||
For records that use the default C<Soft Channel> device support, the soft-event
|
||||
name can be fetched through the INP field link, written to the VAL field and the
|
||||
handle looked up during record processing.
|
||||
|
||||
=fields VAL, EPVT
|
||||
|
||||
=cut
|
||||
|
||||
@@ -69,16 +85,18 @@ support, it can be configured before run-time or set via dbPuts.
|
||||
|
||||
=head3 Input Specification
|
||||
|
||||
The device support routines use the address in this record to obtain input. For
|
||||
records that provide an interrupt handler, the INP field should specify the
|
||||
The device support routines use the address in this record to obtain input.
|
||||
For records that provide an interrupt handler, the INP field should specify the
|
||||
address of the I/O card, and the DTYP field should specify a valid device
|
||||
support module. Be aware that the address format differs according to the card
|
||||
type used. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
support module.
|
||||
|
||||
The address format differs according to the card type used. See
|
||||
L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of hardware addresses and specifying links.
|
||||
|
||||
For soft records, the INP field can be a constant, a database link, or a channel
|
||||
access link. For soft records, the DTYP field should specify C<Soft Channel>.
|
||||
access link, and the DTYP field should be empty or set to C<Soft Channel>.
|
||||
|
||||
=fields INP, DTYP
|
||||
|
||||
@@ -93,24 +111,27 @@ access link. For soft records, the DTYP field should specify C<Soft Channel>.
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
Parameters>
|
||||
for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields NAME, DESC
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The Event record has the alarm parameters common to all record types. L<Alarm
|
||||
Fields> lists other fields related to alarms that are common to all record
|
||||
types.
|
||||
The Event record has the alarm parameters common to all record types.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related to alarms
|
||||
that are common to all record types.
|
||||
|
||||
=fields STAT, SEVR, AMSG, NSTA, NSEV, NAMSG, ACKS, ACKT, UDF
|
||||
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The following fields are used to operate the event record in the simulation
|
||||
mode. See L<Fields Common to Many Record Types> for more information on these
|
||||
fields.
|
||||
mode.
|
||||
See L<Fields Common to Input Record Types|dbCommonInput/Input Simulation Fields>
|
||||
for more information on these fields.
|
||||
|
||||
=fields SIOL, SVAL, SIML, SIMM, SIMS
|
||||
=fields SIOL, SVAL, SIML, SIMM, SIMS, SSCN, SDLY
|
||||
|
||||
=cut
|
||||
|
||||
@@ -179,38 +200,50 @@ initialized if SIOL is CONSTANT or PV_LINK.
|
||||
|
||||
If device support includes C<init_record()>, it is called.
|
||||
|
||||
The string in VAL is converted to a soft-event handle in EPVT.
|
||||
|
||||
=head4 process
|
||||
|
||||
See next section.
|
||||
|
||||
=head4 special
|
||||
|
||||
When the VAL field is set, the new string is converted to a soft-event handle in
|
||||
EPVT.
|
||||
|
||||
=head3 Record Processing
|
||||
|
||||
Routine process implements the following algorithm:
|
||||
Routine C<process()> implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
readValue is called. See L<Input Records> for more information.
|
||||
C<readValue()> is called.
|
||||
See L<Input Records|dbCommonInput/Input Records> for more information.
|
||||
|
||||
=item 2.
|
||||
|
||||
If PACT has been changed to TRUE, the device support read routine has started
|
||||
but has not completed reading a new input value. In this case, the processing
|
||||
routine merely returns, leaving PACT TRUE.
|
||||
If PACT has changed to TRUE, the device support read routine has started
|
||||
but has not completed reading a new soft-event name.
|
||||
In this case, the processing routine returns immediately, leaving PACT TRUE.
|
||||
|
||||
=item 3.
|
||||
|
||||
If VAL E<gt> 0, post event number VAL.
|
||||
Set PACT to TRUE.
|
||||
|
||||
=item 4.
|
||||
|
||||
Check to see if monitors should be invoked. Alarm monitors are invoked if the
|
||||
alarm status or severity has chanet to 0.
|
||||
Post the soft-event whose handle is in EPVT.
|
||||
|
||||
=item 5.
|
||||
|
||||
Scan forward link if necessary, set PACT FALSE, and return.
|
||||
Check to see if monitors should be invoked.
|
||||
Alarm monitors are invoked if the new alarm status or severity are non-zero.
|
||||
|
||||
=item 6.
|
||||
|
||||
Scan forward link if set, set PACT to FALSE, and return.
|
||||
|
||||
=back
|
||||
|
||||
@@ -221,13 +254,15 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
Each record must have an associated set of device support routines. The device
|
||||
support routines are primarily interested in the following fields:
|
||||
|
||||
=fields PACT, DPVT, UDF, NSEV, NSTA, INP, PRIO
|
||||
=fields PACT, DPVT, UDF, NSEV, NSTA, INP, PRIO, VAL, EPVT
|
||||
|
||||
=head3 Device Support Routines
|
||||
|
||||
Device support consists of the following routines:
|
||||
|
||||
=head4 long report(int level)
|
||||
=head4 report
|
||||
|
||||
long report(int level)
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
@@ -235,9 +270,11 @@ It should print a report on the state of the device support to stdout.
|
||||
The C<level> parameter may be used to output increasingly more detailed
|
||||
information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
Level zero should print only a 1-line summary.
|
||||
|
||||
=head4 long init(int after)
|
||||
=head4 init
|
||||
|
||||
long init(int after)
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
@@ -247,23 +284,25 @@ with C<after> set to 1.
|
||||
|
||||
=head4 init_record
|
||||
|
||||
init_record(precord)
|
||||
long init_record(precord)
|
||||
|
||||
This routine is optional. If provided, it is called by the record support
|
||||
C<init_record()> routine.
|
||||
|
||||
=head4 get_ioint_info
|
||||
|
||||
get_ioint_info(int cmd, struct dbCommon *precord, IOSCANPVT *ppvt)
|
||||
long get_ioint_info(int cmd, struct dbCommon *precord, IOSCANPVT *ppvt)
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is added
|
||||
or deleted from an I/O event scan list. C<cmd> has the value (0,1) if the record is
|
||||
being (added to, deleted from) an I/O event list. It must be provided for any
|
||||
device type that can use the ioEvent scanner.
|
||||
This routine is called by the dbScan system each time the record is added
|
||||
or deleted from an I/O event scan list.
|
||||
C<cmd> has the value (0, 1) if the record is being (added to, deleted from) an
|
||||
I/O event list.
|
||||
The C<get_ioint_info> routine is optional, but must be provided by any device
|
||||
support that implements C<I/O Intr> scanning for the event record type.
|
||||
|
||||
=head4 read_event
|
||||
|
||||
read_event(precord)
|
||||
long read_event(precord)
|
||||
|
||||
This routine returns the following values:
|
||||
|
||||
@@ -281,15 +320,13 @@ Other: Error.
|
||||
|
||||
=head3 Device Support For Soft Records
|
||||
|
||||
The C<Soft Channel> device support module is available. The INP link type must
|
||||
be either CONSTANT, DB_LINK, or CA_LINK.
|
||||
A C<Soft Channel> device support module is available.
|
||||
The INP link field is used to fetch the soft-event name.
|
||||
|
||||
If the INP link type is CONSTANT, then the constant value is stored into VAL by
|
||||
C<init_record()>, and UDF is set to FALSE. If the INP link type is PV_LINK, then
|
||||
dbCaAddInlink is called by C<init_record()>.
|
||||
The C<read_event()> routine reads a string through INP and stores it in VAL,
|
||||
then looks up the named soft-event handle and sets EPVT.
|
||||
|
||||
C<read_event> calls recGblGetLinkValue to read the current value of VAL. See
|
||||
L<Input Records> for details on soft input.
|
||||
See L<Input Records|dbCommonInput/Input Records> for details on soft input.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -135,47 +135,47 @@ monitoring deadband functionality.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_INT64) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_INT64) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_INT64) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_INT64) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_INT64) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_INT64) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
|
||||
@@ -171,61 +171,61 @@ monitoring deadband functionality.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(DRVH,DBF_INT64) {
|
||||
prompt("Drive High Limit")
|
||||
promptgroup("30 - Action")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_control_double
|
||||
}
|
||||
field(DRVL,DBF_INT64) {
|
||||
prompt("Drive Low Limit")
|
||||
promptgroup("30 - Action")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_control_double
|
||||
}
|
||||
field(HOPR,DBF_INT64) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_INT64) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_INT64) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_INT64) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_INT64) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_INT64) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
|
||||
@@ -345,53 +345,54 @@ sets UDF to FALSE. read_longin returns the status of C<recGblGetLinkValue>.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_LONG) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_LONG) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_LONG) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_LONG) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_LONG) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_LONG) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -399,6 +400,7 @@ sets UDF to FALSE. read_longin returns the status of C<recGblGetLinkValue>.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -406,6 +408,7 @@ sets UDF to FALSE. read_longin returns the status of C<recGblGetLinkValue>.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -413,6 +416,7 @@ sets UDF to FALSE. read_longin returns the status of C<recGblGetLinkValue>.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_LONG) {
|
||||
|
||||
@@ -78,7 +78,7 @@ channel access link. If the link is a constant, the result is no output. The
|
||||
DTYP field must then specify the C<<< Soft Channel >>> device support routine.
|
||||
|
||||
See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of hardware addresses and database links.
|
||||
|
||||
=fields OUT, DTYP, OOPT, OOCH
|
||||
@@ -187,33 +187,33 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(DRVH,DBF_LONG) {
|
||||
prompt("Drive High Limit")
|
||||
promptgroup("30 - Action")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_control_double
|
||||
}
|
||||
field(DRVL,DBF_LONG) {
|
||||
prompt("Drive Low Limit")
|
||||
promptgroup("30 - Action")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_control_double
|
||||
}
|
||||
field(HOPR,DBF_LONG) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_LONG) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
|
||||
=head3 Alarm Parameters
|
||||
@@ -233,7 +233,7 @@ The HYST field sets an alarm deadband around each limit alarm.
|
||||
For an explanation of the IVOA and IVOV fields, see
|
||||
L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
@@ -247,34 +247,35 @@ to alarms that are common to all record types.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_LONG) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_LONG) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_LONG) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -282,6 +283,7 @@ to alarms that are common to all record types.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -289,6 +291,7 @@ to alarms that are common to all record types.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -296,6 +299,7 @@ to alarms that are common to all record types.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_LONG) {
|
||||
|
||||
@@ -102,6 +102,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
promptgroup("40 - Input")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
|
||||
@@ -276,7 +276,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ONST,DBF_STRING) {
|
||||
prompt("One String")
|
||||
@@ -285,7 +285,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TWST,DBF_STRING) {
|
||||
prompt("Two String")
|
||||
@@ -294,7 +294,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(THST,DBF_STRING) {
|
||||
prompt("Three String")
|
||||
@@ -303,7 +303,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FRST,DBF_STRING) {
|
||||
prompt("Four String")
|
||||
@@ -312,7 +312,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FVST,DBF_STRING) {
|
||||
prompt("Five String")
|
||||
@@ -321,7 +321,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(SXST,DBF_STRING) {
|
||||
prompt("Six String")
|
||||
@@ -330,7 +330,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(SVST,DBF_STRING) {
|
||||
prompt("Seven String")
|
||||
@@ -339,7 +339,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(EIST,DBF_STRING) {
|
||||
prompt("Eight String")
|
||||
@@ -348,7 +348,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(NIST,DBF_STRING) {
|
||||
prompt("Nine String")
|
||||
@@ -357,7 +357,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TEST,DBF_STRING) {
|
||||
prompt("Ten String")
|
||||
@@ -366,7 +366,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ELST,DBF_STRING) {
|
||||
prompt("Eleven String")
|
||||
@@ -375,7 +375,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TVST,DBF_STRING) {
|
||||
prompt("Twelve String")
|
||||
@@ -384,7 +384,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TTST,DBF_STRING) {
|
||||
prompt("Thirteen String")
|
||||
@@ -393,7 +393,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FTST,DBF_STRING) {
|
||||
prompt("Fourteen String")
|
||||
@@ -402,7 +402,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FFST,DBF_STRING) {
|
||||
prompt("Fifteen String")
|
||||
@@ -411,7 +411,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
|
||||
=head3 Alarm Parameters
|
||||
@@ -436,7 +436,7 @@ state occurs, if set to MAJOR or MINOR.
|
||||
The other fields, when set to MAJOR or MINOR, trigger an alarm when VAL equals
|
||||
the corresponding state.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
|
||||
@@ -89,7 +89,7 @@ For records that are to write values to hardware devices, the OUT output link
|
||||
must contain the address of the I/O card, and the DTYP field must specify
|
||||
the proper device support module. Be aware that the address format differs
|
||||
according to the I/O bus used. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on the format of hardware addresses.
|
||||
|
||||
During record processing VAL is converted into RVAL, which is the actual 32-bit
|
||||
@@ -153,6 +153,7 @@ Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
promptgroup("50 - Output")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(DOL,DBF_INLINK) {
|
||||
prompt("Desired Output Link")
|
||||
@@ -299,7 +300,7 @@ the IVOV field to the output.
|
||||
See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>
|
||||
for more information about IVOA and IVOV.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
|
||||
@@ -354,7 +354,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ONST,DBF_STRING) {
|
||||
prompt("One String")
|
||||
@@ -363,7 +363,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TWST,DBF_STRING) {
|
||||
prompt("Two String")
|
||||
@@ -372,7 +372,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(THST,DBF_STRING) {
|
||||
prompt("Three String")
|
||||
@@ -381,7 +381,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FRST,DBF_STRING) {
|
||||
prompt("Four String")
|
||||
@@ -390,7 +390,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FVST,DBF_STRING) {
|
||||
prompt("Five String")
|
||||
@@ -399,7 +399,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(SXST,DBF_STRING) {
|
||||
prompt("Six String")
|
||||
@@ -408,7 +408,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(SVST,DBF_STRING) {
|
||||
prompt("Seven String")
|
||||
@@ -417,7 +417,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(EIST,DBF_STRING) {
|
||||
prompt("Eight String")
|
||||
@@ -426,7 +426,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(NIST,DBF_STRING) {
|
||||
prompt("Nine String")
|
||||
@@ -435,7 +435,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TEST,DBF_STRING) {
|
||||
prompt("Ten String")
|
||||
@@ -444,7 +444,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ELST,DBF_STRING) {
|
||||
prompt("Eleven String")
|
||||
@@ -453,7 +453,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TVST,DBF_STRING) {
|
||||
prompt("Twelve String")
|
||||
@@ -462,7 +462,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(TTST,DBF_STRING) {
|
||||
prompt("Thirteen String")
|
||||
@@ -471,7 +471,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FTST,DBF_STRING) {
|
||||
prompt("Fourteen String")
|
||||
@@ -480,7 +480,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(FFST,DBF_STRING) {
|
||||
prompt("Fifteen String")
|
||||
@@ -489,7 +489,7 @@ for more information on simulation mode and its fields.
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
size(26)
|
||||
prop(YES)
|
||||
prop(YES) # get_enum_str, get_enum_strs, put_enum_str
|
||||
}
|
||||
field(ZRSV,DBF_MENU) {
|
||||
prompt("State Zero Severity")
|
||||
|
||||
@@ -148,7 +148,7 @@ which type of the data is requested through the appropriate input link. As with
|
||||
C<printf()> a C<*> character may be used in the format to specify width and/or
|
||||
precision instead of numeric literals, in which case additional input links are
|
||||
used to provide the necessary integer parameter or parameters. See L<Address
|
||||
Specification|https://docs.epics-controls.org/en/latest/guides/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#address-specification>
|
||||
for information on specifying links.
|
||||
|
||||
The formatted string is written to the VAL field. The maximum number of
|
||||
|
||||
@@ -299,6 +299,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(NVL,DBF_INLINK) {
|
||||
prompt("Index Value Location")
|
||||
@@ -370,54 +371,54 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Rng")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -425,7 +426,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -433,7 +434,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -441,7 +442,7 @@ Scan forward link if necessary, set PACT FALSE, and return.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
|
||||
@@ -334,7 +334,7 @@ INP is expected to point to an array field of a waveform record or similar.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
@@ -353,26 +353,27 @@ INP is expected to point to an array field of a waveform record or similar.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(MALM,DBF_ULONG) {
|
||||
prompt("Maximum Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
initial("1")
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
|
||||
@@ -86,7 +86,7 @@ static long do_sub(subRecord *);
|
||||
static long fetch_values(subRecord *);
|
||||
static void monitor(subRecord *);
|
||||
|
||||
#define INP_ARG_MAX 12
|
||||
#define INP_ARG_MAX 21
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
@@ -196,9 +196,9 @@ static long special(DBADDR *paddr, int after)
|
||||
#define indexof(field) subRecord##field
|
||||
|
||||
static long get_linkNumber(int fieldIndex) {
|
||||
if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
|
||||
if (fieldIndex >= indexof(A) && fieldIndex < indexof(A) + INP_ARG_MAX)
|
||||
return fieldIndex - indexof(A);
|
||||
if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
|
||||
if (fieldIndex >= indexof(LA) && fieldIndex < indexof(LA) + INP_ARG_MAX)
|
||||
return fieldIndex - indexof(LA);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
The subroutine record is used to call a C initialization routine and a recurring
|
||||
scan routine. There is no device support for this record.
|
||||
|
||||
Since UNRELEASED the number of inputs has been increased from 12 to 21.
|
||||
|
||||
=recordtype sub
|
||||
|
||||
=cut
|
||||
@@ -30,17 +32,17 @@ These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Read Parameters
|
||||
|
||||
The subroutine record has twelve input links (INPA-INPL), each of which has a
|
||||
corresponding value field (A-L). These fields are used to retrieve and store
|
||||
The subroutine record has 21 input links INPA - INPU, each of which has a
|
||||
corresponding value field A - U. These fields are used to retrieve and store
|
||||
values that can be passed to the subroutine that the record calls.
|
||||
|
||||
The input links can be either channel access or database links, or constants.
|
||||
When constants, the corresponding value field for the link is initialized with
|
||||
the constant value and the field's value can be changed at run-time via dbPuts.
|
||||
Otherwise, the values for (A-F) are fetched from the input links when the record
|
||||
is processed.
|
||||
Otherwise, the values for A - U are fetched from the input links when the
|
||||
record is processed.
|
||||
|
||||
=fields INPA - INPL, A - L
|
||||
=fields INPA - INPU, A - U
|
||||
|
||||
=head3 Subroutine Connection
|
||||
|
||||
@@ -115,11 +117,11 @@ processing routines or the monitors.
|
||||
VAL should be set by the subroutine. SADR holds the subroutine address and is
|
||||
set by the record processing routine.
|
||||
|
||||
The rest of these fields--LALM, ALST, MLST, and the LA-LL fields--are used to
|
||||
The rest of these fields--LALM, ALST, MLST, and the LA-LU fields--are used to
|
||||
implement the monitors. For example, when LA is not equal to A, the value-change
|
||||
monitors are called for that field.
|
||||
|
||||
=fields VAL, SADR, LALM, ALST, MLST, LA - LL
|
||||
=fields VAL, SADR, LALM, ALST, MLST, LA - LU
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
@@ -161,7 +163,7 @@ recGblGetPrec() >>>.
|
||||
long (*get_graphic_double)(struct dbAddr *paddr, struct dbr_grDouble *p)
|
||||
|
||||
Sets the upper display and lower display limits for a field. If the field is
|
||||
VAL, A-L, LA-LL, HIHI, HIGH, LOW, or LOLO, the limits are set to HOPR and LOPR,
|
||||
VAL, A-U, LA-LU, HIHI, HIGH, LOW, or LOLO, the limits are set to HOPR and LOPR,
|
||||
else if the field has upper and lower limits defined they will be used, else the
|
||||
upper and lower maximum values for the field type will be used.
|
||||
|
||||
@@ -170,7 +172,7 @@ upper and lower maximum values for the field type will be used.
|
||||
long (*get_control_double)(struct dbAddr *paddr, struct dbr_ctrlDouble *p)
|
||||
|
||||
Sets the upper control and the lower control limits for a field. If the field is
|
||||
VAL, A-L, LA-LL, HIHI, HIGH, LOW, or LOLO, the limits are set to HOPR and LOPR,
|
||||
VAL, A-U, LA-LU, HIHI, HIGH, LOW, or LOLO, the limits are set to HOPR and LOPR,
|
||||
else if the field has upper and lower limits defined they will be used, else the
|
||||
upper and lower maximum values for the field type will be used.
|
||||
|
||||
@@ -241,7 +243,7 @@ met.
|
||||
|
||||
=item *
|
||||
|
||||
Monitors for A-L are invoked if value has changed.
|
||||
Monitors for A-U are invoked if value has changed.
|
||||
|
||||
=item *
|
||||
|
||||
@@ -500,58 +502,103 @@ processing.
|
||||
promptgroup("42 - Input G-L")
|
||||
interest(1)
|
||||
}
|
||||
field(INPM,DBF_INLINK) {
|
||||
prompt("Input M")
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPN,DBF_INLINK) {
|
||||
prompt("Input N")
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPO,DBF_INLINK) {
|
||||
prompt("Input O")
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPP,DBF_INLINK) {
|
||||
prompt("Input P")
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPQ,DBF_INLINK) {
|
||||
prompt("Input Q")
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPR,DBF_INLINK) {
|
||||
prompt("Input R")
|
||||
promptgroup("43 - Input M-R")
|
||||
interest(1)
|
||||
}
|
||||
field(INPS,DBF_INLINK) {
|
||||
prompt("Input S")
|
||||
promptgroup("44 - Input S-U")
|
||||
interest(1)
|
||||
}
|
||||
field(INPT,DBF_INLINK) {
|
||||
prompt("Input T")
|
||||
promptgroup("44 - Input S-U")
|
||||
interest(1)
|
||||
}
|
||||
field(INPU,DBF_INLINK) {
|
||||
prompt("Input U")
|
||||
promptgroup("44 - Input S-U")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(HIHI,DBF_DOUBLE) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOLO,DBF_DOUBLE) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(HIGH,DBF_DOUBLE) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(LOW,DBF_DOUBLE) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(BRSV,DBF_MENU) {
|
||||
prompt("Bad Return Severity")
|
||||
@@ -565,7 +612,7 @@ processing.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
@@ -573,7 +620,7 @@ processing.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
@@ -581,7 +628,7 @@ processing.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
@@ -589,7 +636,7 @@ processing.
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_alarm_double
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
@@ -655,6 +702,42 @@ processing.
|
||||
prompt("Value of Input L")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(M,DBF_DOUBLE) {
|
||||
prompt("Value of Input M")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(N,DBF_DOUBLE) {
|
||||
prompt("Value of Input N")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(O,DBF_DOUBLE) {
|
||||
prompt("Value of Input O")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(P,DBF_DOUBLE) {
|
||||
prompt("Value of Input P")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(Q,DBF_DOUBLE) {
|
||||
prompt("Value of Input Q")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(R,DBF_DOUBLE) {
|
||||
prompt("Value of Input R")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(S,DBF_DOUBLE) {
|
||||
prompt("Value of Input S")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(T,DBF_DOUBLE) {
|
||||
prompt("Value of Input T")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(U,DBF_DOUBLE) {
|
||||
prompt("Value of Input U")
|
||||
pp(TRUE)
|
||||
}
|
||||
field(LA,DBF_DOUBLE) {
|
||||
prompt("Prev Value of A")
|
||||
special(SPC_NOMOD)
|
||||
@@ -715,6 +798,51 @@ processing.
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LM,DBF_DOUBLE) {
|
||||
prompt("Prev Value of M")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LN,DBF_DOUBLE) {
|
||||
prompt("Prev Value of N")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LO,DBF_DOUBLE) {
|
||||
prompt("Prev Value of O")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LP,DBF_DOUBLE) {
|
||||
prompt("Prev Value of P")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LQ,DBF_DOUBLE) {
|
||||
prompt("Prev Value of Q")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LR,DBF_DOUBLE) {
|
||||
prompt("Prev Value of R")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LS,DBF_DOUBLE) {
|
||||
prompt("Prev Value of S")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LT,DBF_DOUBLE) {
|
||||
prompt("Prev Value of T")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LU,DBF_DOUBLE) {
|
||||
prompt("Prev Value of U")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
|
||||
@@ -417,7 +417,7 @@ routine and NORD is also set at that time.
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_precision
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
@@ -429,19 +429,19 @@ routine and NORD is also set at that time.
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
prop(YES) # get_units
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
prop(YES) # get_graphic_double, get_control_double
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
|
||||
@@ -185,7 +185,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case 'D':
|
||||
if(lazy_dbd_loaded) {
|
||||
throw std::runtime_error("-D specified too late. softIoc.dbd already loaded.\n");
|
||||
throw std::runtime_error("-D specified too late, softIoc.dbd already loaded.\n");
|
||||
}
|
||||
dbd_file = optarg;
|
||||
break;
|
||||
@@ -195,8 +195,7 @@ int main(int argc, char *argv[])
|
||||
+ optarg + "\"" + ( !macros.empty() ?
|
||||
(std::string(", \"") + macros + "\"") : std::string() )
|
||||
+ ")");
|
||||
errIf(dbLoadRecords(optarg, macros.c_str()),
|
||||
std::string("Failed to load: ")+optarg);
|
||||
errIf(dbLoadRecords(optarg, macros.c_str()), "");
|
||||
loadedDb = true;
|
||||
break;
|
||||
case 'm':
|
||||
@@ -216,8 +215,7 @@ int main(int argc, char *argv[])
|
||||
xmacro += optarg;
|
||||
verbose_out(CMD, std::string("dbLoadRecords(\"")
|
||||
+ exit_file + "\", \"" + xmacro + "\")");
|
||||
errIf(dbLoadRecords(exit_file.c_str(), xmacro.c_str()),
|
||||
std::string("Failed to load: ")+exit_file);
|
||||
errIf(dbLoadRecords(exit_file.c_str(), xmacro.c_str()), "");
|
||||
loadedDb = true;
|
||||
break;
|
||||
}
|
||||
@@ -274,7 +272,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
}catch(std::exception& e){
|
||||
errlogFlush();
|
||||
std::cerr<<ERL_ERROR ": "<<e.what()<<"\n";
|
||||
if (e.what()[0] != '\0')
|
||||
std::cerr<<ERL_ERROR ": "<<e.what()<<"\n";
|
||||
epicsExit(2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ include $(TOP)/configure/CONFIG
|
||||
# ADD MACRO DEFINITIONS BELOW HERE
|
||||
|
||||
# Use typed rset structure (see 3.16.1 release notes)
|
||||
USR_CPPFLAGS += -DUSE_TYPED_RSET
|
||||
USR_CPPFLAGS += -DUSE_TYPED_RSET -DUSE_TYPED_DSET
|
||||
|
||||
# xxxRecord.h will be created from xxxRecord.dbd
|
||||
DBDINC += xxxRecord
|
||||
|
||||
@@ -21,42 +21,30 @@
|
||||
#include "xxxRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
static long init_record(dbCommon *prec)
|
||||
{
|
||||
struct xxxRecord *pxxx = (struct xxxRecord *) prec;
|
||||
|
||||
if (recGblInitConstantLink(&pxxx->inp, DBF_DOUBLE, &pxxx->val))
|
||||
pxxx->udf = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_xxx(struct xxxRecord *pxxx)
|
||||
{
|
||||
long status = dbGetLink(&(pxxx->inp), DBF_DOUBLE, &(pxxx->val), 0, 0);
|
||||
|
||||
/* If get was successful VAL is now defined */
|
||||
if (!status)
|
||||
pxxx->udf = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Create the dset for devXxxSoft */
|
||||
static long init_record();
|
||||
static long read_xxx();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_xxx;
|
||||
}devXxxSoft={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
xxxdset devXxxSoft = {
|
||||
{ 5, NULL, NULL, init_record, NULL },
|
||||
read_xxx,
|
||||
};
|
||||
epicsExportAddress(dset,devXxxSoft);
|
||||
|
||||
|
||||
static long init_record(pxxx)
|
||||
struct xxxRecord *pxxx;
|
||||
{
|
||||
if(recGblInitConstantLink(&pxxx->inp,DBF_DOUBLE,&pxxx->val))
|
||||
pxxx->udf = FALSE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long read_xxx(pxxx)
|
||||
struct xxxRecord *pxxx;
|
||||
{
|
||||
long status;
|
||||
|
||||
status = dbGetLink(&(pxxx->inp),DBF_DOUBLE, &(pxxx->val),0,0);
|
||||
/*If return was succesful then set undefined false*/
|
||||
if(!status) pxxx->udf = FALSE;
|
||||
return(0);
|
||||
}
|
||||
epicsExportAddress(dset, devXxxSoft);
|
||||
|
||||
@@ -67,15 +67,6 @@ rset xxxRSET={
|
||||
};
|
||||
epicsExportAddress(rset,xxxRSET);
|
||||
|
||||
typedef struct xxxset { /* xxx input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_xxx;
|
||||
}xxxdset;
|
||||
|
||||
static void checkAlarms(xxxRecord *prec);
|
||||
static void monitor(xxxRecord *prec);
|
||||
|
||||
@@ -92,13 +83,13 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* must have read_xxx function defined */
|
||||
if( (pdset->number < 5) || (pdset->read_xxx == NULL) ) {
|
||||
if( (pdset->common.number < 5) || (pdset->read_xxx == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"xxx: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
|
||||
if( pdset->init_record ) {
|
||||
if((status=(*pdset->init_record)(prec))) return(status);
|
||||
if( pdset->common.init_record ) {
|
||||
if((status=(*pdset->common.init_record)(pcommon))) return(status);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -3,120 +3,129 @@
|
||||
# SPDX-License-Identifier: EPICS
|
||||
|
||||
recordtype(xxx) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Current EGU Value")
|
||||
promptgroup("40 - Input")
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup("40 - Input")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
}
|
||||
field(HOPR,DBF_FLOAT) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(LOPR,DBF_FLOAT) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(HIHI,DBF_FLOAT) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(LOLO,DBF_FLOAT) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(HIGH,DBF_FLOAT) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(LOW,DBF_FLOAT) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
prompt("Lolo Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
prompt("High Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
prompt("Low Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
prompt("Alarm Deadband")
|
||||
promptgroup("70 - Alarm")
|
||||
interest(1)
|
||||
}
|
||||
field(ADEL,DBF_DOUBLE) {
|
||||
prompt("Archive Deadband")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(MDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Deadband")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ALST,DBF_DOUBLE) {
|
||||
prompt("Last Value Archived")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MLST,DBF_DOUBLE) {
|
||||
prompt("Last Val Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct xxxRecord;
|
||||
%typedef struct xxxdset {
|
||||
% dset common;
|
||||
% long (*read_xxx)(struct xxxRecord *prec);
|
||||
%} xxxdset;
|
||||
%#define HAS_xxxdset
|
||||
%
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Current EGU Value")
|
||||
promptgroup("40 - Input")
|
||||
asl(ASL0)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup("40 - Input")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
}
|
||||
field(HOPR,DBF_FLOAT) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(LOPR,DBF_FLOAT) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(HIHI,DBF_FLOAT) {
|
||||
prompt("Hihi Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(LOLO,DBF_FLOAT) {
|
||||
prompt("Lolo Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(HIGH,DBF_FLOAT) {
|
||||
prompt("High Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(LOW,DBF_FLOAT) {
|
||||
prompt("Low Alarm Limit")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(HHSV,DBF_MENU) {
|
||||
prompt("Hihi Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LLSV,DBF_MENU) {
|
||||
prompt("Lolo Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HSV,DBF_MENU) {
|
||||
prompt("High Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(LSV,DBF_MENU) {
|
||||
prompt("Low Severity")
|
||||
promptgroup("70 - Alarm")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HYST,DBF_DOUBLE) {
|
||||
prompt("Alarm Deadband")
|
||||
promptgroup("70 - Alarm")
|
||||
interest(1)
|
||||
}
|
||||
field(ADEL,DBF_DOUBLE) {
|
||||
prompt("Archive Deadband")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(MDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Deadband")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(LALM,DBF_DOUBLE) {
|
||||
prompt("Last Value Alarmed")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(ALST,DBF_DOUBLE) {
|
||||
prompt("Last Value Archived")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MLST,DBF_DOUBLE) {
|
||||
prompt("Last Val Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user