Merge tag 'R7.0.6' into PSI-7.0
ANJ: Tagged for release Conflicts: .ci configure/os/CONFIG_SITE.linux-x86.Common modules/libcom/src/misc/epicsString.h src/tools/makeTestfile.pl
This commit is contained in:
@@ -360,6 +360,16 @@ static void getOptions(DBADDR *paddr, char **poriginal, long *options,
|
||||
*pushort++ = pcommon->ackt;
|
||||
pbuffer = (char *)pushort;
|
||||
}
|
||||
if( (*options) & DBR_AMSG ) {
|
||||
if (!pfl) {
|
||||
STATIC_ASSERT(sizeof(pcommon->amsg)==sizeof(pfl->amsg));
|
||||
strncpy(pbuffer, pcommon->amsg, sizeof(pcommon->amsg)-1);
|
||||
} else {
|
||||
strncpy(pbuffer, pfl->amsg,sizeof(pfl->amsg)-1);
|
||||
}
|
||||
pbuffer[sizeof(pcommon->amsg)-1] = '\0';
|
||||
pbuffer += sizeof(pcommon->amsg);
|
||||
}
|
||||
if( (*options) & DBR_UNITS ) {
|
||||
memset(pbuffer,'\0',dbr_units_size);
|
||||
if( prset && prset->get_units ){
|
||||
@@ -392,6 +402,15 @@ static void getOptions(DBADDR *paddr, char **poriginal, long *options,
|
||||
}
|
||||
pbuffer = (char *)ptime;
|
||||
}
|
||||
if( (*options) & DBR_UTAG ) {
|
||||
epicsUInt64 *ptag = (epicsUInt64*)pbuffer;
|
||||
if (!pfl) {
|
||||
*ptag++ = pcommon->utag;
|
||||
} else {
|
||||
*ptag++ = pfl->utag;
|
||||
}
|
||||
pbuffer = (char *)ptag;
|
||||
}
|
||||
if( (*options) & DBR_ENUM_STRS )
|
||||
get_enum_strs(paddr, &pbuffer, prset, options);
|
||||
if( (*options) & (DBR_GR_LONG|DBR_GR_DOUBLE ))
|
||||
@@ -523,7 +542,7 @@ long dbProcess(dbCommon *precord)
|
||||
(precord->lcnt++ < MAX_LOCK) ||
|
||||
(precord->sevr >= INVALID_ALARM)) goto all_done;
|
||||
|
||||
recGblSetSevr(precord, SCAN_ALARM, INVALID_ALARM);
|
||||
recGblSetSevrMsg(precord, SCAN_ALARM, INVALID_ALARM, "Async in progress");
|
||||
monitor_mask = recGblResetAlarms(precord);
|
||||
monitor_mask |= DBE_VALUE|DBE_LOG;
|
||||
pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->indvalFlddes];
|
||||
@@ -1385,7 +1404,8 @@ long dbPut(DBADDR *paddr, short dbrType,
|
||||
/* Always do special processing if needed */
|
||||
if (special) {
|
||||
long status2 = dbPutSpecial(paddr, 1);
|
||||
if (status2) goto done;
|
||||
if (status2)
|
||||
status = status2;
|
||||
}
|
||||
if (status) goto done;
|
||||
|
||||
|
||||
@@ -33,16 +33,18 @@ DBCORE_API extern int dbAccessDebugPUTF;
|
||||
/* The database field and request types are defined in dbFldTypes.h*/
|
||||
/* Data Base Request Options */
|
||||
#define DBR_STATUS 0x00000001
|
||||
#define DBR_UNITS 0x00000002
|
||||
#define DBR_PRECISION 0x00000004
|
||||
#define DBR_TIME 0x00000008
|
||||
#define DBR_ENUM_STRS 0x00000010
|
||||
#define DBR_GR_LONG 0x00000020
|
||||
#define DBR_GR_DOUBLE 0x00000040
|
||||
#define DBR_CTRL_LONG 0x00000080
|
||||
#define DBR_CTRL_DOUBLE 0x00000100
|
||||
#define DBR_AL_LONG 0x00000200
|
||||
#define DBR_AL_DOUBLE 0x00000400
|
||||
#define DBR_AMSG 0x00000002
|
||||
#define DBR_UNITS 0x00000004
|
||||
#define DBR_PRECISION 0x00000008
|
||||
#define DBR_TIME 0x00000010
|
||||
#define DBR_UTAG 0x00000020
|
||||
#define DBR_ENUM_STRS 0x00000040
|
||||
#define DBR_GR_LONG 0x00000080
|
||||
#define DBR_GR_DOUBLE 0x00000100
|
||||
#define DBR_CTRL_LONG 0x00000200
|
||||
#define DBR_CTRL_DOUBLE 0x00000400
|
||||
#define DBR_AL_LONG 0x00000800
|
||||
#define DBR_AL_DOUBLE 0x00001000
|
||||
|
||||
/**********************************************************************
|
||||
* The next page contains macros for defining requests.
|
||||
@@ -100,6 +102,9 @@ DBCORE_API extern int dbAccessDebugPUTF;
|
||||
epicsUInt16 severity; /* alarm severity*/\
|
||||
epicsUInt16 acks; /* alarm ack severity*/\
|
||||
epicsUInt16 ackt; /* Acknowledge transient alarms?*/
|
||||
#define DB_AMSG_SIZE 40
|
||||
#define DBRamsg \
|
||||
char amsg[DB_AMSG_SIZE];
|
||||
#define DB_UNITS_SIZE 16
|
||||
#define DBRunits \
|
||||
char units[DB_UNITS_SIZE]; /* units */
|
||||
@@ -112,7 +117,9 @@ DBCORE_API extern int dbAccessDebugPUTF;
|
||||
* too late to change now. DBRprecision must be padded to
|
||||
* maintain 8-byte alignment. */
|
||||
#define DBRtime \
|
||||
epicsTimeStamp time; /* time stamp*/
|
||||
epicsTimeStamp time; /* time stamp*/
|
||||
#define DBRutag \
|
||||
epicsUTag utag;
|
||||
#define DBRenumStrs \
|
||||
epicsUInt32 no_str; /* number of strings*/\
|
||||
epicsInt32 padenumStrs; /*padding to force 8 byte align*/\
|
||||
|
||||
@@ -279,6 +279,11 @@ support routines which write to the VAL field are responsible for setting UDF.
|
||||
special(SPC_NOMOD)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(AMSG,DBF_STRING) {
|
||||
prompt("Alarm Message")
|
||||
special(SPC_NOMOD)
|
||||
size(40)
|
||||
}
|
||||
field(NSTA,DBF_MENU) {
|
||||
prompt("New Alarm Status")
|
||||
special(SPC_NOMOD)
|
||||
@@ -291,6 +296,11 @@ support routines which write to the VAL field are responsible for setting UDF.
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(NAMSG,DBF_STRING) {
|
||||
prompt("New Alarm Message")
|
||||
special(SPC_NOMOD)
|
||||
size(40)
|
||||
}
|
||||
field(ACKS,DBF_MENU) {
|
||||
prompt("Alarm Ack Severity")
|
||||
special(SPC_NOMOD)
|
||||
@@ -514,6 +524,11 @@ field which is then used to acquire a timestamp.
|
||||
interest(2)
|
||||
extra("epicsTimeStamp time")
|
||||
}
|
||||
field(UTAG,DBF_UINT64) {
|
||||
prompt("Time Tag")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(FLNK,DBF_FWDLINK) {
|
||||
prompt("Forward Process Link")
|
||||
promptgroup("20 - Scan")
|
||||
|
||||
@@ -337,8 +337,8 @@ static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity)
|
||||
static long dbDbGetAlarmMsg(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen)
|
||||
{
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
dbCommon *precord = dbChannelRecord(chan);
|
||||
@@ -346,14 +346,20 @@ static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
*status = precord->stat;
|
||||
if (severity)
|
||||
*severity = precord->sevr;
|
||||
if (msgbuf && msgbuflen) {
|
||||
strncpy(msgbuf, precord->amsg, msgbuflen-1);
|
||||
msgbuf[msgbuflen-1] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp)
|
||||
static long dbDbGetTimeStampTag(const struct link *plink, epicsTimeStamp *pstamp, epicsUTag *ptag)
|
||||
{
|
||||
dbChannel *chan = linkChannel(plink);
|
||||
dbCommon *precord = dbChannelRecord(chan);
|
||||
*pstamp = precord->time;
|
||||
if(ptag)
|
||||
*ptag = precord->utag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -401,9 +407,11 @@ static lset dbDb_lset = {
|
||||
dbDbGetValue,
|
||||
dbDbGetControlLimits, dbDbGetGraphicLimits, dbDbGetAlarmLimits,
|
||||
dbDbGetPrecision, dbDbGetUnits,
|
||||
dbDbGetAlarm, dbDbGetTimeStamp,
|
||||
NULL, NULL,
|
||||
dbDbPutValue, NULL,
|
||||
dbDbScanFwdLink, doLocked
|
||||
dbDbScanFwdLink, doLocked,
|
||||
dbDbGetAlarmMsg,
|
||||
dbDbGetTimeStampTag,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ struct event_user {
|
||||
epicsMutexId lock;
|
||||
epicsEventId ppendsem; /* Wait while empty */
|
||||
epicsEventId pflush_sem; /* wait for flush */
|
||||
epicsEventId pexitsem; /* wait for event task to join */
|
||||
|
||||
EXTRALABORFUNC *extralabor_sub;/* off load to event task */
|
||||
void *extralabor_arg;/* parameter to above */
|
||||
@@ -122,6 +123,8 @@ static char *EVENT_PEND_NAME = "eventTask";
|
||||
|
||||
static struct evSubscrip canceledEvent;
|
||||
|
||||
static epicsMutexId stopSync;
|
||||
|
||||
static unsigned short ringSpace ( const struct event_que *pevq )
|
||||
{
|
||||
if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) {
|
||||
@@ -260,6 +263,10 @@ int dbel ( const char *pname, unsigned level )
|
||||
*/
|
||||
void db_init_event_freelists (void)
|
||||
{
|
||||
if (!stopSync) {
|
||||
stopSync = epicsMutexMustCreate();
|
||||
}
|
||||
|
||||
if (!dbevEventUserFreeList) {
|
||||
freeListInitPvt(&dbevEventUserFreeList,
|
||||
sizeof(struct event_user),8);
|
||||
@@ -299,6 +306,9 @@ dbEventCtx db_init_events (void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Flag will be cleared when event task starts */
|
||||
evUser->pendexit = TRUE;
|
||||
|
||||
evUser->firstque.evUser = evUser;
|
||||
evUser->firstque.writelock = epicsMutexCreate();
|
||||
if (!evUser->firstque.writelock)
|
||||
@@ -313,6 +323,9 @@ dbEventCtx db_init_events (void)
|
||||
evUser->lock = epicsMutexCreate();
|
||||
if (!evUser->lock)
|
||||
goto fail;
|
||||
evUser->pexitsem = epicsEventCreate(epicsEventEmpty);
|
||||
if (!evUser->pexitsem)
|
||||
goto fail;
|
||||
|
||||
evUser->flowCtrlMode = FALSE;
|
||||
evUser->extraLaborBusy = FALSE;
|
||||
@@ -327,6 +340,8 @@ fail:
|
||||
epicsEventDestroy (evUser->ppendsem);
|
||||
if(evUser->pflush_sem)
|
||||
epicsEventDestroy (evUser->pflush_sem);
|
||||
if(evUser->pexitsem)
|
||||
epicsEventDestroy (evUser->pexitsem);
|
||||
freeListFree(dbevEventUserFreeList,evUser);
|
||||
return NULL;
|
||||
}
|
||||
@@ -347,6 +362,7 @@ DBCORE_API void db_cleanup_events(void)
|
||||
dbevFieldLogFreeList = NULL;
|
||||
}
|
||||
|
||||
/* intentionally leak stopSync to avoid possible shutdown races */
|
||||
/*
|
||||
* DB_CLOSE_EVENTS()
|
||||
*
|
||||
@@ -368,15 +384,31 @@ void db_close_events (dbEventCtx ctx)
|
||||
* hazardous to the system's health.
|
||||
*/
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
evUser->pendexit = TRUE;
|
||||
if(!evUser->pendexit) { /* event task running */
|
||||
evUser->pendexit = TRUE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
/* notify the waiting task */
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
/* wait for task to exit */
|
||||
epicsEventMustWait(evUser->pexitsem);
|
||||
epicsThreadMustJoin(evUser->taskid);
|
||||
|
||||
epicsMutexMustLock ( evUser->lock );
|
||||
}
|
||||
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
|
||||
/* notify the waiting task */
|
||||
epicsEventSignal(evUser->ppendsem);
|
||||
epicsMutexMustLock (stopSync);
|
||||
|
||||
if(evUser->taskid)
|
||||
epicsThreadMustJoin(evUser->taskid);
|
||||
/* evUser has been deleted by the worker */
|
||||
epicsEventDestroy(evUser->pexitsem);
|
||||
epicsEventDestroy(evUser->ppendsem);
|
||||
epicsEventDestroy(evUser->pflush_sem);
|
||||
epicsMutexDestroy(evUser->lock);
|
||||
|
||||
epicsMutexUnlock (stopSync);
|
||||
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -675,7 +707,10 @@ static db_field_log* db_create_field_log (struct dbChannel *chan, int use_val)
|
||||
struct dbCommon *prec = dbChannelRecord(chan);
|
||||
pLog->stat = prec->stat;
|
||||
pLog->sevr = prec->sevr;
|
||||
strncpy(pLog->amsg, prec->amsg, sizeof(pLog->amsg)-1);
|
||||
pLog->amsg[sizeof(pLog->amsg)-1] = '\0';
|
||||
pLog->time = prec->time;
|
||||
pLog->utag = prec->utag;
|
||||
pLog->field_type = dbChannelFieldType(chan);
|
||||
pLog->field_size = dbChannelFieldSize(chan);
|
||||
pLog->no_elements = dbChannelElements(chan);
|
||||
@@ -1060,18 +1095,17 @@ static void event_task (void *pParm)
|
||||
}
|
||||
}
|
||||
|
||||
epicsEventDestroy(evUser->ppendsem);
|
||||
epicsEventDestroy(evUser->pflush_sem);
|
||||
epicsMutexDestroy(evUser->lock);
|
||||
|
||||
if (dbevEventUserFreeList)
|
||||
freeListFree(dbevEventUserFreeList, evUser);
|
||||
else
|
||||
fprintf(stderr, "%s exiting but dbevEventUserFreeList already NULL\n",
|
||||
__FUNCTION__);
|
||||
|
||||
taskwdRemove(epicsThreadGetIdSelf());
|
||||
|
||||
/* use stopSync to ensure pexitsem is not destroy'd
|
||||
* until epicsEventSignal() has returned.
|
||||
*/
|
||||
epicsMutexMustLock (stopSync);
|
||||
|
||||
epicsEventSignal(evUser->pexitsem);
|
||||
|
||||
epicsMutexUnlock(stopSync);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1111,6 +1145,7 @@ int db_start_events (
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_ERROR;
|
||||
}
|
||||
evUser->pendexit = FALSE;
|
||||
epicsMutexUnlock ( evUser->lock );
|
||||
return DB_EVENT_OK;
|
||||
}
|
||||
|
||||
@@ -313,10 +313,16 @@ long dbTryGetLink(struct link *plink, short dbrType, void *pbuffer,
|
||||
return plset->getValue(plink, dbrType, pbuffer, pnRequest);
|
||||
}
|
||||
|
||||
static
|
||||
void setLinkAlarm(struct link* plink)
|
||||
{
|
||||
recGblSetSevrMsg(plink->precord, LINK_ALARM, INVALID_ALARM,
|
||||
"field %s", dbLinkFieldName(plink));
|
||||
}
|
||||
|
||||
long dbGetLink(struct link *plink, short dbrType, void *pbuffer,
|
||||
long *poptions, long *pnRequest)
|
||||
{
|
||||
struct dbCommon *precord = plink->precord;
|
||||
long status;
|
||||
|
||||
if (poptions && *poptions) {
|
||||
@@ -328,7 +334,7 @@ long dbGetLink(struct link *plink, short dbrType, void *pbuffer,
|
||||
if (status == S_db_noLSET)
|
||||
return -1;
|
||||
if (status)
|
||||
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
|
||||
setLinkAlarm(plink);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -385,24 +391,42 @@ long dbGetUnits(const struct link *plink, char *units, int unitsSize)
|
||||
}
|
||||
|
||||
long dbGetAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity)
|
||||
epicsEnum16 *severity)
|
||||
{
|
||||
return dbGetAlarmMsg(plink, status, severity, NULL, 0);
|
||||
}
|
||||
|
||||
long dbGetAlarmMsg(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen)
|
||||
{
|
||||
lset *plset = plink->lset;
|
||||
|
||||
if (!plset || !plset->getAlarm)
|
||||
if (plset && plset->getAlarmMsg) {
|
||||
return plset->getAlarmMsg(plink, status, severity, msgbuf, msgbuflen);
|
||||
} else if(plset && plset->getAlarm) {
|
||||
return plset->getAlarm(plink, status, severity);
|
||||
} else {
|
||||
return S_db_noLSET;
|
||||
|
||||
return plset->getAlarm(plink, status, severity);
|
||||
}
|
||||
}
|
||||
|
||||
long dbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp)
|
||||
{
|
||||
return dbGetTimeStampTag(plink, pstamp, NULL);
|
||||
}
|
||||
|
||||
long dbGetTimeStampTag(const struct link *plink,
|
||||
epicsTimeStamp *pstamp, epicsUTag *ptag)
|
||||
{
|
||||
lset *plset = plink->lset;
|
||||
|
||||
if (!plset || !plset->getTimeStamp)
|
||||
if (plset && plset->getTimeStampTag) {
|
||||
return plset->getTimeStampTag(plink, pstamp, ptag);
|
||||
} else if(plset && plset->getTimeStamp) {
|
||||
return plset->getTimeStamp(plink, pstamp);
|
||||
} else {
|
||||
return S_db_noLSET;
|
||||
|
||||
return plset->getTimeStamp(plink, pstamp);
|
||||
}
|
||||
}
|
||||
|
||||
long dbPutLink(struct link *plink, short dbrType, const void *pbuffer,
|
||||
@@ -416,9 +440,7 @@ long dbPutLink(struct link *plink, short dbrType, const void *pbuffer,
|
||||
|
||||
status = plset->putValue(plink, dbrType, pbuffer, nRequest);
|
||||
if (status) {
|
||||
struct dbCommon *precord = plink->precord;
|
||||
|
||||
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
|
||||
setLinkAlarm(plink);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -443,9 +465,7 @@ long dbPutLinkAsync(struct link *plink, short dbrType, const void *pbuffer,
|
||||
|
||||
status = plset->putAsync(plink, dbrType, pbuffer, nRequest);
|
||||
if (status) {
|
||||
struct dbCommon *precord = plink->precord;
|
||||
|
||||
recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
|
||||
setLinkAlarm(plink);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -361,6 +361,29 @@ typedef struct lset {
|
||||
* @returns status value
|
||||
*/
|
||||
long (*doLocked)(struct link *plink, dbLinkUserCallback rtn, void *priv);
|
||||
|
||||
/** @brief Extended version of getAlarm
|
||||
*
|
||||
* Equivalent of getAlarm() and also copy out alarm message string.
|
||||
* The msgbuf argument may be NULL and/or msgbuflen==0, in which case
|
||||
* the effect must be the same as a call to getAlarm().
|
||||
*
|
||||
* Implementations must write a trailing nil to msgbuf whenever
|
||||
* @code msgbuf!=NULL && msgbuflen>0 @endcode .
|
||||
*
|
||||
* @since 7.0.6
|
||||
*/
|
||||
long (*getAlarmMsg)(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen);
|
||||
|
||||
/** @brief Extended version of getTimeStamp
|
||||
*
|
||||
* Equivalent of getTimeStamp() and also copy out time tag.
|
||||
* ptag may be NULL.
|
||||
*
|
||||
* @since Added after 7.0.6
|
||||
*/
|
||||
long (*getTimeStampTag)(const struct link *plink, epicsTimeStamp *pstamp, epicsUTag *ptag);
|
||||
} lset;
|
||||
|
||||
#define dbGetSevr(link, sevr) \
|
||||
@@ -402,8 +425,20 @@ DBCORE_API long dbGetUnits(const struct link *plink, char *units,
|
||||
int unitsSize);
|
||||
DBCORE_API long dbGetAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity);
|
||||
/** Get link alarm and message string.
|
||||
* To ensure the complete message string is copied, ensure @code msgbuflen >= sizeof (dbCommon::amsg) @endcode .
|
||||
* A trailing nil will be added whenever @code msgbuflen > 0 @endcode .
|
||||
* @since 7.0.6
|
||||
*/
|
||||
DBCORE_API long dbGetAlarmMsg(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen);
|
||||
#define dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN) dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN)
|
||||
DBCORE_API long dbGetTimeStamp(const struct link *plink,
|
||||
epicsTimeStamp *pstamp);
|
||||
/** @since 7.0.6 */
|
||||
DBCORE_API long dbGetTimeStampTag(const struct link *plink,
|
||||
epicsTimeStamp *pstamp, epicsUTag *ptag);
|
||||
#define dbGetTimeStampTag(LINK, STAMP, TAG) dbGetTimeStampTag(LINK, STAMP, TAG)
|
||||
DBCORE_API long dbPutLink(struct link *plink, short dbrType,
|
||||
const void *pbuffer, long nRequest);
|
||||
DBCORE_API void dbLinkAsyncComplete(struct link *plink);
|
||||
|
||||
@@ -266,7 +266,7 @@ done:
|
||||
void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long count, const void *pbuf)
|
||||
{
|
||||
dbChannel *chan = dbChannelCreate(pv);
|
||||
long status;
|
||||
long status = -1;
|
||||
|
||||
if(!chan || (status=dbChannelOpen(chan))) {
|
||||
testFail("Channel error (%p, %ld) : %s", chan, status, pv);
|
||||
@@ -289,7 +289,7 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
|
||||
const long vSize = dbValueSize(dbfType);
|
||||
const long nStore = vSize * nRequest;
|
||||
long status = S_dbLib_recNotFound;
|
||||
char *gbuf, *gstore;
|
||||
char *gbuf, *gstore = NULL;
|
||||
const char *pbuf = pbufraw;
|
||||
|
||||
if(!chan || (status=dbChannelOpen(chan))) {
|
||||
|
||||
@@ -113,8 +113,10 @@ typedef struct db_field_log {
|
||||
unsigned char mask; /* DBE_* mask */
|
||||
/* the following are used for value and reference types */
|
||||
epicsTimeStamp time; /* Time stamp */
|
||||
epicsUTag utag;
|
||||
unsigned short stat; /* Alarm Status */
|
||||
unsigned short sevr; /* Alarm Severity */
|
||||
char amsg[40];
|
||||
short field_type; /* DBF type of data */
|
||||
short field_size; /* Size of a single element */
|
||||
long no_elements; /* No of valid array elements */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "epicsMath.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsStdlib.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "epicsTime.h"
|
||||
#include "errlog.h"
|
||||
|
||||
@@ -184,6 +185,11 @@ unsigned short recGblResetAlarms(void *precord)
|
||||
if (new_sevr > INVALID_ALARM)
|
||||
new_sevr = INVALID_ALARM;
|
||||
|
||||
if(strcmp(pdbc->namsg, pdbc->amsg)!=0) {
|
||||
strcpy(pdbc->amsg, pdbc->namsg);
|
||||
stat_mask = DBE_ALARM;
|
||||
}
|
||||
|
||||
pdbc->stat = new_stat;
|
||||
pdbc->sevr = new_sevr;
|
||||
pdbc->nsta = 0;
|
||||
@@ -198,6 +204,7 @@ unsigned short recGblResetAlarms(void *precord)
|
||||
}
|
||||
if (stat_mask) {
|
||||
db_post_events(pdbc, &pdbc->stat, stat_mask);
|
||||
db_post_events(pdbc, &pdbc->amsg, stat_mask);
|
||||
val_mask = DBE_ALARM;
|
||||
|
||||
if (!pdbc->ackt || new_sevr >= pdbc->acks) {
|
||||
@@ -211,18 +218,44 @@ unsigned short recGblResetAlarms(void *precord)
|
||||
}
|
||||
return val_mask;
|
||||
}
|
||||
int recGblSetSevrMsg(void *precord, epicsEnum16 new_stat,
|
||||
epicsEnum16 new_sevr,
|
||||
const char *msg, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
ret = recGblSetSevrVMsg(precord, new_stat, new_sevr, msg, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsEnum16 new_sevr)
|
||||
int recGblSetSevrVMsg(void *precord, epicsEnum16 new_stat,
|
||||
epicsEnum16 new_sevr,
|
||||
const char *msg, va_list args)
|
||||
{
|
||||
struct dbCommon *prec = precord;
|
||||
if (prec->nsev < new_sevr) {
|
||||
prec->nsta = new_stat;
|
||||
prec->nsev = new_sevr;
|
||||
if(msg) {
|
||||
epicsVsnprintf(prec->namsg, sizeof(prec->namsg)-1, msg, args);
|
||||
prec->namsg[sizeof(prec->namsg)-1] = '\0';
|
||||
|
||||
} else {
|
||||
prec->namsg[0] = '\0';
|
||||
}
|
||||
prec->namsg[sizeof(prec->namsg)-1] = '\0';
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsEnum16 new_sevr)
|
||||
{
|
||||
return recGblSetSevrMsg(precord, new_stat, new_sevr, NULL);
|
||||
}
|
||||
|
||||
void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
||||
epicsEnum16 sevr)
|
||||
{
|
||||
@@ -271,7 +304,7 @@ void recGblGetTimeStampSimm(void *pvoid, const epicsEnum16 simm, struct link *si
|
||||
|
||||
if (!dbLinkIsConstant(plink)) {
|
||||
if (plink->flags & DBLINK_FLAG_TSELisTIME) {
|
||||
if (dbGetTimeStamp(plink, &prec->time))
|
||||
if (dbGetTimeStampTag(plink, &prec->time, &prec->utag))
|
||||
errlogPrintf("recGblGetTimeStamp: dbGetTimeStamp failed for %s.TSEL\n",
|
||||
prec->name);
|
||||
return;
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#ifndef INCrecGblh
|
||||
#define INCrecGblh 1
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "compilerDependencies.h"
|
||||
#include "epicsTypes.h"
|
||||
#include "dbCoreAPI.h"
|
||||
|
||||
@@ -22,6 +25,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Feature test macro for alarm message (AMSG) field and support
|
||||
*
|
||||
* Covers addition of dbCommon::amsg, recGblSetSevrMsg(), lset::getAlarmMsg()
|
||||
*
|
||||
* @since 7.0.6
|
||||
*/
|
||||
#define HAS_ALARM_MESSAGE 1
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Structures needed for args */
|
||||
@@ -62,6 +73,12 @@ DBCORE_API int recGblSetSevr(void *precord, epicsEnum16 new_stat,
|
||||
epicsEnum16 new_sevr);
|
||||
DBCORE_API void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat,
|
||||
epicsEnum16 sevr);
|
||||
DBCORE_API int recGblSetSevrMsg(void *precord, epicsEnum16 new_stat,
|
||||
epicsEnum16 new_sevr,
|
||||
const char *msg, ...) EPICS_PRINTF_STYLE(4,5);
|
||||
DBCORE_API int recGblSetSevrVMsg(void *precord, epicsEnum16 new_stat,
|
||||
epicsEnum16 new_sevr,
|
||||
const char *msg, va_list args);
|
||||
DBCORE_API void recGblFwdLink(void *precord);
|
||||
DBCORE_API void recGblGetTimeStamp(void *precord);
|
||||
DBCORE_API void recGblGetTimeStampSimm(void *prec, const epicsEnum16 simm, struct link *siol);
|
||||
|
||||
@@ -63,7 +63,7 @@ static long read_lsi(lsiRecord *prec)
|
||||
prec->val[0] = 0;
|
||||
prec->len = 1;
|
||||
prec->udf = TRUE;
|
||||
recGblSetSevr(prec, UDF_ALARM, prec->udfs);
|
||||
recGblSetSevrMsg(prec, UDF_ALARM, prec->udfs, "No such ENV");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -114,7 +114,7 @@ static long read_stringin(stringinRecord *prec)
|
||||
else {
|
||||
prec->val[0] = 0;
|
||||
prec->udf = TRUE;
|
||||
recGblSetSevr(prec, UDF_ALARM, prec->udfs);
|
||||
recGblSetSevrMsg(prec, UDF_ALARM, prec->udfs, "No such ENV");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -16,6 +16,7 @@ dbRecStd_SRCS += dbnd.c
|
||||
dbRecStd_SRCS += arr.c
|
||||
dbRecStd_SRCS += sync.c
|
||||
dbRecStd_SRCS += decimate.c
|
||||
dbRecStd_SRCS += utag.c
|
||||
|
||||
HTMLS += filters.html
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ The following filters are available in this release:
|
||||
|
||||
=item * L<Decimation|/"Decimation Filter dec">
|
||||
|
||||
=item * L<UTag|/"UTag Filter utag">
|
||||
|
||||
=back
|
||||
|
||||
=head2 Using Filters
|
||||
@@ -285,3 +287,26 @@ once every minute:
|
||||
...
|
||||
|
||||
=cut
|
||||
|
||||
registrar(utagInitialize)
|
||||
|
||||
=head3 UTag Filter C<"utag">
|
||||
|
||||
This filter applies a test UTAG&M==V to the value taken from the UTAG record field
|
||||
and drops those updates which evaluate as false.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
=over
|
||||
|
||||
=item Mask C<"M">
|
||||
|
||||
Bit mask.
|
||||
|
||||
=item Value C<"V">
|
||||
|
||||
Required value.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2020 Michael Davidsaver
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <caeventmask.h>
|
||||
#include <chfPlugin.h>
|
||||
#include <dbCommon.h>
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsExport.h>
|
||||
|
||||
typedef struct {
|
||||
epicsInt32 mask, value;
|
||||
int first;
|
||||
} utagPvt;
|
||||
|
||||
static const
|
||||
chfPluginArgDef opts[] = {
|
||||
chfInt32(utagPvt, mask, "M", 0, 1),
|
||||
chfInt32(utagPvt, value, "V", 0, 1),
|
||||
chfPluginArgEnd
|
||||
};
|
||||
|
||||
static void * allocPvt(void)
|
||||
{
|
||||
utagPvt *pvt;
|
||||
pvt = calloc(1, sizeof(utagPvt));
|
||||
pvt->mask = 0xffffffff;
|
||||
return pvt;
|
||||
}
|
||||
|
||||
static void freePvt(void *pvt)
|
||||
{
|
||||
free(pvt);
|
||||
}
|
||||
|
||||
static int parse_ok(void *raw)
|
||||
{
|
||||
utagPvt *pvt = (utagPvt*)raw;
|
||||
pvt->first = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static db_field_log* filter(void* raw, dbChannel *chan, db_field_log *pfl)
|
||||
{
|
||||
utagPvt *pvt = (utagPvt*)raw;
|
||||
epicsUTag utag = pfl->utag;
|
||||
int drop = (utag&pvt->mask)!=pvt->value;
|
||||
|
||||
if(pfl->ctx!=dbfl_context_event || pfl->mask&DBE_PROPERTY) {
|
||||
/* never drop for reads, or property events */
|
||||
|
||||
} else if(pvt->first) {
|
||||
/* never drop first */
|
||||
pvt->first = 0;
|
||||
|
||||
} else if(drop) {
|
||||
db_delete_field_log(pfl);
|
||||
pfl = NULL;
|
||||
}
|
||||
|
||||
return pfl;
|
||||
}
|
||||
|
||||
static void channelRegisterPre(dbChannel *chan, void *pvt,
|
||||
chPostEventFunc **cb_out, void **arg_out, db_field_log *probe)
|
||||
{
|
||||
*cb_out = filter;
|
||||
*arg_out = pvt;
|
||||
}
|
||||
|
||||
static void channel_report(dbChannel *chan, void *raw, int level, const unsigned short indent)
|
||||
{
|
||||
utagPvt *pvt = (utagPvt*)raw;
|
||||
printf("%*sutag : mask=0x%08x value=0x%08x\n", indent, "", (epicsUInt32)pvt->mask, (epicsUInt32)pvt->value);
|
||||
}
|
||||
|
||||
static const
|
||||
chfPluginIf pif = {
|
||||
allocPvt,
|
||||
freePvt,
|
||||
NULL, /* parse_error */
|
||||
parse_ok, /* parse_ok */
|
||||
NULL, /* channel_open */
|
||||
channelRegisterPre,
|
||||
NULL, /* channelRegisterPost */
|
||||
channel_report,
|
||||
NULL, /* channel_close */
|
||||
};
|
||||
|
||||
static
|
||||
void utagInitialize(void)
|
||||
{
|
||||
chfPluginRegister("utag", &pif, opts);
|
||||
}
|
||||
epicsExportRegistrar(utagInitialize);
|
||||
@@ -53,6 +53,7 @@ typedef struct calc_link {
|
||||
} pstate;
|
||||
epicsEnum16 stat;
|
||||
epicsEnum16 sevr;
|
||||
char amsg[DB_AMSG_SIZE];
|
||||
short prec;
|
||||
char *expr;
|
||||
char *major;
|
||||
@@ -66,6 +67,7 @@ typedef struct calc_link {
|
||||
struct link out;
|
||||
double arg[CALCPERFORM_NARGS];
|
||||
epicsTimeStamp time;
|
||||
epicsUTag utag;
|
||||
double val;
|
||||
} calc_link;
|
||||
|
||||
@@ -385,9 +387,10 @@ static void lnkCalc_report(const jlink *pjlink, int level, int indent)
|
||||
|
||||
if (level > 0) {
|
||||
if (clink->sevr)
|
||||
printf("%*s Alarm: %s, %s\n", indent, "",
|
||||
printf("%*s Alarm: %s, %s, \"%s\"\n", indent, "",
|
||||
epicsAlarmSeverityStrings[clink->sevr],
|
||||
epicsAlarmConditionStrings[clink->stat]);
|
||||
epicsAlarmConditionStrings[clink->stat],
|
||||
clink->amsg);
|
||||
|
||||
if (clink->post_major)
|
||||
printf("%*s Major expression: \"%s\"\n", indent, "",
|
||||
@@ -532,6 +535,7 @@ static long lnkCalc_getElements(const struct link *plink, long *nelements)
|
||||
struct lcvt {
|
||||
double *pval;
|
||||
epicsTimeStamp *ptime;
|
||||
epicsUTag *ptag;
|
||||
};
|
||||
|
||||
static long readLocked(struct link *pinp, void *vvt)
|
||||
@@ -541,7 +545,7 @@ static long readLocked(struct link *pinp, void *vvt)
|
||||
long status = dbGetLink(pinp, DBR_DOUBLE, pvt->pval, NULL, &nReq);
|
||||
|
||||
if (!status && pvt->ptime)
|
||||
dbGetTimeStamp(pinp, pvt->ptime);
|
||||
dbGetTimeStampTag(pinp, pvt->ptime, pvt->ptag);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -567,7 +571,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
long nReq = 1;
|
||||
|
||||
if (i == clink->tinp) {
|
||||
struct lcvt vt = {&clink->arg[i], &clink->time};
|
||||
struct lcvt vt = {&clink->arg[i], &clink->time, &clink->utag};
|
||||
|
||||
status = dbLinkDoLocked(child, readLocked, &vt);
|
||||
if (status == S_db_noLSET)
|
||||
@@ -576,6 +580,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
if (dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime) {
|
||||
prec->time = clink->time;
|
||||
prec->utag = clink->utag;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -583,6 +588,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
}
|
||||
clink->stat = 0;
|
||||
clink->sevr = 0;
|
||||
clink->amsg[0] = '\0';
|
||||
|
||||
if (clink->post_expr) {
|
||||
status = calcPerform(clink->arg, &clink->val, clink->post_expr);
|
||||
@@ -604,7 +610,8 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
if (!status && alval) {
|
||||
clink->stat = LINK_ALARM;
|
||||
clink->sevr = MAJOR_ALARM;
|
||||
recGblSetSevr(prec, clink->stat, clink->sevr);
|
||||
strcpy(clink->amsg, "post_major error");
|
||||
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_major error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,7 +622,8 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
if (!status && alval) {
|
||||
clink->stat = LINK_ALARM;
|
||||
clink->sevr = MINOR_ALARM;
|
||||
recGblSetSevr(prec, clink->stat, clink->sevr);
|
||||
strcpy(clink->amsg, "post_minor error");
|
||||
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_minor error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,7 +651,7 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
|
||||
long nReq = 1;
|
||||
|
||||
if (i == clink->tinp) {
|
||||
struct lcvt vt = {&clink->arg[i], &clink->time};
|
||||
struct lcvt vt = {&clink->arg[i], &clink->time, &clink->utag};
|
||||
|
||||
status = dbLinkDoLocked(child, readLocked, &vt);
|
||||
if (status == S_db_noLSET)
|
||||
@@ -652,6 +660,7 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
|
||||
if (dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime) {
|
||||
prec->time = clink->time;
|
||||
prec->utag = clink->utag;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -659,6 +668,7 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
|
||||
}
|
||||
clink->stat = 0;
|
||||
clink->sevr = 0;
|
||||
clink->amsg[0] = '\0';
|
||||
|
||||
/* Get the value being output as VAL */
|
||||
status = conv(pbuffer, &clink->val, NULL);
|
||||
@@ -673,7 +683,8 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
|
||||
if (!status && alval) {
|
||||
clink->stat = LINK_ALARM;
|
||||
clink->sevr = MAJOR_ALARM;
|
||||
recGblSetSevr(prec, clink->stat, clink->sevr);
|
||||
strcpy(clink->amsg, "post_major error");
|
||||
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_major error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,7 +695,8 @@ static long lnkCalc_putValue(struct link *plink, short dbrType,
|
||||
if (!status && alval) {
|
||||
clink->stat = LINK_ALARM;
|
||||
clink->sevr = MINOR_ALARM;
|
||||
recGblSetSevr(prec, clink->stat, clink->sevr);
|
||||
strcpy(clink->amsg, "post_major error");
|
||||
recGblSetSevrMsg(prec, clink->stat, clink->sevr, "post_minor error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,8 +730,8 @@ static long lnkCalc_getUnits(const struct link *plink, char *units, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity)
|
||||
static long lnkCalc_getAlarmMsg(const struct link *plink, epicsEnum16 *status,
|
||||
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
@@ -728,17 +740,23 @@ static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
*status = clink->stat;
|
||||
if (severity)
|
||||
*severity = clink->sevr;
|
||||
if (msgbuf && msgbuflen) {
|
||||
strncpy(msgbuf, clink->amsg, msgbuflen-1);
|
||||
msgbuf[msgbuflen-1] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lnkCalc_getTimestamp(const struct link *plink, epicsTimeStamp *pstamp)
|
||||
static long lnkCalc_getTimestampTag(const struct link *plink, epicsTimeStamp *pstamp, epicsUTag *ptag)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
if (clink->tinp >= 0) {
|
||||
*pstamp = clink->time;
|
||||
if(ptag)
|
||||
*ptag = clink->utag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -761,9 +779,11 @@ static lset lnkCalc_lset = {
|
||||
lnkCalc_getValue,
|
||||
NULL, NULL, NULL,
|
||||
lnkCalc_getPrecision, lnkCalc_getUnits,
|
||||
lnkCalc_getAlarm, lnkCalc_getTimestamp,
|
||||
NULL, NULL,
|
||||
lnkCalc_putValue, NULL,
|
||||
NULL, doLocked
|
||||
NULL, doLocked,
|
||||
lnkCalc_getAlarmMsg,
|
||||
lnkCalc_getTimestampTag,
|
||||
};
|
||||
|
||||
static jlif lnkCalcIf = {
|
||||
|
||||
@@ -432,7 +432,7 @@ static void convert(aiRecord *prec)
|
||||
|
||||
default: /* must use breakpoint table */
|
||||
if (cvtRawToEngBpt(&val,prec->linr,prec->init,(void *)&prec->pbrk,&prec->lbrk)!=0) {
|
||||
recGblSetSevr(prec,SOFT_ALARM,MAJOR_ALARM);
|
||||
recGblSetSevrMsg(prec,SOFT_ALARM,MAJOR_ALARM, "BPT Error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ static long process(struct dbCommon *pcommon)
|
||||
}
|
||||
if (fetch_values(prec) == 0) {
|
||||
if (calcPerform(&prec->a, &prec->val, prec->rpcl)) {
|
||||
recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM);
|
||||
recGblSetSevrMsg(prec, CALC_ALARM, INVALID_ALARM, "calcPerform");
|
||||
} else {
|
||||
prec->udf = isnan(prec->val);
|
||||
}
|
||||
@@ -610,7 +610,7 @@ static void execOutput(calcoutRecord *prec)
|
||||
break;
|
||||
case calcoutDOPT_Use_OVAL:
|
||||
if (calcPerform(&prec->a, &prec->oval, prec->orpc)) {
|
||||
recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM);
|
||||
recGblSetSevrMsg(prec, CALC_ALARM, INVALID_ALARM, "OCAL calcPerform");
|
||||
} else {
|
||||
prec->udf = isnan(prec->oval);
|
||||
}
|
||||
@@ -770,7 +770,7 @@ static long writeValue(calcoutRecord *prec)
|
||||
|
||||
if (!pcalcoutDSET || !pcalcoutDSET->write) {
|
||||
errlogPrintf("%s DSET write does not exist\n", prec->name);
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
recGblSetSevrMsg(prec, SOFT_ALARM, INVALID_ALARM, "DSET write does not exist");
|
||||
prec->pact = TRUE;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,5 @@ softIoc_LIBS = $(EPICS_BASE_IOC_LIBS)
|
||||
|
||||
DB += softIocExit.db
|
||||
|
||||
FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
|
||||
|
||||
CLEANS += epicsInstallDir.h
|
||||
|
||||
|
||||
@@ -249,7 +249,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
} else {
|
||||
if (loadedDb || ranScript) {
|
||||
epicsThreadExitMain();
|
||||
// non-interactive IOC. spin forever
|
||||
while(true) {
|
||||
epicsThreadSleep(1000.0);
|
||||
}
|
||||
|
||||
} else {
|
||||
usage(argv[0], dbd_file);
|
||||
|
||||
@@ -40,7 +40,6 @@ HTMLS += dbdToHtml.html
|
||||
|
||||
# Build Package Config Files
|
||||
|
||||
FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION))
|
||||
C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CPPFLAGS))))
|
||||
C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CFLAGS))))
|
||||
PKGVARS += FINAL_LOCATION OS_CLASS CMPLR_CLASS C_CFLAGS LDFLAGS LDLIBS
|
||||
|
||||
Reference in New Issue
Block a user