Files
epics-base/named-soft-events.patch
2011-06-27 15:46:14 +00:00

582 lines
18 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
=== modified file 'documentation/RELEASE_NOTES.html'
--- documentation/RELEASE_NOTES.html 2010-10-26 15:49:26 +0000
+++ documentation/RELEASE_NOTES.html 2010-10-27 20:51:01 +0000
@@ -138,6 +138,10 @@
<p>Fixed crash when ALG (algorithm) was changed to Average at runtime.</p>
+<h4>Named Soft Events</h4>
+
+<p>Soft events can now be meaningful strings instead of numbers 1-255.
+
<h4>configure/RELEASE Enhancements</h4>
<p>Variable definitions in a <tt>configure/RELEASE</tt> file may now use the
=== modified file 'src/db/dbCommon.dbd'
--- src/db/dbCommon.dbd 2009-04-23 20:35:02 +0000
+++ src/db/dbCommon.dbd 2010-10-27 20:51:01 +0000
@@ -43,10 +43,11 @@
special(SPC_SCAN)
interest(1)
}
- field(EVNT,DBF_SHORT) {
- prompt("Event Number")
+ field(EVNT,DBF_STRING) {
+ prompt("Event Name")
promptgroup(GUI_SCAN)
special(SPC_SCAN)
+ size(40)
interest(1)
}
field(TSE,DBF_SHORT) {
=== modified file 'src/db/dbIocRegister.c'
--- src/db/dbIocRegister.c 2009-01-16 20:50:40 +0000
+++ src/db/dbIocRegister.c 2010-10-27 20:51:01 +0000
@@ -266,11 +266,11 @@
{ scanppl(args[0].dval);}
/* scanpel */
-static const iocshArg scanpelArg0 = { "event number",iocshArgInt};
+static const iocshArg scanpelArg0 = { "event name",iocshArgString};
static const iocshArg * const scanpelArgs[1] = {&scanpelArg0};
static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs};
static void scanpelCallFunc(const iocshArgBuf *args)
-{ scanpel(args[0].ival);}
+{ scanpel(args[0].sval);}
/* scanpiol */
static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0};
=== modified file 'src/db/dbScan.c'
--- src/db/dbScan.c 2009-04-03 17:46:26 +0000
+++ src/db/dbScan.c 2010-10-27 20:51:01 +0000
@@ -101,12 +101,13 @@
/* EVENT */
-#define MAX_EVENTS 256
-typedef struct event_scan_list {
- CALLBACK callback;
- scan_list scan_list;
-} event_scan_list;
-static event_scan_list *pevent_list[NUM_CALLBACK_PRIORITIES][MAX_EVENTS];
+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];
+} event_list;
+static event_list * volatile pevent_list[256];
/* IO_EVENT*/
@@ -204,35 +205,24 @@
recGblRecordError(-1, (void *)precord,
"scanAdd detected illegal SCAN value");
} else if (scan == menuScanEvent) {
- int evnt;
+ char* eventname;
int prio;
- event_scan_list *pesl;
+ event_list *pel;
- evnt = precord->evnt;
- if (evnt < 0 || evnt >= MAX_EVENTS) {
+ eventname = precord->evnt;
+ if (strlen(eventname) >= MAX_STRING_SIZE) {
recGblRecordError(S_db_badField, (void *)precord,
- "scanAdd detected illegal EVNT value");
- precord->scan = menuScanPassive;
+ "scanAdd: too long EVNT value");
return;
}
prio = precord->prio;
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1, (void *)precord,
"scanAdd: illegal prio field");
- precord->scan = menuScanPassive;
return;
}
- pesl = pevent_list[prio][evnt];
- if (pesl == NULL) {
- pesl = dbCalloc(1, sizeof(event_scan_list));
- pevent_list[prio][evnt] = pesl;
- pesl->scan_list.lock = epicsMutexMustCreate();
- callbackSetCallback(eventCallback, &pesl->callback);
- callbackSetPriority(prio, &pesl->callback);
- callbackSetUser(pesl, &pesl->callback);
- ellInit(&pesl->scan_list.list);
- }
- addToList(precord, &pesl->scan_list);
+ pel = eventNameToHandle(eventname);
+ if (pel) addToList(precord, &pel->scan_list[prio]);
} else if (scan == menuScanI_O_Intr) {
io_scan_list *piosl = NULL;
int prio;
@@ -287,31 +277,25 @@
recGblRecordError(-1, (void *)precord,
"scanDelete detected illegal SCAN value");
} else if (scan == menuScanEvent) {
- int evnt;
+ char* eventname;
int prio;
- event_scan_list *pesl;
+ event_list *pel;
scan_list *psl = 0;
- evnt = precord->evnt;
- if (evnt < 0 || evnt >= MAX_EVENTS) {
- recGblRecordError(S_db_badField, (void *)precord,
- "scanAdd detected illegal EVNT value");
- precord->scan = menuScanPassive;
- return;
- }
+ eventname = precord->evnt;
prio = precord->prio;
if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) {
recGblRecordError(-1, (void *)precord,
- "scanAdd: illegal prio field");
- precord->scan = menuScanPassive;
+ "scanDelete detected illegal PRIO field");
return;
}
- pesl = pevent_list[prio][evnt];
- if (pesl) psl = &pesl->scan_list;
- if (!pesl || !psl)
- recGblRecordError(-1, (void *)precord,
- "scanDelete for bad evnt");
- else
+ 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;
+ }
+ if (pel && (psl = &pel->scan_list[prio]))
deleteFromList(precord, psl);
} else if (scan == menuScanI_O_Intr) {
io_scan_list *piosl=NULL;
@@ -372,21 +356,22 @@
return 0;
}
-int scanpel(int event_number) /* print event list */
+int scanpel(char* eventname) /* print event list */
{
char message[80];
- int prio, evnt;
- event_scan_list *pesl;
-
- for (evnt = 0; evnt < MAX_EVENTS; evnt++) {
- if (event_number && evnt<event_number) continue;
- if (event_number && evnt>event_number) break;
- for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
- pesl = pevent_list[prio][evnt];
- if (!pesl) continue;
- if (ellCount(&pesl->scan_list.list) == 0) continue;
- sprintf(message, "Event %d Priority %s", evnt, priorityName[prio]);
- printList(&pesl->scan_list, message);
+ 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 (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]);
+ printList(&pel->scan_list[prio], message);
+ }
}
}
return 0;
@@ -412,39 +397,73 @@
static void eventCallback(CALLBACK *pcallback)
{
- event_scan_list *pesl;
+ scan_list *psl;
- callbackGetUser(pesl, pcallback);
- scanList(&pesl->scan_list);
+ callbackGetUser(psl, pcallback);
+ scanList(psl);
}
static void initEvent(void)
{
- int evnt, prio;
-
+}
+
+event_list *eventNameToHandle(char *eventname)
+{
+ int prio;
+ event_list *pel;
+ static epicsMutexId lock = NULL;
+
+ if (!lock) lock = epicsMutexMustCreate();
+ if (!eventname || eventname[0] == 0) return NULL;
+ epicsMutexMustLock(lock);
+ for (pel = pevent_list[0]; pel; pel=pel->next) {
+ if (strcmp(pel->event_name, eventname) == 0) break;
+ }
+ if (pel == NULL) {
+ pel = dbCalloc(1, sizeof(event_list));
+ strcpy(pel->event_name, eventname);
+ for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
+ callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]);
+ callbackSetPriority(prio, &pel->callback[prio]);
+ callbackSetCallback(eventCallback, &pel->callback[prio]);
+ pel->scan_list[prio].lock = epicsMutexMustCreate();
+ ellInit(&pel->scan_list[prio].list);
+ }
+ 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;
+ }
+ }
+ epicsMutexUnlock(lock);
+ return pel;
+}
+
+void postEvent(event_list *pel)
+{
+ int prio;
+
+ if (scanCtl != ctlRun) return;
+ if (!pel) return;
for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
- for (evnt = 0; evnt < MAX_EVENTS; evnt++) {
- pevent_list[prio][evnt] = NULL;
- }
+ if (ellCount(&pel->scan_list[prio].list) >0)
+ callbackRequest(&pel->callback[prio]);
}
}
+/* backward compatibility */
void post_event(int event)
{
- int prio;
- event_scan_list *pesl;
-
- if (scanCtl != ctlRun) return;
- if (event < 0 || event >= MAX_EVENTS) {
- errMessage(-1, "illegal event passed to post_event");
- return;
- }
- for (prio=0; prio<NUM_CALLBACK_PRIORITIES; prio++) {
- pesl = pevent_list[prio][event];
- if (!pesl) continue;
- if (ellCount(&pesl->scan_list.list) >0)
- callbackRequest((void *)pesl);
- }
+ 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);
}
void scanIoInit(IOSCANPVT *ppioscanpvt)
=== modified file 'src/db/dbScan.h'
--- src/db/dbScan.h 2010-10-05 19:27:37 +0000
+++ src/db/dbScan.h 2010-10-27 20:51:01 +0000
@@ -19,6 +19,7 @@
#include "menuScan.h"
#include "shareLib.h"
+#include "compilerDependencies.h"
#ifdef __cplusplus
extern "C" {
@@ -32,10 +33,13 @@
#define MAX_PHASE SHRT_MAX
#define MIN_PHASE SHRT_MIN
+#define HAVE_NAMED_SOFT_EVENTS
+
/*definitions for I/O Interrupt Scanning */
struct io_scan_list;
typedef struct io_scan_list *IOSCANPVT;
+typedef struct event_list *EVENTPVT;
struct dbCommon;
@@ -43,7 +47,9 @@
epicsShareFunc void scanRun(void);
epicsShareFunc void scanPause(void);
-epicsShareFunc void post_event(int event);
+epicsShareFunc EVENTPVT eventNameToHandle(char* event);
+epicsShareFunc void postEvent(EVENTPVT epvt);
+epicsShareFunc void post_event(int event) EPICS_DEPRECATED;
epicsShareFunc void scanAdd(struct dbCommon *);
epicsShareFunc void scanDelete(struct dbCommon *);
epicsShareFunc double scanPeriod(int scan);
@@ -54,7 +60,7 @@
epicsShareFunc int scanppl(double rate);
/*print event lists*/
-epicsShareFunc int scanpel(int event_number);
+epicsShareFunc int scanpel(char *event_name);
/*print io_event list*/
epicsShareFunc int scanpiol(void);
=== modified file 'src/dev/softDev/devEventSoft.c'
--- src/dev/softDev/devEventSoft.c 2010-10-05 19:27:37 +0000
+++ src/dev/softDev/devEventSoft.c 2010-10-27 20:51:01 +0000
@@ -51,7 +51,7 @@
/* INP must be CONSTANT, PV_LINK, DB_LINK or CA_LINK*/
switch (prec->inp.type) {
case CONSTANT:
- if (recGblInitConstantLink(&prec->inp, DBF_USHORT, &prec->val))
+ if (recGblInitConstantLink(&prec->inp, DBF_STRING, &prec->val))
prec->udf = FALSE;
break;
case PV_LINK:
@@ -69,13 +69,20 @@
static long read_event(eventRecord *prec)
{
long status;
+ char newEvent[MAX_STRING_SIZE];
- status = dbGetLink(&prec->inp, DBR_USHORT, &prec->val, 0, 0);
- if (!status) {
- prec->udf = FALSE;
- if (prec->tsel.type == CONSTANT &&
- prec->tse == epicsTimeEventDeviceTime)
- dbGetTimeStamp(&prec->inp, &prec->time);
+ if (prec->inp.type != CONSTANT)
+ {
+ status = dbGetLinkValue(&prec->inp, DBR_STRING, newEvent, 0, 0);
+ if (status) return status;
+ if (strcmp(newEvent, prec->val) != 0) {
+ strcpy(prec->val, newEvent);
+ prec->epvt = eventNameToHandle(prec->val);
+ }
}
- return status;
+ prec->udf = FALSE;
+ if (prec->tsel.type == CONSTANT &&
+ prec->tse == epicsTimeEventDeviceTime)
+ dbGetTimeStamp(&prec->inp, &prec->time);
+ return 0;
}
=== modified file 'src/rec/calcoutRecord.c'
--- src/rec/calcoutRecord.c 2010-04-05 18:49:18 +0000
+++ src/rec/calcoutRecord.c 2010-10-27 20:51:01 +0000
@@ -197,6 +197,8 @@
callbackSetUser(prec, &prpvt->checkLinkCb);
prpvt->cbScheduled = 0;
+ prec->epvt = eventNameToHandle(prec->oevt);
+
if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec);
prec->pval = prec->val;
prec->mlst = prec->val;
@@ -357,6 +359,9 @@
}
db_post_events(prec, plinkValid, DBE_VALUE);
return 0;
+ case(calcoutRecordOEVT):
+ prec->epvt = eventNameToHandle(prec->oevt);
+ return 0;
default:
recGblDbaddrError(S_db_badChoice, paddr, "calc: special");
return(S_db_badChoice);
@@ -539,27 +544,21 @@
if (prec->nsev < INVALID_ALARM ) {
/* Output the value */
status = writeValue(prec);
- /* post event if output event != 0 */
- if (prec->oevt > 0) {
- post_event((int)prec->oevt);
- }
+ /* post output event if set */
+ if (prec->epvt) postEvent(prec->epvt);
} else switch (prec->ivoa) {
case menuIvoaContinue_normally:
status = writeValue(prec);
- /* post event if output event != 0 */
- if (prec->oevt > 0) {
- post_event((int)prec->oevt);
- }
+ /* post output event if set */
+ if (prec->epvt) postEvent(prec->epvt);
break;
case menuIvoaDon_t_drive_outputs:
break;
case menuIvoaSet_output_to_IVOV:
prec->oval = prec->ivov;
status = writeValue(prec);
- /* post event if output event != 0 */
- if (prec->oevt > 0) {
- post_event((int)prec->oevt);
- }
+ /* post output event if set */
+ if (prec->epvt) postEvent(prec->epvt);
break;
default:
status = -1;
=== modified file 'src/rec/calcoutRecord.dbd'
--- src/rec/calcoutRecord.dbd 2010-10-04 18:46:09 +0000
+++ src/rec/calcoutRecord.dbd 2010-10-27 20:51:01 +0000
@@ -255,10 +255,19 @@
prompt("OCAL Valid")
interest(1)
}
- field(OEVT,DBF_USHORT) {
+ field(OEVT,DBF_STRING) {
prompt("Event To Issue")
promptgroup(GUI_CLOCK)
+ special(SPC_MOD)
asl(ASL0)
+ size(40)
+ }
+ %#include "dbScan.h"
+ field(EPVT, DBF_NOACCESS) {
+ prompt("Event private")
+ special(SPC_NOMOD)
+ interest(4)
+ extra("EVENTPVT epvt")
}
field(IVOA,DBF_MENU) {
prompt("INVALID output action")
=== modified file 'src/rec/eventRecord.c'
--- src/rec/eventRecord.c 2010-10-05 19:27:37 +0000
+++ src/rec/eventRecord.c 2010-10-27 20:51:01 +0000
@@ -32,6 +32,7 @@
#include "errMdef.h"
#include "recSup.h"
#include "recGbl.h"
+#include "special.h"
#include "menuYesNo.h"
#define GEN_SIZE_OFFSET
#include "eventRecord.h"
@@ -43,7 +44,7 @@
#define initialize NULL
static long init_record(eventRecord *, int);
static long process(eventRecord *);
-#define special NULL
+static long special(DBADDR *, int);
static long get_value(eventRecord *, struct valueDes *);
#define cvt_dbaddr NULL
#define get_array_info NULL
@@ -103,9 +104,11 @@
}
if (prec->siol.type == CONSTANT) {
- recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval);
+ recGblInitConstantLink(&prec->siol,DBF_STRING,&prec->sval);
}
+ prec->epvt = eventNameToHandle(prec->val);
+
if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) )
status=(*pdset->init_record)(prec);
return(status);
@@ -123,7 +126,7 @@
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
- if(prec->val>0) post_event((int)prec->val);
+ postEvent(prec->epvt);
recGblGetTimeStamp(prec);
@@ -137,10 +140,21 @@
return(status);
}
+
+static long special(DBADDR *paddr, int after)
+{
+ eventRecord *prec = (eventRecord *)paddr->precord;
+
+ if (!after) return 0;
+ if (dbGetFieldIndex(paddr) == eventRecordVAL) {
+ prec->epvt = eventNameToHandle(prec->val);
+ }
+}
+
static long get_value(eventRecord *prec, struct valueDes *pvdes)
{
- pvdes->field_type = DBF_USHORT;
+ pvdes->field_type = DBF_STRING;
pvdes->no_elements=1;
pvdes->pvalue = (void *)(&prec->val);
return(0);
@@ -177,10 +191,13 @@
return(status);
}
if (prec->simm == menuYesNoYES){
- status=dbGetLink(&(prec->siol),DBR_USHORT,
+ status=dbGetLink(&(prec->siol),DBR_STRING,
&(prec->sval),0,0);
if (status==0) {
- prec->val=prec->sval;
+ if (strcmp(prec->sval, prec->val) != 0) {
+ strcpy(prec->val, prec->sval);
+ prec->epvt = eventNameToHandle(prec->val);
+ }
prec->udf=FALSE;
}
} else {
=== modified file 'src/rec/eventRecord.dbd'
--- src/rec/eventRecord.dbd 2002-07-12 21:35:43 +0000
+++ src/rec/eventRecord.dbd 2010-10-27 20:51:01 +0000
@@ -9,10 +9,19 @@
#*************************************************************************
recordtype(event) {
include "dbCommon.dbd"
- field(VAL,DBF_USHORT) {
- prompt("Event Number To Post")
+ field(VAL,DBF_STRING) {
+ prompt("Event Name To Post")
promptgroup(GUI_INPUTS)
+ special(SPC_MOD)
asl(ASL0)
+ size(40)
+ }
+ %#include "dbScan.h"
+ field(EPVT, DBF_NOACCESS) {
+ prompt("Event private")
+ special(SPC_NOMOD)
+ interest(4)
+ extra("EVENTPVT epvt")
}
field(INP,DBF_INLINK) {
prompt("Input Specification")
@@ -24,8 +33,9 @@
promptgroup(GUI_INPUTS)
interest(1)
}
- field(SVAL,DBF_USHORT) {
+ field(SVAL,DBF_STRING) {
prompt("Simulation Value")
+ size(40)
}
field(SIML,DBF_INLINK) {
prompt("Sim Mode Location")