changed names of caMonitor stuff to recWaitCa stuff. Also added
individual flags for IO_INTR processing of inputs
This commit is contained in:
@@ -39,11 +39,13 @@
|
||||
* .06 08-19-94 nda added Output data option of VAL or DOL
|
||||
* .07 09-14-94 nda corrected bug that caused SCAN_DISABLE to lock up the record forever
|
||||
* .08 02-01-95 nda added VERS and ODLY (output execution delay)
|
||||
* .09 02-15-95 nda addedd INxP to determine which inputs should cause the record
|
||||
* to process when in I/O INTR mode.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#define VERSION 1.08
|
||||
#define VERSION 1.09
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +76,7 @@
|
||||
|
||||
#include <choiceWait.h>
|
||||
#include <waitRecord.h>
|
||||
#include <caMonitor.h>
|
||||
#include <recWaitCa.h>
|
||||
|
||||
|
||||
/* Create RSET - Record Support Entry Table*/
|
||||
@@ -162,7 +164,7 @@ struct cbStruct {
|
||||
struct waitRecord *pwait; /* pointer to wait record which needs work done */
|
||||
WDOG_ID wd_id; /* Watchdog used for delays */
|
||||
IOSCANPVT ioscanpvt; /* used for IO_EVENT scanning */
|
||||
CAMONITOR inpMonitor[12]; /* required structures for each input variable */
|
||||
RECWAITCA inpMonitor[12]; /* required structures for each input variable */
|
||||
int procPending; /* flag to indicate record processing is pending */
|
||||
};
|
||||
|
||||
@@ -185,9 +187,10 @@ static long init_record(pwait,pass)
|
||||
long status = 0;
|
||||
int i;
|
||||
|
||||
char *ppvn[PVN_SIZE];
|
||||
struct dbAddr **ppdbAddr; /* ptr to a ptr to dbAddr */
|
||||
long *paddrValid;
|
||||
char *ppvn[PVN_SIZE];
|
||||
struct dbAddr **ppdbAddr; /* ptr to a ptr to dbAddr */
|
||||
long *paddrValid;
|
||||
unsigned short *piointInc; /* include for IO_INT ? */
|
||||
|
||||
char rpbuf[184];
|
||||
short error_number;
|
||||
@@ -258,12 +261,14 @@ static long init_record(pwait,pass)
|
||||
/* MON_ALWAYS if(pwait->scan == SCAN_IO_EVENT) { */
|
||||
if(1) {
|
||||
paddrValid = &pwait->inav;
|
||||
piointInc = &pwait->inap;
|
||||
|
||||
for(i=0;i<ARG_MAX; i++, paddrValid++) {
|
||||
if(!(*paddrValid)) {
|
||||
if(waitRecDebug) printf("adding monitor\n");
|
||||
status = caMonitorAdd(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"caMonitorAdd error");
|
||||
for(i=0;i<ARG_MAX; i++, paddrValid++, piointInc++) {
|
||||
/* if valid PV AND input include flag is true ... */
|
||||
if(!(*paddrValid) && (*piointInc)) {
|
||||
if(waitRecDebug) printf("adding monitor on input %d\n", i);
|
||||
status = recWaitCaAdd(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"recWaitCaAdd error");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -372,43 +377,43 @@ static long special(paddr,after)
|
||||
char *ppvn[PVN_SIZE];
|
||||
struct dbAddr **ppdbAddr; /* ptr to a ptr to dbAddr */
|
||||
long *paddrValid;
|
||||
unsigned short *piointInc; /* include for IO_INT ? */
|
||||
int i;
|
||||
long status;
|
||||
long odbv =0;
|
||||
short error_number;
|
||||
char rpbuf[184];
|
||||
|
||||
if(waitRecDebug) printf("entering special \n");
|
||||
if(!after) { /* this is called before ca changes the field */
|
||||
switch(special_type) {
|
||||
case(SPC_SCAN): /* about to change SCAN mechanism ... */
|
||||
if(pwait->scan == SCAN_IO_EVENT) {
|
||||
/* Leaving IO_EVENT, delete monitors */
|
||||
paddrValid = &pwait->inav;
|
||||
for(i=0;i<ARG_MAX; i++, paddrValid++) {
|
||||
if(!(*paddrValid)) {
|
||||
if(waitRecDebug) printf("deleting monitor\n");
|
||||
status = caMonitorDelete(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"caMonitorDelete error");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(waitRecDebug) printf("entering special %d \n",after);
|
||||
|
||||
case(SPC_MOD): /* check if changing any PV names while monitored */
|
||||
/* MON_ALWAYS if(pwait->scan == SCAN_IO_EVENT) { */
|
||||
if(1) {
|
||||
*ppvn = &pwait->inan[0];
|
||||
paddrValid = &pwait->inav;
|
||||
for(i=0;i<ARG_MAX; i++, *ppvn += PVN_SIZE, paddrValid++) {
|
||||
if((paddr->pfield==*ppvn) && !(*paddrValid)) {
|
||||
if(waitRecDebug) printf("deleting monitor\n");
|
||||
status = caMonitorDelete(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"caMonitorDelete error");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
if(!after) { /* this is called before ca changes the field */
|
||||
/* MON_ALWAYS This case doesn't currently happen */
|
||||
if((special_type == SPC_SCAN) && (pwait->scan == SCAN_IO_EVENT)) {
|
||||
/* Leaving IO_EVENT, delete monitors */
|
||||
paddrValid = &pwait->inav;
|
||||
for(i=0;i<ARG_MAX; i++, paddrValid++) {
|
||||
if(!(*paddrValid)) {
|
||||
if(waitRecDebug) printf("deleting monitor\n");
|
||||
status = recWaitCaDelete(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"recWaitCaDelete error");
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check if changing any Input PV names/flags while monitored */
|
||||
if((special_type >= REC_WAIT_A) && (special_type <= REC_WAIT_L)) {
|
||||
/* MON_ALWAYS if(pwait->scan == SCAN_IO_EVENT) */
|
||||
/* About to change a PV or flag, delete that particular monitor */
|
||||
i = special_type - REC_WAIT_A; /* index of input */
|
||||
paddrValid = &pwait->inav + i; /* pointer arithmetic */
|
||||
piointInc = &pwait->inap + i; /* pointer arithmetic */
|
||||
/* If PV name is valid and the INxP flag is true, ... */
|
||||
if(!(*paddrValid) && (*piointInc)) {
|
||||
if(waitRecDebug) printf("deleting monitor on input %d\n",i);
|
||||
status = recWaitCaDelete(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"recWaitCaDelete error");
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -416,38 +421,58 @@ static long special(paddr,after)
|
||||
/* this is executed after ca changed the field */
|
||||
switch(special_type) {
|
||||
case(SPC_SCAN): /* Changed SCAN mechanism, set monitors on input links */
|
||||
/* MON_ALWAYS This case currently doesn't happen */
|
||||
if(pwait->scan == SCAN_IO_EVENT) {
|
||||
paddrValid = &pwait->inav;
|
||||
for(i=0;i<ARG_MAX; i++, paddrValid++) {
|
||||
if(!(*paddrValid)) {
|
||||
if(waitRecDebug) printf("adding monitor\n");
|
||||
status = caMonitorAdd(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"caMonitorAdd error");
|
||||
if(waitRecDebug) printf("adding monitor on input %d\n", i);
|
||||
status = recWaitCaAdd(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"recWaitCaAdd error");
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
case(SPC_MOD): /* check if changing any PV names */
|
||||
*ppvn = &pwait->inan[0];
|
||||
ppdbAddr = (struct dbAddr **)&pwait->inaa;
|
||||
paddrValid = &pwait->inav;
|
||||
break;
|
||||
|
||||
case(REC_WAIT_A): /* check if changing any input PV's or flags */
|
||||
case(REC_WAIT_B):
|
||||
case(REC_WAIT_C):
|
||||
case(REC_WAIT_D):
|
||||
case(REC_WAIT_E):
|
||||
case(REC_WAIT_F):
|
||||
case(REC_WAIT_G):
|
||||
case(REC_WAIT_H):
|
||||
case(REC_WAIT_I):
|
||||
case(REC_WAIT_J):
|
||||
case(REC_WAIT_K):
|
||||
case(REC_WAIT_L):
|
||||
|
||||
i = special_type - REC_WAIT_A; /* index of input */
|
||||
paddrValid = &pwait->inav + i; /* pointer arithmetic */
|
||||
ppdbAddr = (struct dbAddr **)&pwait->inaa + i; /* pointer arithmetic */
|
||||
*ppvn = &pwait->inan[0] + (i*PVN_SIZE);
|
||||
|
||||
for(i=0;i<ARG_MAX; i++, *ppvn += PVN_SIZE, ppdbAddr++, paddrValid++) {
|
||||
if(paddr->pfield==*ppvn) {
|
||||
odbv = *paddrValid;
|
||||
*paddrValid = dbNameToAddr(*ppvn, *ppdbAddr);
|
||||
if (odbv != *paddrValid) {
|
||||
db_post_events(pwait,paddrValid,DBE_VALUE);
|
||||
}
|
||||
/* MON_ALWAYS if((pwait->scan == SCAN_IO_EVENT) && !(*paddrValid)) { */
|
||||
if((1) && !(*paddrValid)) {
|
||||
if(waitRecDebug) printf("adding monitor\n");
|
||||
status = caMonitorAdd(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"caMonitorAdd error");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
/* If the PV Name changing, do dbNameToAddr */
|
||||
if(paddr->pfield==*ppvn) {
|
||||
odbv = *paddrValid;
|
||||
*paddrValid = dbNameToAddr(*ppvn, *ppdbAddr);
|
||||
if (odbv != *paddrValid) {
|
||||
db_post_events(pwait,paddrValid,DBE_VALUE);
|
||||
}
|
||||
}
|
||||
/* MON_ALWAYS: Should only do if SCAN_IO_EVENT), but can't now */
|
||||
/* If the INxP flag is set, add a monitor */
|
||||
piointInc = &pwait->inap + i; /* pointer arithmetic */
|
||||
if(!(*paddrValid) && (*piointInc)) {
|
||||
if(waitRecDebug) printf("adding monitor on input %d\n", i);
|
||||
status = recWaitCaAdd(&(((struct cbStruct *)pwait->cbst)->inpMonitor[i]));
|
||||
if(status) errMessage(status,"recWaitCaAdd error");
|
||||
}
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case(SPC_MOD): /* check if changing any other SPC_MOD fields */
|
||||
if(paddr->pfield==pwait->outn) { /* this is the output link */
|
||||
odbv = pwait->outv;
|
||||
pwait->outv = dbNameToAddr(pwait->outn,(struct dbAddr *)pwait->outa);
|
||||
@@ -467,6 +492,7 @@ static long special(paddr,after)
|
||||
}
|
||||
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case(SPC_CALC):
|
||||
pwait->clcv=postfix(pwait->calc,rpbuf,&error_number);
|
||||
@@ -481,6 +507,7 @@ static long special(paddr,after)
|
||||
db_post_events(pwait,pwait->calc,DBE_VALUE);
|
||||
db_post_events(pwait,pwait->clcv,DBE_VALUE);
|
||||
return(0);
|
||||
break;
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"wait: special");
|
||||
return(S_db_badChoice);
|
||||
@@ -725,7 +752,7 @@ static double oldDold;
|
||||
|
||||
|
||||
|
||||
static void inputChanged(struct caMonitor *pcamonitor)
|
||||
static void inputChanged(struct recWaitCa *pcamonitor)
|
||||
{
|
||||
|
||||
struct waitRecord *pwait = (struct waitRecord *)pcamonitor->userPvt;
|
||||
|
||||
154
src/rec/recWaitCa.c
Normal file
154
src/rec/recWaitCa.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <rngLib.h>
|
||||
#include <ellLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <dbDefs.h>
|
||||
#include <taskwd.h>
|
||||
#include <fast_lock.h>
|
||||
#include <cadef.h>
|
||||
#include <caerr.h>
|
||||
#include <caeventmask.h>
|
||||
#include <calink.h>
|
||||
#include <task_params.h>
|
||||
#include <freeList.h>
|
||||
#include <recWaitCa.h>
|
||||
|
||||
extern int interruptAccept;
|
||||
|
||||
#define QUEUE_SIZE 256
|
||||
LOCAL int taskid=0;
|
||||
LOCAL ELLLIST capvtList;
|
||||
LOCAL RING_ID ringQ;;
|
||||
LOCAL FAST_LOCK lock;
|
||||
LOCAL void *freeListPvt;
|
||||
|
||||
typedef enum {cmdNone,cmdAdd,cmdRemove} COMMAND;
|
||||
|
||||
typedef struct {
|
||||
ELLNODE node;
|
||||
RECWAITCA *pcamonitor;
|
||||
chid chid;
|
||||
evid evid;
|
||||
COMMAND cmd;
|
||||
struct dbr_sts_double rtndata; /*Not currently used */
|
||||
} CAPVT;
|
||||
|
||||
void recWaitCaTask(void);
|
||||
|
||||
LOCAL void eventCallback(struct event_handler_args eha)
|
||||
{
|
||||
struct dbr_sts_double *pdata = eha.dbr;
|
||||
CAPVT *pcapvt;
|
||||
RECWAITCA *pcamonitor;
|
||||
|
||||
pcapvt = (CAPVT *)eha.usr;
|
||||
pcamonitor = pcapvt->pcamonitor;
|
||||
(pcamonitor->callback)(pcamonitor);
|
||||
}
|
||||
|
||||
LOCAL void recWaitCaStart(void)
|
||||
{
|
||||
FASTLOCKINIT(&lock);
|
||||
freeListInitPvt(&freeListPvt,sizeof(CAPVT),1);
|
||||
if((ringQ = rngCreate(sizeof(void *) * QUEUE_SIZE)) == NULL) {
|
||||
errMessage(0,"recWaitCaStart failed");
|
||||
exit(1);
|
||||
}
|
||||
ellInit(&capvtList);
|
||||
taskid = taskSpawn("recWaitCaTask",CA_CLIENT_PRI-1,VX_FP_TASK,
|
||||
CA_CLIENT_STACK,(FUNCPTR)recWaitCaTask,0,0,0,0,0,0,0,0,0,0);
|
||||
if(taskid==ERROR) {
|
||||
errMessage(0,"recWaitCaStart: taskSpawn Failure\n");
|
||||
}
|
||||
}
|
||||
|
||||
long recWaitCaAdd(RECWAITCA *pcamonitor)
|
||||
{
|
||||
CAPVT *pcapvt;
|
||||
|
||||
if(!taskid) recWaitCaStart();
|
||||
FASTLOCK(&lock);
|
||||
pcapvt = freeListCalloc(freeListPvt);
|
||||
pcamonitor->recWaitCaPvt = pcapvt;
|
||||
pcapvt->pcamonitor = pcamonitor;
|
||||
pcapvt->cmd = cmdAdd;
|
||||
if(rngBufPut(ringQ,(void *)&pcapvt,sizeof(pcapvt))
|
||||
!=sizeof(pcamonitor)) errMessage(0,"recWaitCaAdd: rngBufPut error");
|
||||
ellAdd(&capvtList,(void *)pcapvt);
|
||||
FASTUNLOCK(&lock);
|
||||
}
|
||||
|
||||
long recWaitCaDelete(RECWAITCA *pcamonitor)
|
||||
{
|
||||
CAPVT *pcapvt = pcamonitor->recWaitCaPvt;
|
||||
|
||||
FASTLOCK(&lock);
|
||||
pcapvt->cmd = cmdRemove;
|
||||
if(rngBufPut(ringQ,(void *)&pcapvt,sizeof(pcapvt))
|
||||
!=sizeof(pcamonitor)) errMessage(0,"recWaitCaDelete: rngBufPut error");
|
||||
FASTUNLOCK(&lock);
|
||||
}
|
||||
|
||||
/*LOCAL */
|
||||
void recWaitCaTask(void)
|
||||
{
|
||||
CAPVT *pcapvt;
|
||||
RECWAITCA *pcamonitor;
|
||||
int status;
|
||||
|
||||
taskwdInsert(taskIdSelf(),NULL,NULL);
|
||||
SEVCHK(ca_task_initialize(),"ca_task_initialize");
|
||||
while(TRUE) {
|
||||
while (rngNBytes(ringQ)>=sizeof(pcapvt) && interruptAccept){
|
||||
if(rngBufGet(ringQ,(void *)&pcapvt,sizeof(pcapvt))
|
||||
!=sizeof(pcapvt)) {
|
||||
errMessage(0,"recWaitCaTask: rngBufGet error");
|
||||
continue;
|
||||
}
|
||||
FASTLOCK(&lock);
|
||||
pcamonitor = pcapvt->pcamonitor;
|
||||
if(pcapvt->cmd==cmdAdd) {
|
||||
SEVCHK(ca_build_and_connect(pcamonitor->channame,TYPENOTCONN,0,
|
||||
&pcapvt->chid,0,NULL,pcapvt),
|
||||
"ca_build_and_connect");
|
||||
SEVCHK(ca_add_event(DBR_STS_DOUBLE,pcapvt->chid,
|
||||
eventCallback,pcapvt,&pcapvt->evid),
|
||||
"ca_add_event");
|
||||
} else {/*must be cmdRemove*/
|
||||
SEVCHK(ca_clear_channel(pcapvt->chid),"ca_clear_channel");
|
||||
pcapvt->cmd=cmdNone;
|
||||
ellDelete(&capvtList,(void *)pcapvt);
|
||||
freeListFree(freeListPvt,pcapvt);
|
||||
}
|
||||
pcapvt->cmd=cmdNone;
|
||||
FASTUNLOCK(&lock);
|
||||
}
|
||||
status = ca_pend_event(.1);
|
||||
if(status!=ECA_NORMAL && status!=ECA_TIMEOUT)
|
||||
SEVCHK(status,"ca_pend_event");
|
||||
}
|
||||
}
|
||||
|
||||
static void myCallback(struct recWaitCa *pcamonitor)
|
||||
{
|
||||
printf("myCallback: %s\n",pcamonitor->channame);
|
||||
}
|
||||
|
||||
int testCaMonitor(char *name)
|
||||
{
|
||||
RECWAITCA *pcamonitor;
|
||||
long status;
|
||||
|
||||
pcamonitor = calloc(1,sizeof(RECWAITCA));
|
||||
pcamonitor->channame = calloc(1,strlen(name)+1);
|
||||
pcamonitor->callback = myCallback;
|
||||
strcpy(pcamonitor->channame,name);
|
||||
status = recWaitCaAdd(pcamonitor);
|
||||
if(status) errMessage(status,"testCaMonitor error");
|
||||
return(0);
|
||||
}
|
||||
9
src/rec/recWaitCa.h
Normal file
9
src/rec/recWaitCa.h
Normal file
@@ -0,0 +1,9 @@
|
||||
typedef struct recWaitCa{
|
||||
char *channame;
|
||||
void (*callback)(struct recWaitCa *pcamonitor);
|
||||
void *userPvt;
|
||||
void *recWaitCaPvt;
|
||||
} RECWAITCA;
|
||||
|
||||
long recWaitCaAdd(RECWAITCA *pcamonitor);
|
||||
long recWaitCaDelete(RECWAITCA *pcamonitor);
|
||||
Reference in New Issue
Block a user