diff --git a/src/sequencer/Version b/src/sequencer/Version index 39c0fc0a5..758abfe98 100755 --- a/src/sequencer/Version +++ b/src/sequencer/Version @@ -1,3 +1,3 @@ -1.9.0(3.12.1) +1.9.1 diff --git a/src/sequencer/gen_ss_code.c b/src/sequencer/gen_ss_code.c index 89b0f1855..693512b53 100644 --- a/src/sequencer/gen_ss_code.c +++ b/src/sequencer/gen_ss_code.c @@ -81,7 +81,7 @@ Expr *sp; printf("\n/* Delay function for state \"%s\" in state set \"%s\" */\n", sp->value, ssp->value); - printf("static D_%s_%s(ssId, pVar)\n", ssp->value, sp->value); + printf("static void D_%s_%s(ssId, pVar)\n", ssp->value, sp->value); printf("SS_ID\tssId;\n"); printf("struct UserVar\t*pVar;\n{\n"); @@ -108,7 +108,7 @@ Expr *sp; #ifdef DEBUG fprintf("stderr, "eval_delay: type=%s\n", stype[ep->type]); -#endif /* DEBUG */ +#endif DEBUG /* Generate 1-st part of function w/ 1-st 2 parameters */ delay_id = (int)ep->right; /* delay id was previously assigned */ @@ -140,7 +140,8 @@ Expr *ssp; /* Parent state set */ /* Action function declaration */ printf("\n/* Action function for state \"%s\" in state set \"%s\" */\n", sp->value, ssp->value); - printf("static A_%s_%s(ssId, pVar, transNum)\n", ssp->value, sp->value); + printf("static void A_%s_%s(ssId, pVar, transNum)\n", + ssp->value, sp->value); printf("SS_ID\tssId;\n"); printf("struct UserVar\t*pVar;\n"); printf("short\ttransNum;\n{\n"); @@ -186,7 +187,7 @@ Expr *ssp; printf("\n/* Event function for state \"%s\" in state set \"%s\" */\n", sp->value, ssp->value); - printf("static E_%s_%s(ssId, pVar, pTransNum, pNextState)\n", + printf("static long E_%s_%s(ssId, pVar, pTransNum, pNextState)\n", ssp->value, sp->value); printf("SS_ID\tssId;\n"); printf("struct UserVar\t*pVar;\n"); @@ -322,7 +323,7 @@ int level; /* indentation level */ case E_VAR: #ifdef DEBUG fprintf(stderr, "E_VAR: %s\n", ep->value); -#endif /* DEBUG */ +#endif DEBUG if(reent_opt) { /* Make variables point to allocated structure */ Var *vp; @@ -349,7 +350,7 @@ int level; /* indentation level */ case E_FUNC: #ifdef DEBUG fprintf(stderr, "E_FUNC: %s\n", ep->value); -#endif /* DEBUG */ +#endif DEBUG if (special_func(stmt_type, ep, sp)) break; printf("%s(", ep->value); @@ -469,7 +470,7 @@ Expr *sp; /* current State struct */ #ifdef DEBUG fprintf(stderr, "special_func: func_code=%d\n", func_code); -#endif /* DEBUG */ +#endif DEBUG switch (func_code) { case F_DELAY: @@ -620,7 +621,7 @@ char *fname; /* function name */ { #ifdef DEBUG fprintf(stderr, "gen_pv_func: var=%s\n", ep1->value); -#endif /* DEBUG */ +#endif DEBUG cp = vp->chan; index = cp->index; } @@ -664,7 +665,7 @@ gen_exit_handler() Expr *ep; printf("/* Exit handler */\n"); - printf("static exit_handler(ssId, pVar)\n"); + printf("static void exit_handler(ssId, pVar)\n"); printf("int\tssId;\n"); printf("struct UserVar\t*pVar;\n{\n"); for (ep = exit_code_list; ep != 0; ep = ep->next) diff --git a/src/sequencer/gen_tables.c b/src/sequencer/gen_tables.c index 9fef4c48c..fe02eca58 100644 --- a/src/sequencer/gen_tables.c +++ b/src/sequencer/gen_tables.c @@ -13,6 +13,7 @@ 01mar94,ajk Implemented new interface to sequencer (see seqCom.h). 01mar94,ajk Implemented assignment of array elements to db channels. 17may94,ajk removed old event flag (-e) option. +20jul95,ajk Added unsigned types. ***************************************************************************/ /*#define DEBUG 1*/ @@ -75,7 +76,7 @@ gen_db_blocks() #ifdef DEBUG fprintf(stderr, "gen_db_blocks: index=%d, num_elem=%d\n", cp->index, cp->num_elem); -#endif /* DEBUG */ +#endif DEBUG if (cp->num_elem == 0) { /* Variable assigned to single pv */ @@ -185,6 +186,10 @@ int type; case V_SHORT: return "short"; case V_INT: return "int"; case V_LONG: return "long"; + case V_UCHAR: return "unsigned char"; + case V_USHORT:return "unsigned short"; + case V_UINT: return "unsigned int"; + case V_ULONG: return "unsigned long"; case V_FLOAT: return "float"; case V_DOUBLE: return "double"; case V_STRING: return "string"; @@ -415,7 +420,7 @@ int numEventWords; for (n = 0; n < numEventWords; n++) fprintf(stderr, " 0x%x", pEventWords[n]); fprintf(stderr, "\n"); -#endif /* DEBUG */ +#endif DEBUG } /* Evaluate the event mask for a given transition (when() statement). diff --git a/src/sequencer/parse.c b/src/sequencer/parse.c index a9d749507..9af8067ae 100644 --- a/src/sequencer/parse.c +++ b/src/sequencer/parse.c @@ -30,7 +30,7 @@ #ifndef TRUE #define TRUE 1 #define FALSE 0 -#endif /* TRUE */ +#endif TRUE int debug_print_opt = 0; /* Debug level (set by source file) */ @@ -187,7 +187,7 @@ char *db_name; /* ptr to db name */ #ifdef DEBUG fprintf(stderr, "assign %s to \"%s\";\n", name, db_name); -#endif /* DEBUG */ +#endif DEBUG /* Find the variable */ vp = (Var *)findVar(name); if (vp == 0) @@ -230,7 +230,7 @@ char *db_name; /* ptr to db name */ #ifdef DEBUG fprintf(stderr, "assign %s[%s] to \"%s\";\n", name, subscript, db_name); -#endif /* DEBUG */ +#endif DEBUG /* Find the variable */ vp = (Var *)findVar(name); if (vp == 0) @@ -303,7 +303,7 @@ Expr *db_name_list; /* ptr to db name list */ #ifdef DEBUG fprintf(stderr, "assign %s to {", name); -#endif /* DEBUG */ +#endif DEBUG /* Find the variable */ vp = (Var *)findVar(name); if (vp == 0) @@ -342,7 +342,7 @@ Expr *db_name_list; /* ptr to db name list */ #ifdef DEBUG fprintf(stderr, "\"%s\", ", db_name_list->value); -#endif /* DEBUG */ +#endif DEBUG cp->db_name_list[elem_num] = db_name_list->value; /* DB name */ cp->count = vp->length2; @@ -350,7 +350,7 @@ Expr *db_name_list; /* ptr to db name list */ } #ifdef DEBUG fprintf(stderr, "};\n"); -#endif /* DEBUG */ +#endif DEBUG return; } @@ -418,7 +418,7 @@ char *subscript; /* element number or NULL */ #ifdef DEBUG fprintf(stderr, "monitor_stmt: name=%s[%s]\n", name, subscript); -#endif /* DEBUG */ +#endif DEBUG /* Find the variable */ vp = (Var *)findVar(name); @@ -488,7 +488,7 @@ char *ef_name; #ifdef DEBUG fprintf(stderr, "sync_stmt: name=%s, subNum=%s, ef_name=%s\n", name, subscript, ef_name); -#endif /* DEBUG */ +#endif DEBUG vp = (Var *)findVar(name); if (vp == 0) @@ -625,7 +625,7 @@ Expr *prog_list; ss_list = prog_list; #ifdef DEBUG fprintf(stderr, "----Phase2---\n"); -#endif /* DEBUG */ +#endif DEBUG phase2(ss_list); exit(0); @@ -701,7 +701,7 @@ Expr *ep2; /* beginning 2-nd (append it to 1-st) */ break; } fprintf(stderr, ")\n"); -#endif /* DEBUG */ +#endif DEBUG return ep1; } diff --git a/src/sequencer/phase2.c b/src/sequencer/phase2.c index 90b588b7c..9b6e472ca 100644 --- a/src/sequencer/phase2.c +++ b/src/sequencer/phase2.c @@ -144,7 +144,7 @@ reconcile_variables() { #ifdef DEBUG fprintf(stderr, "reconcile_variables: ss=%s\n", ssp->value); -#endif /* DEBUG */ +#endif DEBUG traverseExprTree(ssp, E_VAR, 0, connect_variable, 0); } @@ -261,6 +261,18 @@ gen_var_decl() case V_SHORT: vstr = "short"; break; + case V_UCHAR: + vstr = "unsigned char"; + break; + case V_UINT: + vstr = "unsigned int"; + break; + case V_ULONG: + vstr = "unsigned long"; + break; + case V_USHORT: + vstr = "unsigned short"; + break; case V_FLOAT: vstr = "float"; break; @@ -432,7 +444,7 @@ assign_delay_ids() #ifdef DEBUG fprintf(stderr, "assign_delay_ids:\n"); -#endif /* DEBUG */ +#endif DEBUG for (ssp = ss_list; ssp != 0; ssp = ssp->next) { for (sp = ssp->left; sp != 0; sp = sp->next) diff --git a/src/sequencer/seq.h b/src/sequencer/seq.h index 0a733ea07..340920d60 100644 --- a/src/sequencer/seq.h +++ b/src/sequencer/seq.h @@ -1,4 +1,4 @@ -/* /share/epicsH %W% %G% +/* base/include $Id$ * * DESCRIPTION: Definitions for the run-time sequencer. * @@ -57,12 +57,10 @@ #include "cadef.h" #include "db_access.h" #include "alarm.h" -#ifdef vxWorks #include "vxWorks.h" #include "ioLib.h" #include "semLib.h" #include "taskLib.h" -#endif /* vxWorks */ #endif /* Structure to hold information about database channels */ @@ -73,14 +71,14 @@ struct db_channel char *pVar; /* ptr to variable */ char *pVarName; /* variable name string */ char *pVarType; /* variable type string (e.g. ("int") */ - int count; /* number of elements in array */ - int efId; /* event flag id if synced */ - int eventNum; /* event number */ + long count; /* number of elements in array */ + long efId; /* event flag id if synced */ + long eventNum; /* event number */ BOOL monFlag; /* TRUE if channel is to be monitored */ /* These are filled in at run time */ char *dbName; /* channel name after macro expansion */ - int index; /* index in array of db channels */ + long index; /* index in array of db channels */ chid chid; /* ptr to channel id (from ca_search()) */ BOOL assigned; /* TRUE only if channel is assigned */ BOOL connected; /* TRUE only if channel is connected */ @@ -88,7 +86,7 @@ struct db_channel short dbOffset; /* Offset to value in db access structure */ short status; /* last db access status code */ TS_STAMP timeStamp; /* time stamp */ - int dbCount; /* actual count for db access */ + long dbCount; /* actual count for db access */ short severity; /* last db access severity code */ short size; /* size (in bytes) of single variable element */ short getType; /* db get type (e.g. DBR_STS_INT) */ @@ -104,9 +102,9 @@ typedef struct db_channel CHAN; struct state_info_block { char *pStateName; /* state name */ - FUNCPTR actionFunc; /* ptr to action routine for this state */ - FUNCPTR eventFunc; /* ptr to event routine for this state */ - FUNCPTR delayFunc; /* ptr to delay setup routine for this state */ + ACTION_FUNC actionFunc; /* ptr to action routine for this state */ + EVENT_FUNC eventFunc; /* ptr to event routine for this state */ + DELAY_FUNC delayFunc; /* ptr to delay setup routine for this state */ bitMask *pEventMask; /* event mask for this state */ }; typedef struct state_info_block STATE; @@ -116,11 +114,11 @@ typedef struct state_info_block STATE; struct state_set_control_block { char *pSSName; /* state set name (for debugging) */ - int taskId; /* task id */ - int taskPriority; /* task priority */ + long taskId; /* task id */ + long taskPriority; /* task priority */ SEM_ID syncSemId; /* semaphore for event sync */ SEM_ID getSemId; /* semaphore for synchronous pvGet() */ - int numStates; /* number of states */ + long numStates; /* number of states */ STATE *pStates; /* ptr to array of state blocks */ short currentState; /* current state index */ short nextState; /* next state index */ @@ -128,7 +126,7 @@ struct state_set_control_block short errorState; /* error state index (-1 if none defined) */ short transNum; /* highest priority trans. # that triggered */ bitMask *pMask; /* current event mask */ - int numDelays; /* number of delays activated */ + long numDelays; /* number of delays activated */ ULONG delay[MAX_NDELAY]; /* queued delay value in tics */ BOOL delayExpired[MAX_NDELAY]; /* TRUE if delay expired */ ULONG timeEntered; /* time that a state was entered */ @@ -148,26 +146,26 @@ typedef struct macro { struct state_program { char *pProgName; /* program name (for debugging) */ - int taskId; /* task id (main task) */ + long taskId; /* task id (main task) */ BOOL task_is_deleted;/* TRUE if main task has been deleted */ - int taskPriority; /* task priority */ + long taskPriority; /* task priority */ SEM_ID caSemId; /* semiphore for locking CA events */ CHAN *pChan; /* table of channels */ - int numChans; /* number of db channels, incl. unassigned */ - int assignCount; /* number of db channels assigned */ - int connCount; /* number of channels connected */ + long numChans; /* number of db channels, incl. unassigned */ + long assignCount; /* number of db channels assigned */ + long connCount; /* number of channels connected */ SSCB *pSS; /* array of state set control blocks */ - int numSS; /* number of state sets */ + long numSS; /* number of state sets */ char *pVar; /* ptr to user variable area */ - int varSize; /* # bytes in user variable area */ + long varSize; /* # bytes in user variable area */ MACRO *pMacros; /* ptr to macro table */ char *pParams; /* program paramters */ bitMask *pEvents; /* event bits for event flags & db */ - int numEvents; /* number of events */ - int options; /* options (bit-encoded) */ - FUNCPTR exitFunc; /* exit function */ + long numEvents; /* number of events */ + long options; /* options (bit-encoded) */ + EXIT_FUNC exitFunc; /* exit function */ SEM_ID logSemId; /* logfile locking semaphore */ - int logFd; /* logfile file descr. */ + long logFd; /* logfile file descr. */ }; typedef struct state_program SPROG; @@ -179,20 +177,20 @@ typedef struct state_program SPROG; #define SPAWN_PRIORITY 100 /* Function declarations for internal sequencer funtions */ -int seqConnect(SPROG *); +long seqConnect(SPROG *); VOID seqEventHandler(struct event_handler_args); VOID seqConnHandler(struct connection_handler_args); VOID seqCallbackHandler(struct event_handler_args); -VOID seqWakeup(SPROG *, int); -int seq(struct seqProgram *, char *, int); +VOID seqWakeup(SPROG *, long); +long seq(struct seqProgram *, char *, long); VOID seqFree(SPROG *); -int sequencer(SPROG *, int, char *); +long sequencer(SPROG *, long, char *); VOID ssEntry(SPROG *, SSCB *); -int sprogDelete(int); -int seqMacParse(char *, SPROG *); +long sprogDelete(long); +long seqMacParse(char *, SPROG *); char *seqMacValGet(MACRO *, char *); -VOID seqMacEval(char *, char *, int, MACRO *); +VOID seqMacEval(char *, char *, long, MACRO *); STATUS seq_log(); -SPROG *seqFindProg(int); +SPROG *seqFindProg(long); -#endif /* INCLseqh */ +#endif /*INCLseqh*/ diff --git a/src/sequencer/seqCom.h b/src/sequencer/seqCom.h index 93064db0c..206615c54 100644 --- a/src/sequencer/seqCom.h +++ b/src/sequencer/seqCom.h @@ -1,4 +1,4 @@ -/* * base/include seqCom.h,v 1.3 1995/10/10 01:25:08 wright Exp +/* * base/include $Id$ * * DESCRIPTION: Common definitions for state programs and run-time sequencer. * @@ -21,13 +21,14 @@ * Los Alamos National Laboratory * Modification Log: * ----------------- - * + * 09aug95,ajk added PVOIDFUNC type, added , and fixed #endif. */ #ifndef INCLseqComh #define INCLseqComh #define MAGIC 940501 /* current magic number for SPROG */ +#include /* standard i/o defs */ #include "tsDefs.h" /* time stamp defs */ /* Bit encoding for run-time options */ @@ -50,9 +51,12 @@ typedef long bitMask; #ifndef TRUE #define TRUE 1 #define FALSE 0 -#endif /* TRUE */ +#endif /*TRUE*/ -typedef int (*PFUNC)(); /* ptr to a function */ +typedef void (*ACTION_FUNC)(); +typedef long (*EVENT_FUNC)(); +typedef void (*DELAY_FUNC)(); +typedef void (*EXIT_FUNC)(); typedef long SS_ID; /* state set id */ #ifdef OFFSET @@ -60,7 +64,7 @@ typedef long SS_ID; /* state set id */ #endif /* The OFFSET macro calculates the byte offset of a structure member * from the start of a structure */ -#define OFFSET(structure, member) ((int) &(((structure *) 0) -> member)) +#define OFFSET(structure, member) ((long) &(((structure *) 0) -> member)) /* Structure to hold information about database channels */ struct seqChan @@ -70,19 +74,19 @@ struct seqChan * or structure offset (+r option) */ char *pVarName; /* variable name, including subscripts */ char *pVarType; /* variable type, e.g. "int" */ - int count; /* element count for arrays */ - int eventNum; /* event number for this channel */ - int efId; /* event flag id if synced */ - int monFlag; /* TRUE if channel is to be monitored */ + long count; /* element count for arrays */ + long eventNum; /* event number for this channel */ + long efId; /* event flag id if synced */ + long monFlag; /* TRUE if channel is to be monitored */ }; /* Structure to hold information about a state */ struct seqState { char *pStateName; /* state name */ - PFUNC actionFunc; /* action routine for this state */ - PFUNC eventFunc; /* event routine for this state */ - PFUNC delayFunc; /* delay setup routine for this state */ + ACTION_FUNC actionFunc; /* action routine for this state */ + EVENT_FUNC eventFunc; /* event routine for this state */ + DELAY_FUNC delayFunc; /* delay setup routine for this state */ bitMask *pEventMask; /* event mask for this state */ }; @@ -91,24 +95,24 @@ struct seqSS { char *pSSName; /* state set name */ struct seqState *pStates; /* array of state blocks */ - int numStates; /* number of states in this state set */ - int errorState; /* error state index (-1 if none defined) */ + long numStates; /* number of states in this state set */ + long errorState; /* error state index (-1 if none defined) */ }; /* All information about a state program */ struct seqProgram { - int magic; /* magic number */ + long magic; /* magic number */ char *pProgName; /* program name (for debugging) */ struct seqChan *pChan; /* table of channels */ - int numChans; /* number of db channels */ + long numChans; /* number of db channels */ struct seqSS *pSS; /* array of state set info structs */ - int numSS; /* number of state sets */ - int varSize; /* # bytes in user variable area */ + long numSS; /* number of state sets */ + long varSize; /* # bytes in user variable area */ char *pParams; /* program paramters */ - int numEvents; /* number of event flags */ - int options; /* options (bit-encoded) */ - PFUNC exitFunc; /* exit function */ + long numEvents; /* number of event flags */ + long options; /* options (bit-encoded) */ + EXIT_FUNC exitFunc; /* exit function */ }; @@ -121,30 +125,30 @@ struct seqProgram */ /*#define ANSI*/ #ifdef ANSI -void seq_efSet(SS_ID, int); /* set an event flag */ -int seq_efTest(SS_ID, int); /* test an event flag */ -int seq_efClear(SS_ID, int); /* clear an event flag */ -int seq_efTestAndClear(SS_ID, int); /* test & clear an event flag */ -int seq_pvGet(SS_ID, int); /* get pv value */ -int seq_pvPut(SS_ID, int); /* put pv value */ -TS_STAMP seq_pvTimeStamp(SS_ID, int); /* get time stamp value */ -int seq_pvAssign(SS_ID, int, char *);/* assign/connect to a pv */ -int seq_pvMonitor(SS_ID, int); /* enable monitoring on pv */ -int seq_pvStopMonitor(SS_ID, int); /* disable monitoring on pv */ -int seq_pvStatus(SS_ID, int); /* returns pv alarm status code */ -int seq_pvSeverity(SS_ID, int); /* returns pv alarm severity */ -int seq_pvAssigned(SS_ID, int); /* returns TRUE if assigned */ -int seq_pvConnected(SS_ID, int); /* TRUE if connected */ -int seq_pvGetComplete(SS_ID, int); /* TRUE if last get completed */ -int seq_pvChannelCount(SS_ID); /* returns number of channels */ -int seq_pvConnectCount(SS_ID); /* returns number of channels connected */ -int seq_pvAssignCount(SS_ID); /* returns number of channels assigned */ -int seq_pvCount(SS_ID, int); /* returns number of elements in array */ +void seq_efSet(SS_ID, long); /* set an event flag */ +long seq_efTest(SS_ID, long); /* test an event flag */ +long seq_efClear(SS_ID, long); /* clear an event flag */ +long seq_efTestAndClear(SS_ID, long);/* test & clear an event flag */ +long seq_pvGet(SS_ID, long); /* get pv value */ +long seq_pvPut(SS_ID, long); /* put pv value */ +TS_STAMP seq_pvTimeStamp(SS_ID, long); /* get time stamp value */ +long seq_pvAssign(SS_ID, long, char *);/* assign/connect to a pv */ +long seq_pvMonitor(SS_ID, long); /* enable monitoring on pv */ +long seq_pvStopMonitor(SS_ID, long); /* disable monitoring on pv */ +long seq_pvStatus(SS_ID, long); /* returns pv alarm status code */ +long seq_pvSeverity(SS_ID, long); /* returns pv alarm severity */ +long seq_pvAssigned(SS_ID, long); /* returns TRUE if assigned */ +long seq_pvConnected(SS_ID, long); /* TRUE if connected */ +long seq_pvGetComplete(SS_ID, long); /* TRUE if last get completed */ +long seq_pvChannelCount(SS_ID); /* returns number of channels */ +long seq_pvConnectCount(SS_ID); /* returns number of channels connected */ +long seq_pvAssignCount(SS_ID); /* returns number of channels assigned */ +long seq_pvCount(SS_ID, long); /* returns number of elements in array */ void seq_pvFlush(); /* flush put/get requests */ -int seq_pvIndex(SS_ID, int); /* returns index of pv */ -int seq_seqLog(); /* Logging: variable number of parameters */ -void seq_delayInit(SS_ID, int, float);/* initialize a delay entry */ -int seq_delay(SS_ID, int); /* test a delay entry */ +long seq_pvIndex(SS_ID, long); /* returns index of pv */ +long seq_seqLog(); /* Logging: variable number of parameters */ +void seq_delayInit(SS_ID, long, float);/* initialize a delay entry */ +long seq_delay(SS_ID, long); /* test a delay entry */ char *seq_macValueGet(SS_ID, char *); /* Given macro name, return ptr to value */ -#endif /* ANSI */ -#endif /* INCLseqComh */ +#endif /*ANSI*/ +#endif /*INCLseqComh*/ diff --git a/src/sequencer/seq_ca.c b/src/sequencer/seq_ca.c index 3a1c50258..c2da2371b 100644 --- a/src/sequencer/seq_ca.c +++ b/src/sequencer/seq_ca.c @@ -43,24 +43,25 @@ * 28mar94,ajk Restructured event& callback handlers to call proc_db_events(). * 29mar94,ajk Removed getPtrToValue(). Offset is now in db_channel structure. * 08apr94,ajk Added support for time stamp. + * 17jan96,ajk Removed ca_import_cancel(), which is now in channel access lib. + * 17jan96,ajk Many routines changed to use ANSI-style function headers. */ #define ANSI #include "seq.h" -LOCAL VOID proc_db_events(union db_access_val *, CHAN *, int); +LOCAL VOID proc_db_events(union db_access_val *, CHAN *, long); /*#define DEBUG*/ #ifdef DEBUG #undef LOCAL #define LOCAL -#endif /* DEBUG */ +#endif DEBUG /* * seq_connect() - Connect to all database channels through channel access. */ -seq_connect(pSP) -SPROG *pSP; +long seq_connect(SPROG *pSP) { CHAN *pDB; int status, i; @@ -79,7 +80,7 @@ SPROG *pSP; #ifdef DEBUG logMsg("seq_connect: connect %s to %s\n", pDB->pVarName, pDB->dbName); -#endif /* DEBUG */ +#endif DEBUG /* Connect to it */ status = ca_build_and_connect( pDB->dbName, /* DB channel name */ @@ -118,8 +119,7 @@ SPROG *pSP; * args points to CA event handler argument structure. args.usr contains * a pointer to the channel structure (CHAN *). */ -VOID seq_event_handler(args) -struct event_handler_args args; +VOID seq_event_handler(struct event_handler_args args) { /* Process event handling in each state set */ proc_db_events((union db_access_val *)args.dbr, (CHAN *)args.usr, MON_COMPLETE); @@ -132,8 +132,7 @@ struct event_handler_args args; * Called when a "get" completes. * args.usr points to the db structure (CHAN *) for tis channel. */ -VOID seq_callback_handler(args) -struct event_handler_args args; +VOID seq_callback_handler(struct event_handler_args args) { /* Process event handling in each state set */ @@ -143,10 +142,7 @@ struct event_handler_args args; } /* Common code for event and callback handling */ -LOCAL VOID proc_db_events(pAccess, pDB, complete_type) -union db_access_val *pAccess; -CHAN *pDB; -int complete_type; +LOCAL VOID proc_db_events(union db_access_val *pAccess, CHAN *pDB, long complete_type) { SPROG *pSP; void *pVal; @@ -154,7 +150,7 @@ int complete_type; #ifdef DEBUG logMsg("proc_db_events: var=%s, pv=%s\n", pDB->VarName, pDB->dbName); -#endif /* DEBUG */ +#endif DEBUG /* Copy value returned into user variable */ pVal = (void *)pAccess + pDB->dbOffset; /* ptr to data in CA structure */ @@ -170,6 +166,12 @@ int complete_type; /* Get ptr to the state program that owns this db entry */ pSP = pDB->sprog; + /* Indicate completed pvGet() */ + if (complete_type == GET_COMPLETE) + { + pDB->getComplete = TRUE; + } + /* Wake up each state set that uses this channel in an event */ seqWakeup(pSP, pDB->eventNum); @@ -177,28 +179,24 @@ int complete_type; if (pDB-> efId > 0) seq_efSet((SS_ID)pSP->pSS, pDB->efId); - /* Special processing for completed pvGet() */ - if (complete_type == GET_COMPLETE) - { - pDB->getComplete = TRUE; - - /* If syncronous pvGet then notify pending state set */ - if (pDB->getSemId != NULL) - semGive(pDB->getSemId); - } + /* Special processing for completed synchronous (-a) pvGet() */ + if ( (complete_type == GET_COMPLETE) && ((pSP->options & OPT_ASYNC) == 0) ) + semGive(pDB->getSemId); return; } /* Disconnect all database channels */ -seq_disconnect(pSP) -SPROG *pSP; +/*#define DEBUG_DISCONNECT*/ + +long seq_disconnect(SPROG *pSP) { CHAN *pDB; STATUS status; + extern int ca_static; int i; extern int seqAuxTaskId; - SPROG *pMySP; /* NULL if this task is not a sequencer task */ + SPROG *pMySP; /* will be NULL if this task is not a sequencer task */ /* Did we already disconnect? */ if (pSP->connCount < 0) @@ -208,7 +206,8 @@ SPROG *pSP; pMySP = seqFindProg(taskIdSelf() ); if (pMySP == NULL) { - ca_import(seqAuxTaskId); /* not a sequencer task */ + status = ca_import(seqAuxTaskId); /* not a sequencer task */ + SEVCHK (status, "seq_disconnect: ca_import"); } pDB = pSP->pChan; @@ -216,20 +215,14 @@ SPROG *pSP; { if (!pDB->assigned) continue; -#ifdef DEBUG +#ifdef DEBUG_DISCONNECT logMsg("seq_disconnect: disconnect %s from %s\n", pDB->pVarName, pDB->dbName); taskDelay(30); -#endif /* DEBUG */ +#endif /*DEBUG_DISCONNECT*/ /* Disconnect this channel */ status = ca_clear_channel(pDB->chid); - - if (status != ECA_NORMAL) - { - /* SEVCHK(status, "ca_clear_chan"); */ - /* ca_task_exit(); */ - /* return -1; */ - } + SEVCHK (status, "seq_disconnect: ca_clear_channel"); /* Clear monitor & connect indicators */ pDB->monitored = FALSE; @@ -243,8 +236,11 @@ SPROG *pSP; /* Cancel CA context if it was imported above */ if (pMySP == NULL) { -logMsg("seq_disconnect: cancel import CA context\n"); - ca_import_cancel(taskIdSelf()); +#ifdef DEBUG_DISCONNECT + logMsg("seq_disconnect: ca_import_cancel\n"); +#endif /*DEBUG_DISCONNECT*/ + /*ca_import_cancel(taskIdSelf());*/ + status = taskVarDelete(taskIdSelf(), &ca_static); } return 0; @@ -254,8 +250,7 @@ logMsg("seq_disconnect: cancel import CA context\n"); * seq_conn_handler() - Sequencer connection handler. * Called each time a connection is established or broken. */ -VOID seq_conn_handler(args) -struct connection_handler_args args; +VOID seq_conn_handler(struct connection_handler_args args) { CHAN *pDB; SPROG *pSP; @@ -274,7 +269,7 @@ struct connection_handler_args args; pDB->monitored = FALSE; #ifdef DEBUG logMsg("%s disconnected from %s\n", pDB->VarName, pDB->dbName); -#endif /* DEBUG */ +#endif DEBUG } else /* PV connected */ { @@ -284,7 +279,7 @@ struct connection_handler_args args; pDB->monitored = TRUE; #ifdef DEBUG logMsg("%s connected to %s\n", pDB->VarName, pDB->dbName); -#endif /* DEBUG */ +#endif DEBUG pDB->dbCount = ca_element_count(args.chid); if (pDB->dbCount > pDB->count) pDB->dbCount = pDB->count; @@ -300,9 +295,7 @@ struct connection_handler_args args; * seqWakeup() -- wake up each state set that is waiting on this event * based on the current event mask. EventNum = 0 means wake all state sets. */ -VOID seqWakeup(pSP, eventNum) -SPROG *pSP; -int eventNum; +VOID seqWakeup(SPROG *pSP, long eventNum) { int nss; SSCB *pSS; @@ -319,75 +312,3 @@ int eventNum; } return; } - #include "memLib.h" -#include "taskVarLib.h" -#include "taskLib.h" -/******************************************************************************* -* P A T C H E D 5.02b -- allows call from taskDeleteHook routine -- ajk -* taskVarDelete - remove a task variable from a task -* -* This routine removes the specified task variable from the calling -* task's context. The private value of that variable is lost. -* -* RETURNS -* OK, or -* ERROR if the calling task does not own the specified task variable. -* -* SEE ALSO: taskVarAdd(2), taskVarGet(2), taskVarSet(2) -*/ - -LOCAL STATUS LtaskVarDelete (tid, pVar) - int tid; /* task id whose task variable is to be retrieved */ - int *pVar; /* pointer to task variable to be removed from task */ - - { - FAST TASK_VAR **ppTaskVar; /* ptr to ptr to next node */ - FAST TASK_VAR *pTaskVar; - WIND_TCB *pTcb = (WIND_TCB *)tid; /* P A T C H -- ajk 19feb93*/ - - if (pTcb == NULL) /* check that task is valid */ - return (ERROR); - - /* find descriptor for specified task variable */ - - for (ppTaskVar = &pTcb->pTaskVar; - *ppTaskVar != NULL; - ppTaskVar = &((*ppTaskVar)->next)) - { - pTaskVar = *ppTaskVar; - - if (pTaskVar->address == pVar) - { - /* if active task, replace background value */ - - if (taskIdCurrent == pTcb) - *pVar = pTaskVar->value; - - *ppTaskVar = pTaskVar->next;/* delete variable from list */ - - free ((char *)pTaskVar); /* free storage of deleted cell */ - - return (OK); - } - } - - /* specified address is not a task variable for specified task */ - - errnoSet (S_taskLib_TASK_VAR_NOT_FOUND); - return (ERROR); - } - /* Temporary routine to cancel ca_import() -- THIS SHOULD GO INTO CHANNEL ACCESS! */ -ca_import_cancel(tid) -int tid; -{ - extern int ca_static; - int status; - - status = LtaskVarDelete(tid, &ca_static); - if (status != OK) - { - logMsg("Seq: taskVarDelete failed for tid = 0x%x\n", tid); - } - - return status; -} diff --git a/src/sequencer/seq_if.c b/src/sequencer/seq_if.c index 5b6711683..9488dcc3a 100644 --- a/src/sequencer/seq_if.c +++ b/src/sequencer/seq_if.c @@ -68,9 +68,7 @@ void seq_pvFlush() /* * seq_pvGet() - Get DB value (uses channel access). */ -seq_pvGet(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvGet(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ SSCB *pSS; @@ -90,7 +88,7 @@ int pvId; pDB->getComplete = FALSE; /* If synchronous pvGet then clear the pvGet pend semaphore */ - if ( !(pSP->options & OPT_ASYNC) ) + if ((pSP->options & OPT_ASYNC) == 0) { pDB->getSemId = pSS->getSemId; semTake(pSS->getSemId, NO_WAIT); @@ -101,63 +99,73 @@ int pvId; pDB->getType, /* db request type */ pDB->count, /* element count */ pDB->chid, /* chid */ - seq_callback_handler, /* callback handler */ + seq_callback_handler +, /* callback handler */ pDB); /* user arg */ - if ( (pSP->options & OPT_ASYNC) || (status != ECA_NORMAL) ) - return status; + if (status != ECA_NORMAL) + { + pDB->getComplete = TRUE; + SEVCHK(status, "pvGet"); - /* Synchronous pvGet() */ + return status; + } ca_flush_io(); + if ((pSP->options & OPT_ASYNC) != 0) + { /* +a option: return immediately */ + return ECA_NORMAL; + } - /* Wait for completion (10s timeout) */ + /* Synchronous (-a option): wait for completion (10s timeout) */ sem_status = semTake(pSS->getSemId, 600); - if (sem_status == ERROR) - status = ECA_TIMEOUT; + if (sem_status != OK) + { + logMsg ("semTake error=%d\n", sem_status); + return ECA_TIMEOUT; + } - return status; + return ECA_NORMAL; } /* * seq_pvGetComplete() - returns TRUE if the last get completed. */ -seq_pvGetComplete(ssId, pvId) -SS_ID ssId; -int pvId; -{ - SPROG *pSP; /* ptr to state program */ - CHAN *pDB; /* ptr to channel struct */ - int status; - - pSP = ((SSCB *)ssId)->sprog; - pDB = pSP->pChan; - return pDB->getComplete; -} - - -/* - * seq_pvPut() - Put DB value. - */ -seq_pvPut(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvGetComplete(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ int status; + pSP = ((SSCB *)ssId)->sprog; + pDB = pSP->pChan + pvId; + return pDB->getComplete; +} + + +/* + * seq_pvPut() - Put DB value. + */ +long seq_pvPut(SS_ID ssId, long pvId) +{ + SPROG *pSP; /* ptr to state program */ + CHAN *pDB; /* ptr to channel struct */ + int status, count; + pSP = ((SSCB *)ssId)->sprog; pDB = pSP->pChan + pvId; #ifdef DEBUG logMsg("seq_pvPut: pv name=%s, pVar=0x%x\n", pDB->dbName, pDB->pVar); -#endif /* DEBUG */ +#endif DEBUG if (!pDB->connected) return ECA_DISCONN; - status = ca_array_put(pDB->putType, pDB->count, - pDB->chid, pDB->pVar); + count = pDB->count; + if (count > pDB->dbCount) + count = pDB->dbCount; /* don't try to put more than db count */ + status = ca_array_put(pDB->putType, count, pDB->chid, pDB->pVar); + #ifdef DEBUG logMsg("seq_pvPut: status=%d\n", status); if (status != ECA_NORMAL) @@ -165,9 +173,9 @@ int pvId; seq_log(pSP, "pvPut on \"%s\" failed (%d)\n", pDB->dbName, status); seq_log(pSP, " putType=%d\n", pDB->putType); - seq_log(pSP, " size=%d, count=%d\n", pDB->size, pDB->count); + seq_log(pSP, " size=%d, count=%d\n", pDB->size, count); } -#endif /* DEBUG */ +#endif DEBUG return status; } @@ -175,10 +183,7 @@ int pvId; * seq_pvAssign() - Assign/Connect to a channel. * Assign to a zero-lth string ("") disconnects/de-assignes. */ -seq_pvAssign(ssId, pvId, pvName) -SS_ID ssId; -int pvId; -char *pvName; +long seq_pvAssign(SS_ID ssId, long pvId, char *pvName) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -190,7 +195,7 @@ char *pvName; #ifdef DEBUG printf("Assign %s to \"%s\"\n", pDB->pVarName, pvName); -#endif /* DEBUG */ +#endif DEBUG if (pDB->assigned) { /* Disconnect this channel */ status = ca_clear_channel(pDB->chid); @@ -244,9 +249,7 @@ char *pvName; /* * seq_pvMonitor() - Initiate a monitor on a channel. */ -seq_pvMonitor(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvMonitor(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -258,7 +261,7 @@ int pvId; #ifdef DEBUG printf("monitor \"%s\"\n", pDB->dbName); -#endif /* DEBUG */ +#endif DEBUG if (pDB->monitored || !pDB->assigned) return ECA_NORMAL; @@ -289,9 +292,7 @@ int pvId; /* * seq_pvStopMonitor() - Cancel a monitor */ -seq_pvStopMonitor(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvStopMonitor(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -317,8 +318,7 @@ int pvId; /* * seq_pvChannelCount() - returns total number of database channels. */ -seq_pvChannelCount(ssId) -SS_ID ssId; +long seq_pvChannelCount(SS_ID ssId) { SPROG *pSP; /* ptr to state program */ int status; @@ -330,8 +330,7 @@ SS_ID ssId; /* * seq_pvConnectCount() - returns number of database channels connected. */ -seq_pvConnectCount(ssId) -SS_ID ssId; +long seq_pvConnectCount(SS_ID ssId) { SPROG *pSP; /* ptr to state program */ int status; @@ -343,8 +342,7 @@ SS_ID ssId; /* * seq_pvAssignCount() - returns number of database channels assigned. */ -seq_pvAssignCount(ssId) -SS_ID ssId; +long seq_pvAssignCount(SS_ID ssId) { SPROG *pSP; /* ptr to state program */ int status; @@ -356,9 +354,7 @@ SS_ID ssId; /* * seq_pvConnected() - returns TRUE if database channel is connected. */ -seq_pvConnected(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvConnected(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; @@ -372,9 +368,7 @@ int pvId; /* * seq_pvAssigned() - returns TRUE if database channel is assigned. */ -seq_pvAssigned(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvAssigned(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; @@ -389,9 +383,7 @@ int pvId; * seq_pvCount() - returns number elements in an array, which is the lesser of * (1) the array size and (2) the element count returned by channel access. */ -seq_pvCount(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvCount(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -405,9 +397,7 @@ int pvId; /* * seq_pvStatus() - returns channel alarm status. */ -seq_pvStatus(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvStatus(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -421,9 +411,7 @@ int pvId; /* * seq_pvSeverity() - returns channel alarm severity. */ -seq_pvSeverity(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvSeverity(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -437,9 +425,7 @@ int pvId; /* * seq_pvIndex() - returns index of database variable. */ -int seq_pvIndex(ssId, pvId) -SS_ID ssId; -int pvId; +long seq_pvIndex(SS_ID ssId, long pvId) { return pvId; /* index is same as pvId */ } @@ -447,9 +433,7 @@ int pvId; /* * seq_pvTimeStamp() - returns channel time stamp. */ -TS_STAMP seq_pvTimeStamp(ssId, pvId) -SS_ID ssId; -int pvId; +TS_STAMP seq_pvTimeStamp(SS_ID ssId, long pvId) { SPROG *pSP; /* ptr to state program */ CHAN *pDB; /* ptr to channel struct */ @@ -463,9 +447,7 @@ int pvId; * seq_efSet() - Set an event flag, then wake up each state * set that might be waiting on that event flag. */ -VOID seq_efSet(ssId, ev_flag) -SS_ID ssId; -int ev_flag; /* event flag */ +VOID seq_efSet(SS_ID ssId, long ev_flag) { SPROG *pSP; SSCB *pSS; @@ -477,7 +459,7 @@ int ev_flag; /* event flag */ #ifdef DEBUG logMsg("seq_efSet: pSP=0x%x, pSS=0x%x, ev_flag=0x%x\n", pSP, pSS, ev_flag); taskDelay(10); -#endif /* DEBUG */ +#endif DEBUG /* Set this bit (apply resource lock) */ semTake(pSP->caSemId, WAIT_FOREVER); @@ -493,9 +475,8 @@ int ev_flag; /* event flag */ /* * seq_efTest() - Test event flag against outstanding events. */ -int seq_efTest(ssId, ev_flag) -SS_ID ssId; -int ev_flag; /* event flag */ +long seq_efTest(SS_ID ssId, long ev_flag) +/* event flag */ { SPROG *pSP; SSCB *pSS; @@ -507,16 +488,14 @@ int ev_flag; /* event flag */ #ifdef DEBUG logMsg("seq_efTest: ev_flag=%d, event=0x%x, isSet=%d\n", ev_flag, pSP->pEvents[0], isSet); -#endif /* DEBUG */ +#endif DEBUG return isSet; } /* * seq_efClear() - Test event flag against outstanding events, then clear it. */ -int seq_efClear(ssId, ev_flag) -SS_ID ssId; -int ev_flag; /* event flag */ +long seq_efClear(SS_ID ssId, long ev_flag) { SPROG *pSP; SSCB *pSS; @@ -533,9 +512,7 @@ int ev_flag; /* event flag */ /* * seq_efTestAndClear() - Test event flag against outstanding events, then clear it. */ -int seq_efTestAndClear(ssId, ev_flag) -SS_ID ssId; -int ev_flag; /* event flag */ +long seq_efTestAndClear(SS_ID ssId, long ev_flag) { SPROG *pSP; SSCB *pSS; @@ -548,11 +525,9 @@ int ev_flag; /* event flag */ bitClear(pSP->pEvents, ev_flag); return isSet; } - /* - * seq_delay() - test for delay() time-out expired */ -int seq_delay(ssId, delayId) -SS_ID ssId; -int delayId; + +/* seq_delay() - test for delay() time-out expired */ +long seq_delay(SS_ID ssId, long delayId) { SSCB *pSS; ULONG timeElapsed; @@ -573,12 +548,9 @@ int delayId; } /* - * seq_delayInit() - initialize delay time on entering a state. + * seq_delayInit() - initialize delay time (in seconds) on entering a state. */ -VOID seq_delayInit(ssId, delayId, delay) -SS_ID ssId; -int delayId; -float delay; /* delay in seconds */ +VOID seq_delayInit(SS_ID ssId, long delayId, float delay) { SSCB *pSS; int ndelay; @@ -593,12 +565,10 @@ float delay; /* delay in seconds */ pSS->numDelays = ndelay; } /* - * seq_optGet: return the value of an option. + * seq_optGet: return the value of an option (e.g. "a"). * FALSE means "-" and TRUE means "+". */ -BOOL seq_optGet(ssId, opt) -SS_ID ssId; -char *opt; /* one of the snc options as a strign (e.g. "a") */ +BOOL seq_optGet(SS_ID ssId, char *opt) { SPROG *pSP; diff --git a/src/sequencer/seq_mac.c b/src/sequencer/seq_mac.c index e6e21e195..38aa2b4b5 100644 --- a/src/sequencer/seq_mac.c +++ b/src/sequencer/seq_mac.c @@ -33,7 +33,7 @@ LOCAL MACRO *seqMacTblGet(MACRO *, char *); VOID seqMacEval(pInStr, pOutStr, maxChar, pMac) char *pInStr; char *pOutStr; -int maxChar; +long maxChar; MACRO *pMac; { char name[50], *pValue, *pTmp; @@ -119,7 +119,7 @@ char *pName; #ifdef DEBUG logMsg("seqMacValGet: name=%s", pName); -#endif /* DEBUG */ +#endif DEBUG for (i = 0 ; i < MAX_MACROS; i++, pMac++) { if (pMac->pName != NULL) @@ -128,14 +128,14 @@ char *pName; { #ifdef DEBUG logMsg(", value=%s\n", pMac->pValue); -#endif /* DEBUG */ +#endif DEBUG return pMac->pValue; } } } #ifdef DEBUG logMsg(", no value\n"); -#endif /* DEBUG */ +#endif DEBUG return NULL; } /* @@ -144,7 +144,7 @@ char *pName; * Assumes the table may already contain entries (values may be changed). * String for name and value are allocated dynamically from pool. */ -int seqMacParse(pMacStr, pSP) +long seqMacParse(pMacStr, pSP) char *pMacStr; /* macro definition string */ SPROG *pSP; { diff --git a/src/sequencer/seq_main.c b/src/sequencer/seq_main.c index 6fa31674c..3a5ff90a5 100644 --- a/src/sequencer/seq_main.c +++ b/src/sequencer/seq_main.c @@ -44,6 +44,10 @@ 15mar94,ajk Rearranged code that builds program structures. 02may94,ajk Performed initialization when sequencer is evoked, even w/o parameters. +19jul95,ajk Added unsigned types (unsigned char, short, int, long). +20jul95,ajk Added priority specification at run time. +03aug95,ajk Fix problem with +r option: user variable space (pSP->pVar) + was not being allocated. ***************************************************************************/ /*#define DEBUG 1*/ @@ -52,7 +56,7 @@ #ifdef DEBUG #undef LOCAL #define LOCAL -#endif /* DEBUG */ +#endif DEBUG /* ANSI functional prototypes for local routines */ LOCAL SPROG *seqInitTables(struct seqProgram *); @@ -86,13 +90,13 @@ int seqAuxTaskId = 0; * Creates the initial state program task and returns its task id. * Most initialization is performed here. */ -int seq(pSeqProg, macro_def, stack_size) +long seq(pSeqProg, macro_def, stack_size) struct seqProgram *pSeqProg; /* state program info generated by snc */ char *macro_def; /* optional macro def'n string */ -int stack_size; /* optional stack size (bytes) */ +long stack_size; /* optional stack size (bytes) */ { int tid; - extern sequencer(); /* Sequencer task entry point */ + extern long sequencer();/* Sequencer task entry point */ extern sprog_delete(); /* Task delete routine */ extern char *seqVersion; SPROG *pSP; @@ -111,7 +115,7 @@ int stack_size; /* optional stack size (bytes) */ taskDelay(5); /* wait for task to init. ch'l access */ #ifdef DEBUG logMsg("task seqAux spawned, tid=0x%x\n", seqAuxTaskId); -#endif /* DEBUG */ +#endif DEBUG } /* Specify a routine to run at task delete */ @@ -173,8 +177,21 @@ int stack_size; /* optional stack size (bytes) */ #ifdef DEBUG logMsg("Spawing task %s, stack_size=%d\n", ptask_name, stack_size); #endif - tid = taskSpawn(ptask_name, SPAWN_PRIORITY, SPAWN_OPTIONS, - stack_size, sequencer, (int)pSP, stack_size, (int)ptask_name, 0,0,0,0,0,0,0); + /* Specify task priority */ + pSP->taskPriority = SPAWN_PRIORITY; + pValue = seqMacValGet(pSP->pMacros, "priority"); + if (pValue != NULL && strlen(pValue) > 0) + { + sscanf(pValue, "%d", &(pSP->taskPriority)); + } + if (pSP->taskPriority < SPAWN_PRIORITY) + pSP->taskPriority = SPAWN_PRIORITY; + if (pSP->taskPriority > 255) + pSP->taskPriority = 255; + + tid = taskSpawn(ptask_name, pSP->taskPriority, SPAWN_OPTIONS, + stack_size, (FUNCPTR)sequencer, (int)pSP, stack_size, (int)ptask_name, + 0,0,0,0,0,0,0); seq_log(pSP, "Spawning state program \"%s\", task name = \"%s\"\n", pSP->pProgName, ptask_name); @@ -240,11 +257,14 @@ SPROG *pSP; pSP->pProgName = pSeqProg->pProgName; pSP->exitFunc = pSeqProg->exitFunc; pSP->varSize = pSeqProg->varSize; + /* Allocate user variable area if reentrant option (+r) is set */ + if ((pSP->options & OPT_REENT) != 0) + pSP->pVar = (char *)calloc(pSP->varSize, 1); #ifdef DEBUG logMsg("init_sprog: num SS=%d, num Chans=%d, num Events=%d, Prog Name=%s, var Size=%d\n", pSP->numSS, pSP->numChans, pSP->numEvents, pSP->pProgName, pSP->varSize); -#endif /* DEBUG */ +#endif DEBUG /* Create a semaphore for resource locking on CA events */ pSP->caSemId = semBCreate(SEM_Q_FIFO, SEM_FULL); @@ -302,7 +322,7 @@ SPROG *pSP; #ifdef DEBUG logMsg("init_sscb: SS Name=%s, num States=%d, pSS=0x%x\n", pSS->pSSName, pSS->numStates, pSS); -#endif /* DEBUG */ +#endif DEBUG /* Create a binary semaphore for synchronizing events in a SS */ pSS->syncSemId = semBCreate(SEM_Q_FIFO, SEM_FULL); if (pSS->syncSemId == NULL) @@ -311,8 +331,8 @@ SPROG *pSP; return; } - /* Create a binary semaphore for pvGet() synconizing */ - if (!pSP->options & OPT_ASYNC) + /* Create a binary semaphore for synchronous pvGet() (-a) */ + if ((pSP->options & OPT_ASYNC) == 0) { pSS->getSemId = semBCreate(SEM_Q_FIFO, SEM_FULL); @@ -339,13 +359,13 @@ SPROG *pSP; #ifdef DEBUG logMsg("init_sscb: State Name=%s, Event Mask=0x%x\n", pState->pStateName, *pState->pEventMask); -#endif /* DEBUG */ +#endif DEBUG } } #ifdef DEBUG logMsg("init_sscb: numSS=%d\n", pSP->numSS); -#endif /* DEBUG */ +#endif DEBUG return; } @@ -369,7 +389,7 @@ SPROG *pSP; { #ifdef DEBUG logMsg("init_chan: pDB=0x%x\n", pDB); -#endif /* DEBUG */ +#endif DEBUG pDB->sprog = pSP; pDB->dbAsName = pSeqChan->dbAsName; pDB->pVarName = pSeqChan->pVarName; @@ -386,7 +406,7 @@ SPROG *pSP; &pDB->putType, &pDB->size, &pDB->dbOffset); /* Reentrant option: Convert offset to address of the user variable. */ - if (pSP->options & OPT_REENT) + if ((pSP->options & OPT_REENT) != 0) pDB->pVar += (int)pSP->pVar; #ifdef DEBUG logMsg(" Assigned Name=%s, VarName=%s, VarType=%s, count=%d\n", @@ -394,7 +414,7 @@ SPROG *pSP; logMsg(" size=%d, dbOffset=%d\n", pDB->size, pDB->dbOffset); logMsg(" efId=%d, monFlag=%d, eventNum=%d\n", pDB->efId, pDB->monFlag, pDB->eventNum); -#endif /* DEBUG */ +#endif DEBUG } } @@ -436,7 +456,7 @@ SPROG *pSP; #ifdef DEBUG logMsg("seqChanNameEval: \"%s\" evaluated to \"%s\"\n", pDB->dbAsName, pDB->dbName); -#endif /* DEBUG */ +#endif DEBUG } } /* @@ -467,6 +487,18 @@ LOCAL struct typeMap { "long", DBR_LONG, DBR_TIME_LONG, sizeof (long), OFFSET(struct dbr_time_long, value), + "unsigned char", DBR_CHAR, DBR_TIME_CHAR, + sizeof (char), OFFSET(struct dbr_time_char, value), + + "unsigned short", DBR_SHORT, DBR_TIME_SHORT, + sizeof (short), OFFSET(struct dbr_time_short, value), + + "unsigned int", DBR_LONG, DBR_TIME_LONG, + sizeof (long), OFFSET(struct dbr_time_long, value), + + "unsigned long", DBR_LONG, DBR_TIME_LONG, + sizeof (long), OFFSET(struct dbr_time_long, value), + "float", DBR_FLOAT, DBR_TIME_FLOAT, sizeof (float), OFFSET(struct dbr_time_float, value), diff --git a/src/sequencer/seq_prog.c b/src/sequencer/seq_prog.c index 65c74e329..931d20f20 100644 --- a/src/sequencer/seq_prog.c +++ b/src/sequencer/seq_prog.c @@ -40,7 +40,7 @@ typedef struct prog_node * seqFindProg() - find a program in the state program list from task id. */ SPROG *seqFindProg(taskId) -int taskId; +long taskId; { PROG_NODE *pNode; SPROG *pSP; diff --git a/src/sequencer/seq_qry.c b/src/sequencer/seq_qry.c index 7ba098dee..d4d77e158 100644 --- a/src/sequencer/seq_qry.c +++ b/src/sequencer/seq_qry.c @@ -74,6 +74,9 @@ int tid; ((pSP->options & OPT_ASYNC) != 0), ((pSP->options & OPT_DEBUG) != 0), ((pSP->options & OPT_NEWEF) != 0), ((pSP->options & OPT_REENT) != 0), ((pSP->options & OPT_CONN) != 0) ); + if ((pSP->options & OPT_REENT) != 0) + printf(" user variables: address=%d=0x%x, length=%d=0x%x bytes\n", + pSP->pVar, pSP->pVar, pSP->varSize, pSP->varSize); printf(" log file fd=%d\n", pSP->logFd); status = ioctl(pSP->logFd, FIOGETNAME, (int)file_name); if (status != ERROR) @@ -111,7 +114,7 @@ int tid; printf(" - expired"); printf("\n"); } -#endif /* DEBUG */ +#endif DEBUG printf("\n"); } diff --git a/src/sequencer/seq_task.c b/src/sequencer/seq_task.c index d3cdde2ac..37beff042 100644 --- a/src/sequencer/seq_task.c +++ b/src/sequencer/seq_task.c @@ -26,6 +26,7 @@ 24nov93,ajk Changed implementation of event bits to support unlimited channels 20may94,ajk Changed sprog_delete() to spawn a separate cleanup task. 19oct95,ajk/rmw Fixed bug which kept events from being cleared in old eventflag mode +20jul95,ajk Add user-specified task priority to taskSpwan(). ***************************************************************************/ /*#define DEBUG*/ #define ANSI @@ -44,10 +45,10 @@ LOCAL long seq_getTimeout(SSCB *); /* * sequencer() - Sequencer main task entry point. - * */ -sequencer(pSP, stack_size, pTaskName) + */ +long sequencer(pSP, stack_size, pTaskName) SPROG *pSP; /* ptr to original (global) state program table */ -int stack_size; /* stack size */ +long stack_size; /* stack size */ char *pTaskName; /* Parent task name */ { SSCB *pSS; @@ -83,7 +84,7 @@ char *pTaskName; /* Parent task name */ /* Spawn the task */ task_id = taskSpawn( task_name, /* task name */ - SPAWN_PRIORITY+pSS->taskPriority, /* priority */ + pSP->taskPriority, /* priority */ SPAWN_OPTIONS, /* task options */ stack_size, /* stack size */ (FUNCPTR)ss_entry, /* entry point */ @@ -115,7 +116,7 @@ SSCB *pSS; ss_task_init(pSP, pSS); /* If "+c" option, wait for all channels to connect */ - if (pSP->options & OPT_CONN) + if ((pSP->options & OPT_CONN) != 0) seq_waitConnect(pSP, pSS); /* Initilaize state set to enter the first state */ @@ -323,6 +324,7 @@ int tid; /* task being deleted */ SPROG *pSP; extern int seq_cleanup(); SEM_ID cleanupSem; + int status; pSP = seqFindProg(tid); if (pSP == NULL) @@ -332,50 +334,59 @@ int tid; /* task being deleted */ cleanupSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY); /* Spawn the cleanup task */ - taskSpawn("seqCleanup", SPAWN_PRIORITY-1, VX_FP_TASK, 2000, seq_cleanup, + taskSpawn("tSeqCleanup", SPAWN_PRIORITY-1, VX_FP_TASK, 8000, seq_cleanup, tid, (int)pSP, (int)cleanupSem, 0,0,0,0,0,0,0); /* Wait for cleanup task completion */ - semTake(cleanupSem, WAIT_FOREVER); + for (;;) + { + status = semTake(cleanupSem, 600); + if (status == OK) + break; + logMsg("sprog_delete waiting for seq_cleanup\n"); + } semDelete(cleanupSem); return 0; } /* Cleanup task */ +/*#define DEBUG_CLEANUP*/ + seq_cleanup(tid, pSP, cleanupSem) -int tid; +int tid; /* tid of 1-st SS to be deleted */ SPROG *pSP; SEM_ID cleanupSem; /* indicate cleanup is finished */ { - int nss, tid_ss; + int nss; SSCB *pSS; + extern int ca_static; /* CA static variable */ - logMsg("Delete %s: pSP=%d=0x%x, tid=%d\n", - pSP->pProgName, pSP, pSP, tid); +#ifdef DEBUG_CLEANUP + logMsg("Delete %s: pSP=%d=0x%x, tid=%d\n", pSP->pProgName, pSP, pSP, tid); +#endif /*DEBUG_CLEANUP*/ /* Wait for log semaphore (in case a task is doing a write) */ semTake(pSP->logSemId, 600); /* Remove tasks' watchdog & suspend all state set tasks except self */ -#ifdef DEBUG +#ifdef DEBUG_CLEANUP logMsg(" Suspending state set tasks:\n"); -#endif /* DEBUG */ +#endif /*DEBUG_CLEANUP*/ pSS = pSP->pSS; for (nss = 0; nss < pSP->numSS; nss++, pSS++) { - tid_ss = pSS->taskId; - + if (pSS->taskId == 0) + continue; +#ifdef DEBUG_CLEANUP + logMsg(" tid=%d\n", pSS->taskId); +#endif /*DEBUG_CLEANUP*/ /* Remove the task from EPICS watchdog */ - taskwdRemove(tid_ss); + taskwdRemove(pSS->taskId); - if (tid_ss != taskIdSelf() ) - { -#ifdef DEBUG - logMsg(" suspend task: tid=%d\n", tid_ss); -#endif /* DEBUG */ - taskSuspend(tid_ss); - } + /* Suspend the task */ + if (pSS->taskId != tid) + taskSuspend(pSS->taskId); } /* Give back log semaphore */ @@ -384,27 +395,37 @@ SEM_ID cleanupSem; /* indicate cleanup is finished */ /* Call user exit routine (only if task has run) */ if (pSP->pSS->taskId != 0) { -#ifdef DEBUG +#ifdef DEBUG_CLEANUP logMsg(" Call exit function\n"); -#endif /* DEBUG */ +#endif /*DEBUG_CLEANUP*/ pSP->exitFunc( (SS_ID)pSP->pSS, pSP->pVar); } /* Disconnect all channels */ +#ifdef DEBUG_CLEANUP + logMsg(" Disconnect all channels\n"); +#endif /*DEBUG_CLEANUP*/ + seq_disconnect(pSP); /* Cancel the CA context for each state set task */ for (nss = 0, pSS = pSP->pSS; nss < pSP->numSS; nss++, pSS++) { - ca_import_cancel(pSS->taskId); + if (pSS->taskId == 0) + continue; +#ifdef DEBUG_CLEANUP + logMsg(" ca_import_cancel(0x%x)\n", pSS->taskId); +#endif /*DEBUG_CLEANUP*/ + /*ca_import_cancel(pSS->taskId);*/ + taskVarDelete(pSS->taskId, &ca_static); } /* Close the log file */ - if (pSP->logFd > 0 && pSP->logFd != ioGlobalStdGet(1)) + if ( (pSP->logFd > 0) && (pSP->logFd != ioGlobalStdGet(1)) ) { -#ifdef DEBUG +#ifdef DEBUG_CLEANUP logMsg("Closing log fd=%d\n", pSP->logFd); -#endif /* DEBUG */ +#endif /*DEBUG_CLEANUP*/ close(pSP->logFd); pSP->logFd = ioGlobalStdGet(1); } @@ -416,13 +437,12 @@ SEM_ID cleanupSem; /* indicate cleanup is finished */ pSS = pSP->pSS; for (nss = 0; nss < pSP->numSS; nss++, pSS++) { - tid_ss = pSS->taskId; - if ( (tid != tid_ss) && (tid_ss != 0) ) + if ( (pSS->taskId != tid) && (pSS->taskId != 0) ) { -#ifdef DEBUG - logMsg(" delete ss task: tid=%d\n", tid_ss); -#endif /* DEBUG */ - taskDelete(tid_ss); +#ifdef DEBUG_CLEANUP + logMsg(" delete ss task: tid=%d\n", pSS->taskId); +#endif /*DEBUG_CLEANUP*/ + taskDelete(pSS->taskId); } if (pSS->syncSemId != 0) diff --git a/src/sequencer/snc.y b/src/sequencer/snc.y index 818fa1668..e2c7086d9 100644 --- a/src/sequencer/snc.y +++ b/src/sequencer/snc.y @@ -12,6 +12,7 @@ 02may93,ajk Removed "parameter" definition for functions, and added "%prec" qualifications to some "expr" definitions. 31may94,ajk Changed method for handling global C code. +20jul95,ajk Added "unsigned" types (see UNSIGNED token). ***************************************************************************/ /* SNC - State Notation Compiler. * The general structure of a state program is: @@ -40,7 +41,7 @@ #ifndef TRUE #define TRUE 1 #define FALSE 0 -#endif /* TRUE */ +#endif TRUE extern int line_num; /* input file line no. */ %} @@ -62,7 +63,8 @@ extern int line_num; /* input file line no. */ %token BAD_CHAR L_BRACKET R_BRACKET %token COLON SEMI_COLON EQUAL %token L_PAREN R_PAREN PERIOD POINTER COMMA OR AND -%token MONITOR ASSIGN TO WHEN CHAR SHORT INT LONG FLOAT DOUBLE STRING_DECL +%token MONITOR ASSIGN TO WHEN +%token UNSIGNED CHAR SHORT INT LONG FLOAT DOUBLE STRING_DECL %token EVFLAG SYNC %token ASTERISK AMPERSAND %token AUTO_INCR AUTO_DECR @@ -177,6 +179,10 @@ type /* types for variables defined in SNL */ | SHORT { $$ = V_SHORT; } | INT { $$ = V_INT; } | LONG { $$ = V_LONG; } +| UNSIGNED CHAR { $$ = V_UCHAR; } +| UNSIGNED SHORT { $$ = V_USHORT; } +| UNSIGNED INT { $$ = V_UINT; } +| UNSIGNED LONG { $$ = V_ULONG; } | FLOAT { $$ = V_FLOAT; } | DOUBLE { $$ = V_DOUBLE; } | STRING_DECL { $$ = V_STRING; } diff --git a/src/sequencer/snc_lex.l b/src/sequencer/snc_lex.l index 10886d14f..3e15ddfca 100644 --- a/src/sequencer/snc_lex.l +++ b/src/sequencer/snc_lex.l @@ -20,6 +20,7 @@ 31may94,ajk Changed handling of escaped C code. 17feb95,ajk Removed includes "parse.h" & "snc.h", because this module now gets included in snc.y. +20jul95,ajk Added unsigned types. ***************************************************************************/ /* Lexical analyzer for State Notation Compiler (snc). * @@ -142,6 +143,7 @@ HEX 0x([0-9a-fA-F])+ "when" RETURN(WHEN); "monitor" RETURN(MONITOR); "assign" RETURN(ASSIGN); +"unsigned" RETURN(UNSIGNED); "char" RETURN(CHAR); "short" RETURN(SHORT); "int" RETURN(INT);