Merge changes from 3.16 branch into 7.0
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include "epicsExport.h"
|
||||
#include "link.h"
|
||||
#include "recSup.h"
|
||||
#include "dbUnitTest.h" /* for testSyncCallback() */
|
||||
|
||||
|
||||
static int callbackQueueSize = 2000;
|
||||
@@ -352,3 +353,86 @@ void callbackRequestProcessCallbackDelayed(CALLBACK *pcallback,
|
||||
callbackSetProcess(pcallback, Priority, pRec);
|
||||
callbackRequestDelayed(pcallback, seconds);
|
||||
}
|
||||
|
||||
/* Sync. process of testSyncCallback()
|
||||
*
|
||||
* 1. For each priority, make a call to callbackRequest() for each worker.
|
||||
* 2. Wait until all callbacks are concurrently being executed
|
||||
* 3. Last worker to begin executing signals success and begins waking up other workers
|
||||
* 4. Last worker to wake signals testSyncCallback() to complete
|
||||
*/
|
||||
typedef struct {
|
||||
epicsEventId wait_phase2, wait_phase4;
|
||||
int nphase2, nphase3;
|
||||
epicsCallback cb;
|
||||
} sync_helper;
|
||||
|
||||
static void sync_callback(epicsCallback *cb)
|
||||
{
|
||||
sync_helper *helper;
|
||||
callbackGetUser(helper, cb);
|
||||
|
||||
testGlobalLock();
|
||||
|
||||
assert(helper->nphase2 > 0);
|
||||
if(--helper->nphase2!=0) {
|
||||
/* we are _not_ the last to start. */
|
||||
testGlobalUnlock();
|
||||
epicsEventMustWait(helper->wait_phase2);
|
||||
testGlobalLock();
|
||||
}
|
||||
|
||||
/* we are either the last to start, or have been
|
||||
* woken by the same and must pass the wakeup along
|
||||
*/
|
||||
epicsEventMustTrigger(helper->wait_phase2);
|
||||
|
||||
assert(helper->nphase2 == 0);
|
||||
assert(helper->nphase3 > 0);
|
||||
|
||||
if(--helper->nphase3==0) {
|
||||
/* we are the last to wake up. wake up testSyncCallback() */
|
||||
epicsEventMustTrigger(helper->wait_phase4);
|
||||
}
|
||||
|
||||
testGlobalUnlock();
|
||||
}
|
||||
|
||||
void testSyncCallback(void)
|
||||
{
|
||||
sync_helper helper[NUM_CALLBACK_PRIORITIES];
|
||||
unsigned i;
|
||||
|
||||
testDiag("Begin testSyncCallback()");
|
||||
|
||||
for(i=0; i<NUM_CALLBACK_PRIORITIES; i++) {
|
||||
helper[i].wait_phase2 = epicsEventMustCreate(epicsEventEmpty);
|
||||
helper[i].wait_phase4 = epicsEventMustCreate(epicsEventEmpty);
|
||||
|
||||
/* no real need to lock here, but do so anyway so that valgrind can establish
|
||||
* the locking requirements for sync_helper.
|
||||
*/
|
||||
testGlobalLock();
|
||||
helper[i].nphase2 = helper[i].nphase3 = callbackQueue[i].threadsRunning;
|
||||
testGlobalUnlock();
|
||||
|
||||
callbackSetUser(&helper[i], &helper[i].cb);
|
||||
callbackSetPriority(i, &helper[i].cb);
|
||||
callbackSetCallback(sync_callback, &helper[i].cb);
|
||||
|
||||
callbackRequest(&helper[i].cb);
|
||||
}
|
||||
|
||||
for(i=0; i<NUM_CALLBACK_PRIORITIES; i++) {
|
||||
epicsEventMustWait(helper[i].wait_phase4);
|
||||
}
|
||||
|
||||
for(i=0; i<NUM_CALLBACK_PRIORITIES; i++) {
|
||||
testGlobalLock();
|
||||
epicsEventDestroy(helper[i].wait_phase2);
|
||||
epicsEventDestroy(helper[i].wait_phase4);
|
||||
testGlobalUnlock();
|
||||
}
|
||||
|
||||
testDiag("Complete testSyncCallback()");
|
||||
}
|
||||
|
||||
@@ -42,7 +42,9 @@ typedef struct callbackPvt {
|
||||
int priority;
|
||||
void *user; /*for use by callback user*/
|
||||
void *timer; /*for use by callback itself*/
|
||||
}CALLBACK;
|
||||
}epicsCallback;
|
||||
|
||||
typedef epicsCallback CALLBACK;
|
||||
|
||||
typedef void (*CALLBACKFUNC)(struct callbackPvt*);
|
||||
|
||||
|
||||
@@ -293,10 +293,14 @@ static void get_alarm(DBADDR *paddr, char **ppbuffer,
|
||||
if (*options & DBR_AL_LONG) {
|
||||
struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer;
|
||||
|
||||
pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit;
|
||||
pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit;
|
||||
pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit;
|
||||
pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit;
|
||||
pal->upper_alarm_limit = finite(ald.upper_alarm_limit) ?
|
||||
(epicsInt32) ald.upper_alarm_limit : 0;
|
||||
pal->upper_warning_limit = finite(ald.upper_warning_limit) ?
|
||||
(epicsInt32) ald.upper_warning_limit : 0;
|
||||
pal->lower_warning_limit = finite(ald.lower_warning_limit) ?
|
||||
(epicsInt32) ald.lower_warning_limit : 0;
|
||||
pal->lower_alarm_limit = finite(ald.lower_alarm_limit) ?
|
||||
(epicsInt32) ald.lower_alarm_limit : 0;
|
||||
|
||||
if (no_data)
|
||||
*options ^= DBR_AL_LONG; /*Turn off option*/
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Copyright (c) 2013 Helmholtz-Zentrum Berlin
|
||||
* für Materialien und Energie GmbH.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* dbScan.c */
|
||||
/* tasks and subroutines to scan the database */
|
||||
@@ -109,8 +109,8 @@ static char *priorityName[NUM_CALLBACK_PRIORITIES] = {
|
||||
typedef struct event_list {
|
||||
CALLBACK callback[NUM_CALLBACK_PRIORITIES];
|
||||
scan_list scan_list[NUM_CALLBACK_PRIORITIES];
|
||||
struct event_list *next;
|
||||
char event_name[MAX_STRING_SIZE];
|
||||
struct event_list *next;
|
||||
char eventname[1]; /* actually arbitrary size */
|
||||
} event_list;
|
||||
static event_list * volatile pevent_list[256];
|
||||
static epicsMutexId event_lock;
|
||||
@@ -247,11 +247,6 @@ void scanAdd(struct dbCommon *precord)
|
||||
event_list *pel;
|
||||
|
||||
eventname = precord->evnt;
|
||||
if (strlen(eventname) >= MAX_STRING_SIZE) {
|
||||
recGblRecordError(S_db_badField, (void *)precord,
|
||||
"scanAdd: too long EVNT value");
|
||||
return;
|
||||
}
|
||||
prio = precord->prio;
|
||||
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
@@ -315,24 +310,17 @@ void scanDelete(struct dbCommon *precord)
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete detected illegal SCAN value");
|
||||
} else if (scan == menuScanEvent) {
|
||||
char* eventname;
|
||||
int prio;
|
||||
event_list *pel;
|
||||
scan_list *psl = 0;
|
||||
|
||||
eventname = precord->evnt;
|
||||
prio = precord->prio;
|
||||
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
|
||||
recGblRecordError(-1, (void *)precord,
|
||||
"scanDelete detected illegal PRIO field");
|
||||
return;
|
||||
}
|
||||
do /* multithreading: make sure pel is consistent */
|
||||
pel = pevent_list[0];
|
||||
while (pel != pevent_list[0]);
|
||||
for (; pel; pel=pel->next) {
|
||||
if (strcmp(pel->event_name, eventname) == 0) break;
|
||||
}
|
||||
pel = eventNameToHandle(precord->evnt);
|
||||
if (pel && (psl = &pel->scan_list[prio]))
|
||||
deleteFromList(precord, psl);
|
||||
} else if (scan == menuScanI_O_Intr) {
|
||||
@@ -420,14 +408,12 @@ int scanpel(const char* eventname) /* print event list */
|
||||
int prio;
|
||||
event_list *pel;
|
||||
|
||||
do /* multithreading: make sure pel is consistent */
|
||||
pel = pevent_list[0];
|
||||
while (pel != pevent_list[0]);
|
||||
for (; pel; pel = pel->next) {
|
||||
if (!eventname || strcmp(pel->event_name, eventname) == 0) {
|
||||
for (pel = pevent_list[0]; pel; pel = pel->next) {
|
||||
if (!eventname || epicsStrGlobMatch(pel->eventname, eventname)) {
|
||||
printf("Event \"%s\"\n", pel->eventname);
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
if (ellCount(&pel->scan_list[prio].list) == 0) continue;
|
||||
sprintf(message, "Event \"%s\" Priority %s", pel->event_name, priorityName[prio]);
|
||||
sprintf(message, " Priority %s", priorityName[prio]);
|
||||
printList(&pel->scan_list[prio], message);
|
||||
}
|
||||
}
|
||||
@@ -478,20 +464,52 @@ event_list *eventNameToHandle(const char *eventname)
|
||||
int prio;
|
||||
event_list *pel;
|
||||
static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT;
|
||||
double eventnumber = 0;
|
||||
size_t namelength;
|
||||
|
||||
if (!eventname || eventname[0] == 0)
|
||||
return NULL;
|
||||
if (!eventname) return NULL;
|
||||
while (isspace((int) eventname[0])) eventname++;
|
||||
if (!eventname[0]) return NULL;
|
||||
namelength = strlen(eventname);
|
||||
while (isspace((int) eventname[namelength-1])) namelength--;
|
||||
|
||||
/* Backward compatibility with numeric events:
|
||||
Treat any string that represents a double with an
|
||||
integer part between 0 and 255 the same as the integer
|
||||
because it is most probably a conversion from double
|
||||
like from a calc record.
|
||||
*/
|
||||
if (epicsParseDouble(eventname, &eventnumber, NULL) == 0)
|
||||
{
|
||||
if (eventnumber >= 0 && eventnumber < 256)
|
||||
{
|
||||
if (eventnumber < 1)
|
||||
return NULL; /* 0 is no event */
|
||||
if ((pel = pevent_list[(int)eventnumber]) != NULL)
|
||||
return pel;
|
||||
}
|
||||
else
|
||||
eventnumber = 0; /* not a numeric event between 1 and 255 */
|
||||
}
|
||||
|
||||
epicsThreadOnce(&onceId, eventOnce, NULL);
|
||||
epicsMutexMustLock(event_lock);
|
||||
for (pel = pevent_list[0]; pel; pel=pel->next) {
|
||||
if (strcmp(pel->event_name, eventname) == 0) break;
|
||||
if (strncmp(pel->eventname, eventname, namelength) == 0
|
||||
&& pel->eventname[namelength] == 0)
|
||||
break;
|
||||
}
|
||||
if (pel == NULL) {
|
||||
pel = calloc(1, sizeof(event_list));
|
||||
pel = calloc(1, sizeof(event_list) + namelength);
|
||||
if (!pel)
|
||||
goto done;
|
||||
strcpy(pel->event_name, eventname);
|
||||
if (eventnumber > 0) {
|
||||
/* backward compatibility: make all numeric events look like integers */
|
||||
sprintf(pel->eventname, "%i", (int)eventnumber);
|
||||
pevent_list[(int)eventnumber] = pel;
|
||||
}
|
||||
else
|
||||
strncpy(pel->eventname, eventname, namelength);
|
||||
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
|
||||
callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]);
|
||||
callbackSetPriority(prio, &pel->callback[prio]);
|
||||
@@ -501,12 +519,6 @@ event_list *eventNameToHandle(const char *eventname)
|
||||
}
|
||||
pel->next=pevent_list[0];
|
||||
pevent_list[0]=pel;
|
||||
{ /* backward compatibility */
|
||||
char* p;
|
||||
long e = strtol(eventname, &p, 0);
|
||||
if (*p == 0 && e > 0 && e <= 255)
|
||||
pevent_list[e] = pel;
|
||||
}
|
||||
}
|
||||
done:
|
||||
epicsMutexUnlock(event_lock);
|
||||
@@ -528,13 +540,8 @@ void postEvent(event_list *pel)
|
||||
/* backward compatibility */
|
||||
void post_event(int event)
|
||||
{
|
||||
event_list* pel;
|
||||
|
||||
if (event <= 0 || event > 255) return;
|
||||
do { /* multithreading: make sure pel is consistent */
|
||||
pel = pevent_list[event];
|
||||
} while (pel != pevent_list[event]);
|
||||
postEvent(pel);
|
||||
postEvent(pevent_list[event]);
|
||||
}
|
||||
|
||||
static void ioscanOnce(void *arg)
|
||||
|
||||
@@ -51,7 +51,7 @@ epicsShareFunc void scanCleanup(void);
|
||||
|
||||
epicsShareFunc EVENTPVT eventNameToHandle(const char* event);
|
||||
epicsShareFunc void postEvent(EVENTPVT epvt);
|
||||
epicsShareFunc void post_event(int event) EPICS_DEPRECATED;
|
||||
epicsShareFunc void post_event(int event);
|
||||
epicsShareFunc void scanAdd(struct dbCommon *);
|
||||
epicsShareFunc void scanDelete(struct dbCommon *);
|
||||
epicsShareFunc double scanPeriod(int scan);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "osiUnistd.h"
|
||||
#include "registry.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "epicsThread.h"
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbAccess.h"
|
||||
@@ -415,3 +416,26 @@ unsigned testMonitorCount(testMonitor *mon, unsigned reset)
|
||||
return count;
|
||||
}
|
||||
|
||||
static
|
||||
epicsMutexId test_global;
|
||||
|
||||
static
|
||||
epicsThreadOnceId test_global_once = EPICS_THREAD_ONCE_INIT;
|
||||
|
||||
static
|
||||
void test_global_init(void* ignored)
|
||||
{
|
||||
test_global = epicsMutexMustCreate();
|
||||
}
|
||||
|
||||
void testGlobalLock(void)
|
||||
{
|
||||
epicsThreadOnce(&test_global_once, &test_global_init, NULL);
|
||||
epicsMutexMustLock(test_global);
|
||||
}
|
||||
|
||||
void testGlobalUnlock(void)
|
||||
{
|
||||
epicsMutexUnlock(test_global);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,65 @@ epicsShareFunc void testMonitorWait(testMonitor*);
|
||||
*/
|
||||
epicsShareFunc unsigned testMonitorCount(testMonitor*, unsigned reset);
|
||||
|
||||
/** Synchronize the shared callback queues.
|
||||
*
|
||||
* Block until all callback queue jobs which were queued, or running,
|
||||
* have completed.
|
||||
*/
|
||||
epicsShareFunc void testSyncCallback(void);
|
||||
|
||||
/** Global mutex for use by test code.
|
||||
*
|
||||
* This utility mutex is intended to be used to avoid races in situations
|
||||
* where some other syncronization primitive is being destroyed (epicsEvent,
|
||||
* epicsMutex, ...).
|
||||
*
|
||||
* For example. The following has a subtle race where the event may be
|
||||
* destroyed (free()'d) before the call to epicsEventMustSignal() has
|
||||
* returned. On some targets this leads to a use after free() error.
|
||||
*
|
||||
@code
|
||||
epicsEventId evt;
|
||||
void thread1() {
|
||||
evt = epicsEventMustCreate(...);
|
||||
// spawn thread2()
|
||||
epicsEventMustWait(evt);
|
||||
epicsEventDestroy(evt);
|
||||
}
|
||||
// ...
|
||||
void thread2() {
|
||||
epicsEventMustSignal(evt);
|
||||
}
|
||||
@endcode
|
||||
*
|
||||
* One way to avoid this race is to use a global mutex to ensure
|
||||
* that epicsEventMustSignal() has returned before destroying
|
||||
* the event.
|
||||
*
|
||||
@code
|
||||
epicsEventId evt;
|
||||
void thread1() {
|
||||
evt = epicsEventMustCreate(...);
|
||||
// spawn thread2()
|
||||
epicsEventMustWait(evt);
|
||||
testGlobalLock(); // <-- added
|
||||
epicsEventDestroy(evt);
|
||||
testGlobalUnlock(); // <-- added
|
||||
}
|
||||
// ...
|
||||
void thread2() {
|
||||
testGlobalLock(); // <-- added
|
||||
epicsEventMustSignal(evt);
|
||||
testGlobalUnlock(); // <-- added
|
||||
}
|
||||
@endcode
|
||||
*
|
||||
* This must be a global mutex to avoid simply shifting the race
|
||||
* from the event to a locally allocated mutex.
|
||||
*/
|
||||
epicsShareFunc void testGlobalLock(void);
|
||||
epicsShareFunc void testGlobalUnlock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1064,32 +1064,39 @@ static void dbRecordHead(char *recordType, char *name, int visible)
|
||||
|
||||
static void dbRecordField(char *name,char *value)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbFindField(pdbentry,name);
|
||||
if(status) {
|
||||
epicsPrintf("Record \"%s\" does not have a field \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
if (status) {
|
||||
epicsPrintf("Record \"%s\" does not have a field \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
if (pdbentry->indfield == 0) {
|
||||
epicsPrintf("Can't set \"NAME\" field of record \"%s\"\n",
|
||||
dbGetRecordName(pdbentry));
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
if (*value == '"') {
|
||||
/* jsonSTRING values still have their quotes */
|
||||
/* jsonSTRING values still have their quotes */
|
||||
value++;
|
||||
value[strlen(value) - 1] = 0;
|
||||
value[strlen(value) - 1] = 0;
|
||||
}
|
||||
dbTranslateEscape(value, value); /* in-place; safe & legal */
|
||||
status = dbPutString(pdbentry,value);
|
||||
if(status) {
|
||||
if (status) {
|
||||
char msg[128];
|
||||
|
||||
errSymLookup(status, msg, sizeof(msg));
|
||||
epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s\n",
|
||||
dbGetRecordName(pdbentry), name, value, msg);
|
||||
dbGetRecordName(pdbentry), name, value, msg);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
@@ -1097,39 +1104,39 @@ static void dbRecordField(char *name,char *value)
|
||||
|
||||
static void dbRecordInfo(char *name, char *value)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
if (*value == '"') {
|
||||
/* jsonSTRING values still have their quotes */
|
||||
/* jsonSTRING values still have their quotes */
|
||||
value++;
|
||||
value[strlen(value) - 1] = 0;
|
||||
value[strlen(value) - 1] = 0;
|
||||
}
|
||||
dbTranslateEscape(value, value); /* yuck: in-place, but safe */
|
||||
status = dbPutInfo(pdbentry,name,value);
|
||||
if(status) {
|
||||
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",
|
||||
if (status) {
|
||||
epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n",
|
||||
dbGetRecordName(pdbentry), name, value);
|
||||
yyerror(NULL);
|
||||
return;
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dbRecordAlias(char *name)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
if (duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbCreateAlias(pdbentry, name);
|
||||
if(status) {
|
||||
if (status) {
|
||||
epicsPrintf("Can't create alias \"%s\" for \"%s\"\n",
|
||||
name, dbGetRecordName(pdbentry));
|
||||
yyerror(NULL);
|
||||
@@ -1139,15 +1146,16 @@ static void dbRecordAlias(char *name)
|
||||
|
||||
static void dbAlias(char *name, char *alias)
|
||||
{
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry = &dbEntry;
|
||||
DBENTRY dbEntry;
|
||||
DBENTRY *pdbEntry = &dbEntry;
|
||||
|
||||
dbInitEntry(pdbbase, pdbEntry);
|
||||
if (dbFindRecord(pdbEntry, name)) {
|
||||
epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n",
|
||||
alias, name);
|
||||
yyerror(NULL);
|
||||
} else if (dbCreateAlias(pdbEntry, alias)) {
|
||||
}
|
||||
else if (dbCreateAlias(pdbEntry, alias)) {
|
||||
epicsPrintf("Can't create alias \"%s\" referring to \"%s\"\n",
|
||||
alias, name);
|
||||
yyerror(NULL);
|
||||
@@ -1157,14 +1165,14 @@ static void dbAlias(char *name, char *alias)
|
||||
|
||||
static void dbRecordBody(void)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
DBENTRY *pdbentry;
|
||||
|
||||
if(duplicate) {
|
||||
duplicate = FALSE;
|
||||
return;
|
||||
if (duplicate) {
|
||||
duplicate = FALSE;
|
||||
return;
|
||||
}
|
||||
pdbentry = (DBENTRY *)popFirstTemp();
|
||||
if(ellCount(&tempList))
|
||||
yyerrorAbort("dbRecordBody: tempList not empty");
|
||||
if (ellCount(&tempList))
|
||||
yyerrorAbort("dbRecordBody: tempList not empty");
|
||||
dbFreeEntry(pdbentry);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ epicsExportAddress(dset, devMbbiDirectSoft);
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec)
|
||||
{
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_ENUM, &prec->val))
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ULONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
return 0;
|
||||
@@ -56,7 +56,7 @@ static long init_record(mbbiDirectRecord *prec)
|
||||
static long readLocked(struct link *pinp, void *dummy)
|
||||
{
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *) pinp->precord;
|
||||
long status = dbGetLink(pinp, DBR_USHORT, &prec->val, 0, 0);
|
||||
long status = dbGetLink(pinp, DBR_ULONG, &prec->val, 0, 0);
|
||||
|
||||
if (status) return status;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef struct devPvt {
|
||||
struct {
|
||||
DBRstatus
|
||||
DBRtime
|
||||
epicsUInt16 value;
|
||||
epicsUInt32 value;
|
||||
} buffer;
|
||||
} devPvt;
|
||||
|
||||
@@ -58,7 +58,7 @@ static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
}
|
||||
|
||||
assert(type == getFieldType);
|
||||
pdevPvt->status = dbChannelGetField(ppn->chan, DBR_USHORT,
|
||||
pdevPvt->status = dbChannelGetField(ppn->chan, DBR_ULONG,
|
||||
&pdevPvt->buffer, &pdevPvt->options, &no_elements, 0);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ static long init(int pass)
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec)
|
||||
{
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val))
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ULONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -59,7 +59,7 @@ static long init_record(mbbiDirectRecord *prec)
|
||||
|
||||
static long read_mbbi(mbbiDirectRecord *prec)
|
||||
{
|
||||
if (!dbGetLink(&prec->inp, DBR_LONG, &prec->rval, 0, 0)) {
|
||||
if (!dbGetLink(&prec->inp, DBR_ULONG, &prec->rval, 0, 0)) {
|
||||
prec->rval &= prec->mask;
|
||||
if (dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
{
|
||||
dbPutLink(&prec->out, DBR_USHORT, &prec->val, 1);
|
||||
dbPutLink(&prec->out, DBR_ULONG, &prec->val, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ static long write_mbbo(mbboDirectRecord *prec)
|
||||
if (prec->pact)
|
||||
return 0;
|
||||
|
||||
status = dbPutLinkAsync(plink, DBR_USHORT, &prec->val, 1);
|
||||
status = dbPutLinkAsync(plink, DBR_ULONG, &prec->val, 1);
|
||||
if (!status)
|
||||
prec->pact = TRUE;
|
||||
else if (status == S_db_noLSET)
|
||||
status = dbPutLink(plink, DBR_USHORT, &prec->val, 1);
|
||||
status = dbPutLink(plink, DBR_ULONG, &prec->val, 1);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -146,9 +146,9 @@ Note: Negative index numbers address from the end of the array, with C<-1> being
|
||||
|
||||
=item Square bracket notation C<[start:increment:end]> (shorthand)
|
||||
|
||||
The common square bracket notation with can be used in place of JSON.
|
||||
The common square bracket notation which can be used in place of JSON.
|
||||
Any parameter may be omitted (keeping the colons) to use the default value.
|
||||
If only one colon is included, this means C<[start:end]> with a increment of 1.
|
||||
If only one colon is included, this means C<[start:end]> with an increment of 1.
|
||||
If only a single parameter is used C<[index]> the filter returns one element.
|
||||
|
||||
=item Start index C<"s">
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsMath.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
@@ -248,15 +249,17 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
{
|
||||
longinRecord *prec=(longinRecord *)paddr->precord;
|
||||
|
||||
if(dbGetFieldIndex(paddr) == indexof(VAL)){
|
||||
pad->upper_alarm_limit = prec->hihi;
|
||||
pad->upper_warning_limit = prec->high;
|
||||
pad->lower_warning_limit = prec->low;
|
||||
pad->lower_alarm_limit = prec->lolo;
|
||||
} else recGblGetAlarmDouble(paddr,pad);
|
||||
return(0);
|
||||
if (dbGetFieldIndex(paddr) == indexof(VAL)){
|
||||
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
|
||||
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
|
||||
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
|
||||
pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
|
||||
}
|
||||
else
|
||||
recGblGetAlarmDouble(paddr,pad);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast)
|
||||
{
|
||||
enum {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsMath.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
@@ -282,15 +283,17 @@ static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
|
||||
{
|
||||
longoutRecord *prec=(longoutRecord *)paddr->precord;
|
||||
|
||||
if(dbGetFieldIndex(paddr) == indexof(VAL)) {
|
||||
pad->upper_alarm_limit = prec->hihi;
|
||||
pad->upper_warning_limit = prec->high;
|
||||
pad->lower_warning_limit = prec->low;
|
||||
pad->lower_alarm_limit = prec->lolo;
|
||||
} else recGblGetAlarmDouble(paddr,pad);
|
||||
return(0);
|
||||
if (dbGetFieldIndex(paddr) == indexof(VAL)) {
|
||||
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
|
||||
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
|
||||
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
|
||||
pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
|
||||
}
|
||||
else
|
||||
recGblGetAlarmDouble(paddr,pad);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void checkAlarms(longoutRecord *prec)
|
||||
{
|
||||
epicsInt32 val, hyst, lalm;
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
* Copyright (c) 2002 Southeastern Universities Research Association, as
|
||||
* Operator of Thomas Jefferson National Accelerator Facility.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* mbbiDirectRecord.c - Record Support routines for mbboDirect records */
|
||||
/* mbbiDirectRecord.c - Record Support routines for mbbiDirect records */
|
||||
/*
|
||||
* Original Authors: Bob Dalesio and Matthew Needes
|
||||
* Date: 10-07-93
|
||||
@@ -93,7 +93,7 @@ struct mbbidset { /* multi bit binary input dset */
|
||||
static void monitor(mbbiDirectRecord *);
|
||||
static long readValue(mbbiDirectRecord *);
|
||||
|
||||
#define NUM_BITS 16
|
||||
#define NUM_BITS 32
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
@@ -114,7 +114,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
|
||||
recGblInitConstantLink(&prec->siol, DBF_ULONG, &prec->sval);
|
||||
|
||||
/* Initialize MASK if the user set NOBT instead */
|
||||
if (prec->mask == 0 && prec->nobt <= 32)
|
||||
@@ -123,11 +123,11 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
if (pdset->init_record) {
|
||||
status = pdset->init_record(prec);
|
||||
if (status == 0) {
|
||||
epicsUInt16 val = prec->val;
|
||||
epicsUInt32 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
/* Initialize B0 - BF from VAL */
|
||||
/* Initialize B0 - B1F from VAL */
|
||||
for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1)
|
||||
*pBn = !! (val & 1);
|
||||
}
|
||||
@@ -208,7 +208,7 @@ static void monitor(mbbiDirectRecord *prec)
|
||||
{
|
||||
epicsUInt16 events = recGblResetAlarms(prec);
|
||||
epicsUInt16 vl_events = events | DBE_VALUE | DBE_LOG;
|
||||
epicsUInt16 val = prec->val;
|
||||
epicsUInt32 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#*************************************************************************
|
||||
recordtype(mbbiDirect) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_USHORT) {
|
||||
field(VAL,DBF_LONG) {
|
||||
prompt("Current Value")
|
||||
promptgroup("40 - Input")
|
||||
asl(ASL0)
|
||||
@@ -39,7 +39,7 @@ recordtype(mbbiDirect) {
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(MLST,DBF_USHORT) {
|
||||
field(MLST,DBF_LONG) {
|
||||
prompt("Last Value Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
@@ -54,7 +54,7 @@ recordtype(mbbiDirect) {
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SVAL,DBF_ULONG) {
|
||||
field(SVAL,DBF_LONG) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
@@ -151,32 +151,112 @@ recordtype(mbbiDirect) {
|
||||
interest(1)
|
||||
}
|
||||
field(BA,DBF_UCHAR) {
|
||||
prompt("Bit A")
|
||||
prompt("Bit 10")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BB,DBF_UCHAR) {
|
||||
prompt("Bit B")
|
||||
prompt("Bit 11")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BC,DBF_UCHAR) {
|
||||
prompt("Bit C")
|
||||
prompt("Bit 12")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BD,DBF_UCHAR) {
|
||||
prompt("Bit D")
|
||||
prompt("Bit 13")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BE,DBF_UCHAR) {
|
||||
prompt("Bit E")
|
||||
prompt("Bit 14")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BF,DBF_UCHAR) {
|
||||
prompt("Bit F")
|
||||
prompt("Bit 15")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B10,DBF_UCHAR) {
|
||||
prompt("Bit 16")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B11,DBF_UCHAR) {
|
||||
prompt("Bit 17")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B12,DBF_UCHAR) {
|
||||
prompt("Bit 18")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B13,DBF_UCHAR) {
|
||||
prompt("Bit 19")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B14,DBF_UCHAR) {
|
||||
prompt("Bit 20")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B15,DBF_UCHAR) {
|
||||
prompt("Bit 21")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B16,DBF_UCHAR) {
|
||||
prompt("Bit 22")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B17,DBF_UCHAR) {
|
||||
prompt("Bit 23")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B18,DBF_UCHAR) {
|
||||
prompt("Bit 24")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B19,DBF_UCHAR) {
|
||||
prompt("Bit 25")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1A,DBF_UCHAR) {
|
||||
prompt("Bit 26")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1B,DBF_UCHAR) {
|
||||
prompt("Bit 27")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1C,DBF_UCHAR) {
|
||||
prompt("Bit 28")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1D,DBF_UCHAR) {
|
||||
prompt("Bit 29")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1E,DBF_UCHAR) {
|
||||
prompt("Bit 30")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1F,DBF_UCHAR) {
|
||||
prompt("Bit 31")
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ static void convert(mbboDirectRecord *);
|
||||
static void monitor(mbboDirectRecord *);
|
||||
static long writeValue(mbboDirectRecord *);
|
||||
|
||||
#define NUM_BITS 16
|
||||
#define NUM_BITS 32
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
@@ -117,7 +117,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val))
|
||||
if (recGblInitConstantLink(&prec->dol, DBF_ULONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
/* Initialize MASK if the user set NOBT instead */
|
||||
@@ -142,8 +142,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
|
||||
if (!prec->udf &&
|
||||
prec->omsl == menuOmslsupervisory) {
|
||||
/* Set initial B0 - BF from VAL */
|
||||
epicsUInt16 val = prec->val;
|
||||
/* Set initial B0 - B1F from VAL */
|
||||
epicsUInt32 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
@@ -175,9 +175,9 @@ static long process(struct dbCommon *pcommon)
|
||||
if (!pact) {
|
||||
if (!dbLinkIsConstant(&prec->dol) &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
epicsUInt16 val;
|
||||
epicsUInt32 val;
|
||||
|
||||
if (dbGetLink(&prec->dol, DBR_USHORT, &val, 0, 0)) {
|
||||
if (dbGetLink(&prec->dol, DBR_ULONG, &val, 0, 0)) {
|
||||
recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
|
||||
goto CONTINUE;
|
||||
}
|
||||
@@ -185,11 +185,11 @@ static long process(struct dbCommon *pcommon)
|
||||
}
|
||||
else if (prec->omsl == menuOmslsupervisory) {
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
epicsUInt16 val = 0;
|
||||
epicsUInt16 bit = 1;
|
||||
epicsUInt32 val = 0;
|
||||
epicsUInt32 bit = 1;
|
||||
int i;
|
||||
|
||||
/* Construct VAL from B0 - BF */
|
||||
/* Construct VAL from B0 - B1F */
|
||||
for (i = 0; i < NUM_BITS; i++, bit <<= 1)
|
||||
if (*pBn++)
|
||||
val |= bit;
|
||||
@@ -264,7 +264,7 @@ static long special(DBADDR *paddr, int after)
|
||||
if (prec->omsl == menuOmslsupervisory) {
|
||||
/* Adjust VAL corresponding to the bit changed */
|
||||
epicsUInt8 *pBn = (epicsUInt8 *) paddr->pfield;
|
||||
int bit = 1 << (pBn - &prec->b0);
|
||||
epicsUInt32 bit = 1 << (pBn - &prec->b0);
|
||||
|
||||
if (*pBn)
|
||||
prec->val |= bit;
|
||||
@@ -278,9 +278,9 @@ static long special(DBADDR *paddr, int after)
|
||||
|
||||
case SPC_RESET: /* OMSL field modified */
|
||||
if (prec->omsl == menuOmslclosed_loop) {
|
||||
/* Construct VAL from B0 - BF */
|
||||
/* Construct VAL from B0 - B1F */
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
epicsUInt16 val = 0, bit = 1;
|
||||
epicsUInt32 val = 0, bit = 1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_BITS; i++, bit <<= 1)
|
||||
@@ -289,8 +289,8 @@ static long special(DBADDR *paddr, int after)
|
||||
prec->val = val;
|
||||
}
|
||||
else if (prec->omsl == menuOmslsupervisory) {
|
||||
/* Set B0 - BF from VAL and post monitors */
|
||||
epicsUInt16 val = prec->val;
|
||||
/* Set B0 - B1F from VAL and post monitors */
|
||||
epicsUInt32 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
@@ -362,7 +362,7 @@ static long writeValue(mbboDirectRecord *prec)
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
status = dbPutLink(&prec->siol, DBR_ULONG, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
recordtype(mbboDirect) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_USHORT) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_LONG) {
|
||||
prompt("Word")
|
||||
promptgroup("50 - Output")
|
||||
asl(ASL0)
|
||||
@@ -38,6 +38,99 @@ recordtype(mbboDirect) {
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(RVAL,DBF_ULONG) {
|
||||
prompt("Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(ORAW,DBF_ULONG) {
|
||||
prompt("Prev Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(RBV,DBF_ULONG) {
|
||||
prompt("Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(ORBV,DBF_ULONG) {
|
||||
prompt("Prev Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MASK,DBF_ULONG) {
|
||||
prompt("Hardware Mask")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(MLST,DBF_LONG) {
|
||||
prompt("Last Value Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SHFT,DBF_USHORT) {
|
||||
prompt("Shift")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID outpt action")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
menu(menuIvoa)
|
||||
}
|
||||
field(IVOV,DBF_LONG) {
|
||||
prompt("INVALID output value")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
}
|
||||
field(B0,DBF_UCHAR) {
|
||||
prompt("Bit 0")
|
||||
promptgroup("51 - Output 0-7")
|
||||
@@ -96,151 +189,170 @@ recordtype(mbboDirect) {
|
||||
}
|
||||
field(B8,DBF_UCHAR) {
|
||||
prompt("Bit 8")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B9,DBF_UCHAR) {
|
||||
prompt("Bit 9")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BA,DBF_UCHAR) {
|
||||
prompt("Bit 10")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BB,DBF_UCHAR) {
|
||||
prompt("Bit 11")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BC,DBF_UCHAR) {
|
||||
prompt("Bit 12")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BD,DBF_UCHAR) {
|
||||
prompt("Bit 13")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BE,DBF_UCHAR) {
|
||||
prompt("Bit 14")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(BF,DBF_UCHAR) {
|
||||
prompt("Bit 15")
|
||||
promptgroup("52 - Output 9-F")
|
||||
promptgroup("52 - Output 8-15")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(RVAL,DBF_ULONG) {
|
||||
prompt("Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
pp(TRUE)
|
||||
}
|
||||
field(ORAW,DBF_ULONG) {
|
||||
prompt("Prev Raw Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(RBV,DBF_ULONG) {
|
||||
prompt("Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(ORBV,DBF_ULONG) {
|
||||
prompt("Prev Readback Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(MASK,DBF_ULONG) {
|
||||
prompt("Hardware Mask")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
}
|
||||
field(MLST,DBF_ULONG) {
|
||||
prompt("Last Value Monitored")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SHFT,DBF_ULONG) {
|
||||
prompt("Shift")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
field(B10,DBF_UCHAR) {
|
||||
prompt("Bit 16")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
field(B11,DBF_UCHAR) {
|
||||
prompt("Bit 17")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
field(B12,DBF_UCHAR) {
|
||||
prompt("Bit 18")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
field(B13,DBF_UCHAR) {
|
||||
prompt("Bit 19")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID outpt action")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
menu(menuIvoa)
|
||||
field(B14,DBF_UCHAR) {
|
||||
prompt("Bit 20")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(IVOV,DBF_USHORT) {
|
||||
prompt("INVALID output value")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
field(B15,DBF_UCHAR) {
|
||||
prompt("Bit 21")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B16,DBF_UCHAR) {
|
||||
prompt("Bit 22")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B17,DBF_UCHAR) {
|
||||
prompt("Bit 23")
|
||||
promptgroup("53 - Output 16-23")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B18,DBF_UCHAR) {
|
||||
prompt("Bit 24")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B19,DBF_UCHAR) {
|
||||
prompt("Bit 25")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1A,DBF_UCHAR) {
|
||||
prompt("Bit 26")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1B,DBF_UCHAR) {
|
||||
prompt("Bit 27")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1C,DBF_UCHAR) {
|
||||
prompt("Bit 28")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1D,DBF_UCHAR) {
|
||||
prompt("Bit 29")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1E,DBF_UCHAR) {
|
||||
prompt("Bit 30")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
field(B1F,DBF_UCHAR) {
|
||||
prompt("Bit 31")
|
||||
promptgroup("54 - Output 24-31")
|
||||
special(SPC_MOD)
|
||||
pp(TRUE)
|
||||
interest(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
|
||||
|
||||
/* Flag bits */
|
||||
#define F_CHAR 1
|
||||
#define F_SHORT 2
|
||||
#define F_LONG 4
|
||||
#define F_LEFT 8
|
||||
#define F_BADFMT 0x10
|
||||
#define F_BADLNK 0x20
|
||||
#define F_CHAR 1
|
||||
#define F_SHORT 2
|
||||
#define F_LONG 4
|
||||
#define F_LONGLONG 8
|
||||
#define F_LEFT 0x10
|
||||
#define F_BADFMT 0x40
|
||||
#define F_BADLNK 0x80
|
||||
#define F_BAD (F_BADFMT | F_BADLNK)
|
||||
|
||||
#define GET_PRINT(VALTYPE, DBRTYPE) \
|
||||
@@ -129,13 +130,20 @@ static void doPrintf(printfRecord *prec)
|
||||
flags |= F_BADLNK;
|
||||
break;
|
||||
case 'h':
|
||||
if (flags & F_SHORT)
|
||||
if (flags & (F_LONGLONG | F_LONG | F_CHAR))
|
||||
flags |= F_BADFMT;
|
||||
else if (flags & F_SHORT)
|
||||
flags = (flags & ~F_SHORT) | F_CHAR;
|
||||
else
|
||||
flags |= F_SHORT;
|
||||
break;
|
||||
case 'l':
|
||||
flags |= F_LONG;
|
||||
if (flags & (F_LONGLONG | F_SHORT | F_CHAR))
|
||||
flags |= F_BADFMT;
|
||||
else if (flags & F_LONG)
|
||||
flags = (flags & ~F_LONG) | F_LONGLONG;
|
||||
else
|
||||
flags |= F_LONG;
|
||||
break;
|
||||
default:
|
||||
if (strchr("diouxXeEfFgGcs%", ch) == NULL)
|
||||
@@ -175,6 +183,9 @@ static void doPrintf(printfRecord *prec)
|
||||
else if (flags & F_SHORT) {
|
||||
GET_PRINT(epicsInt16, DBR_SHORT);
|
||||
}
|
||||
else if (flags & F_LONGLONG) {
|
||||
GET_PRINT(epicsInt64, DBR_INT64);
|
||||
}
|
||||
else { /* F_LONG has no real effect */
|
||||
GET_PRINT(epicsInt32, DBR_LONG);
|
||||
}
|
||||
@@ -187,6 +198,9 @@ static void doPrintf(printfRecord *prec)
|
||||
else if (flags & F_SHORT) {
|
||||
GET_PRINT(epicsUInt16, DBR_USHORT);
|
||||
}
|
||||
else if (flags & F_LONGLONG) {
|
||||
GET_PRINT(epicsUInt64, DBR_UINT64);
|
||||
}
|
||||
else { /* F_LONG has no real effect */
|
||||
GET_PRINT(epicsUInt32, DBR_ULONG);
|
||||
}
|
||||
|
||||
@@ -198,8 +198,8 @@ static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
|
||||
|
||||
static void checkAlarms(xxxRecord *prec)
|
||||
{
|
||||
double val;
|
||||
float hyst, lalm, hihi, high, low, lolo;
|
||||
double val, hyst, lalm;
|
||||
float hihi, high, low, lolo;
|
||||
unsigned short hhsv, llsv, hsv, lsv;
|
||||
|
||||
if(prec->udf == TRUE ){
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
TOP = ../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
ARCH = $(EPICS_HOST_ARCH)
|
||||
TARGETS = envPaths
|
||||
include $(TOP)/configure/RULES.ioc
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
TOP = ../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
ARCH = $(EPICS_HOST_ARCH)
|
||||
TARGETS = envPaths
|
||||
include $(TOP)/configure/RULES.ioc
|
||||
|
||||
@@ -46,7 +46,7 @@ BEGIN {
|
||||
|
||||
my $tool = 'dbdToHtml';
|
||||
|
||||
use vars qw($opt_D @opt_I $opt_o);
|
||||
our ($opt_D, @opt_I, $opt_o);
|
||||
getopts('DI@o:') or
|
||||
die "Usage: $tool [-D] [-I dir] [-o file.html] file.dbd.pod\n";
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use EPICS::Readfile;
|
||||
|
||||
my $tool = 'dbdToMenuH.pl';
|
||||
|
||||
use vars qw($opt_D @opt_I $opt_o $opt_s);
|
||||
our ($opt_D, @opt_I, $opt_o, $opt_s);
|
||||
getopts('DI@o:') or
|
||||
die "Usage: $tool: [-D] [-I dir] [-o menu.h] menu.dbd [menu.h]\n";
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use EPICS::Readfile;
|
||||
|
||||
my $tool = 'dbdToRecordtypeH.pl';
|
||||
|
||||
use vars qw($opt_D @opt_I $opt_o $opt_s);
|
||||
our ($opt_D, @opt_I, $opt_o, $opt_s);
|
||||
getopts('DI@o:s') or
|
||||
die "Usage: $tool [-D] [-I dir] [-o xRecord.h] xRecord.dbd [xRecord.h]\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user