From adffe02a2dfcb5bd2b578e9f1c9b0f2e854b08cb Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 30 Aug 1995 21:17:46 +0000 Subject: [PATCH] Still new --- src/rec/Makefile.Vx | 2 + src/rec/recDynLink.c | 467 +++++++++++++++++++------------------------ src/rec/recDynLink.h | 19 +- 3 files changed, 217 insertions(+), 271 deletions(-) diff --git a/src/rec/Makefile.Vx b/src/rec/Makefile.Vx index 7a2bba73b..678f24274 100644 --- a/src/rec/Makefile.Vx +++ b/src/rec/Makefile.Vx @@ -46,6 +46,7 @@ SRCS.c += ../recTimer.c SRCS.c += ../recWait.c SRCS.c += ../recWaitCa.c SRCS.c += ../recDynLink.c +SRCS.c += ../recDynLinkTest.c SRCS.c += ../recWaveform.c # LIBOBJS += recAai.o @@ -90,6 +91,7 @@ LIBOBJS += recTimer.o LIBOBJS += recWait.o LIBOBJS += recWaitCa.o LIBOBJS += recDynLink.o +LIBOBJS += recDynLinkTest.o LIBOBJS += recWaveform.o LIBNAME = recSup diff --git a/src/rec/recDynLink.c b/src/rec/recDynLink.c index 32c396c9e..eafbc052e 100644 --- a/src/rec/recDynLink.c +++ b/src/rec/recDynLink.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -58,12 +59,15 @@ extern int interruptAccept; int recDynLinkQsize = 256; -LOCAL int taskid=0; -LOCAL RING_ID ringQ;; -LOCAL FAST_LOCK lock; +LOCAL int inpTaskId=0; +LOCAL int outTaskId=0; +LOCAL RING_ID inpRingQ;; +LOCAL RING_ID outRingQ;; LOCAL SEM_ID wakeUpSem; -typedef enum{cmdSearch,cmdClear,cmdAddInput,cmdPut} cmdType; +typedef enum{cmdSearch,cmdClear,cmdPut} cmdType; +typedef enum{ioInput,ioOutput}ioType; +typedef enum{stateStarting,stateSearching,stateGetting,stateConnected}stateType; typedef struct dynLinkPvt{ FAST_LOCK lock; @@ -78,76 +82,126 @@ typedef struct dynLinkPvt{ void *pbuffer; size_t nRequest; short dbrType; - short getCompleted; double graphicLow,graphHigh; double controlLow,controlHigh; char units[MAX_UNITS_SIZE]; short precision; + ioType io; + stateType state; + short scalar; } dynLinkPvt; +/*For cmdClear data is chid. For all other commands precDynLink*/ typedef struct { - recDynLink *precDynLink; + union { + recDynLink *precDynLink; + dynLinkPvt *pdynLinkPvt; + }data; cmdType cmd; }ringBufCmd; -LOCAL void recDynLinkStart(void); +LOCAL void recDynLinkStartInput(void); +LOCAL void recDynLinkStartOutput(void); LOCAL void connectCallback(struct connection_handler_args cha); LOCAL void getCallback(struct event_handler_args eha); LOCAL void monitorCallback(struct event_handler_args eha); -LOCAL void recDynLinkTask(void); +LOCAL void recDynLinkInp(void); +LOCAL void recDynLinkOut(void); -long recDynLinkSearch(recDynLink *precDynLink,char *pvname, - recDynCallback searchCallback,int dbOnly) +long recDynLinkAddInput(recDynLink *precDynLink,char *pvname, + short dbrType,int options, + recDynCallback searchCallback,recDynCallback monitorCallback) { dynLinkPvt *pdynLinkPvt; struct db_addr dbaddr; ringBufCmd cmd; - if(dbOnly && db_name_to_addr(pvname,&dbaddr)) return(-1); - if(!taskid) recDynLinkStart(); - FASTLOCK(&lock); + if(options&rdlDBONLY && db_name_to_addr(pvname,&dbaddr))return(-1); + if(!inpTaskId) recDynLinkStartInput(); pdynLinkPvt = precDynLink->pdynLinkPvt; if(!pdynLinkPvt) { pdynLinkPvt = (dynLinkPvt *)calloc(1,sizeof(dynLinkPvt)); if(!pdynLinkPvt) { - printf("recDynLinkSearch can't allocate storage"); + printf("recDynLinkAddInput can't allocate storage"); taskSuspend(0); } FASTLOCKINIT(&pdynLinkPvt->lock); precDynLink->pdynLinkPvt = pdynLinkPvt; } pdynLinkPvt->pvname = pvname; + pdynLinkPvt->dbrType = dbrType; pdynLinkPvt->searchCallback = searchCallback; - cmd.precDynLink = precDynLink; + pdynLinkPvt->monitorCallback = monitorCallback; + pdynLinkPvt->io = ioInput; + pdynLinkPvt->scalar = (options&rdlSCALAR) ? TRUE : FALSE; + pdynLinkPvt->state = stateStarting; + cmd.data.precDynLink = precDynLink; cmd.cmd = cmdSearch; - if(rngBufPut(ringQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) - errMessage(0,"recDynLinkSearch: rngBufPut error"); - semGive(wakeUpSem); - FASTUNLOCK(&lock); + if(rngBufPut(inpRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) + errMessage(0,"recDynLinkAddInput: rngBufPut error"); return(0); } + +long recDynLinkAddOutput(recDynLink *precDynLink,char *pvname, + short dbrType,int options, + recDynCallback searchCallback) +{ + dynLinkPvt *pdynLinkPvt; + struct db_addr dbaddr; + ringBufCmd cmd; + + if(options&rdlDBONLY && db_name_to_addr(pvname,&dbaddr))return(-1); + if(!outTaskId) recDynLinkStartOutput(); + pdynLinkPvt = precDynLink->pdynLinkPvt; + if(!pdynLinkPvt) { + pdynLinkPvt = (dynLinkPvt *)calloc(1,sizeof(dynLinkPvt)); + if(!pdynLinkPvt) { + printf("recDynLinkAddInput can't allocate storage"); + taskSuspend(0); + } + FASTLOCKINIT(&pdynLinkPvt->lock); + precDynLink->pdynLinkPvt = pdynLinkPvt; + } + pdynLinkPvt->pvname = pvname; + pdynLinkPvt->dbrType = dbrType; + pdynLinkPvt->searchCallback = searchCallback; + pdynLinkPvt->io = ioOutput; + pdynLinkPvt->scalar = (options&rdlSCALAR) ? TRUE : FALSE; + pdynLinkPvt->state = stateStarting; + cmd.data.precDynLink = precDynLink; + cmd.cmd = cmdSearch; + if(rngBufPut(outRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) + errMessage(0,"recDynLinkAddInput: rngBufPut error"); + semGive(wakeUpSem); + return(0); +} + long recDynLinkClear(recDynLink *precDynLink) { dynLinkPvt *pdynLinkPvt; ringBufCmd cmd; - FASTLOCK(&lock); pdynLinkPvt = precDynLink->pdynLinkPvt; if(!pdynLinkPvt) { printf("recDynLinkClear. recDynLinkSearch was never called\n"); taskSuspend(0); } - cmd.precDynLink = precDynLink; + if(pdynLinkPvt->chid) ca_puser(pdynLinkPvt->chid) = NULL; + cmd.data.pdynLinkPvt = pdynLinkPvt; cmd.cmd = cmdClear; - if(rngBufPut(ringQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) - errMessage(0,"recDynLinkClear: rngBufPut error"); - semGive(wakeUpSem); - FASTUNLOCK(&lock); + if(pdynLinkPvt->io==ioInput) { + if(rngBufPut(inpRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) + errMessage(0,"recDynLinkClear: rngBufPut error"); + } else { + if(rngBufPut(outRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) + errMessage(0,"recDynLinkClear: rngBufPut error"); + } + precDynLink->pdynLinkPvt = NULL; return(0); } - + long recDynLinkConnectionStatus(recDynLink *precDynLink) { dynLinkPvt *pdynLinkPvt; @@ -157,7 +211,7 @@ long recDynLinkConnectionStatus(recDynLink *precDynLink) status = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1; return(status); } - + long recDynLinkGetNelem(recDynLink *precDynLink,size_t *nelem) { dynLinkPvt *pdynLinkPvt; @@ -174,7 +228,7 @@ long recDynLinkGetControlLimits(recDynLink *precDynLink, dynLinkPvt *pdynLinkPvt; pdynLinkPvt = precDynLink->pdynLinkPvt; - if(!pdynLinkPvt->getCompleted) return(-1); + if(pdynLinkPvt->state!=stateConnected) return(-1); if(low) *low = pdynLinkPvt->controlLow; if(high) *high = pdynLinkPvt->controlHigh; return(0); @@ -186,18 +240,18 @@ long recDynLinkGetGraphicLimits(recDynLink *precDynLink, dynLinkPvt *pdynLinkPvt; pdynLinkPvt = precDynLink->pdynLinkPvt; - if(!pdynLinkPvt->getCompleted) return(-1); + if(pdynLinkPvt->state!=stateConnected) return(-1); if(low) *low = pdynLinkPvt->graphicLow; if(high) *high = pdynLinkPvt->graphHigh; return(0); } - + long recDynLinkGetPrecision(recDynLink *precDynLink,int *prec) { dynLinkPvt *pdynLinkPvt; pdynLinkPvt = precDynLink->pdynLinkPvt; - if(!pdynLinkPvt->getCompleted) return(-1); + if(pdynLinkPvt->state!=stateConnected) return(-1); if(prec) *prec = pdynLinkPvt->precision; return(0); } @@ -208,7 +262,7 @@ long recDynLinkGetUnits(recDynLink *precDynLink,char *units,int maxlen) int maxToCopy; pdynLinkPvt = precDynLink->pdynLinkPvt; - if(!pdynLinkPvt->getCompleted) return(-1); + if(pdynLinkPvt->state!=stateConnected) return(-1); maxToCopy = MAX_UNITS_SIZE; if(maxlenunits,maxToCopy); @@ -216,32 +270,6 @@ long recDynLinkGetUnits(recDynLink *precDynLink,char *units,int maxlen) return(0); } -long recDynLinkAddInput(recDynLink *precDynLink, - recDynCallback monitorCallback,short dbrType,size_t nRequest) -{ - dynLinkPvt *pdynLinkPvt; - ringBufCmd cmd; - - FASTLOCK(&lock); - pdynLinkPvt = precDynLink->pdynLinkPvt; - if(!pdynLinkPvt) { - printf("recDynLinkAddInput. recDynLinkSearch was never called\n"); - taskSuspend(0); - } - pdynLinkPvt->monitorCallback = monitorCallback; - pdynLinkPvt->dbrType = dbrType; - pdynLinkPvt->nRequest = nRequest; - if(nRequest>0) - pdynLinkPvt->pbuffer = calloc(nRequest,dbr_size[dbrType]); - cmd.precDynLink = precDynLink; - cmd.cmd = cmdAddInput; - if(rngBufPut(ringQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) - errMessage(0,"recDynLinkAddMonitor: rngBufPut error"); - semGive(wakeUpSem); - FASTUNLOCK(&lock); - return(0); -} - long recDynLinkGet(recDynLink *precDynLink,void *pbuffer,size_t *nRequest, TS_STAMP *timestamp,short *status,short *severity) { @@ -249,67 +277,78 @@ long recDynLinkGet(recDynLink *precDynLink,void *pbuffer,size_t *nRequest, long caStatus; pdynLinkPvt = precDynLink->pdynLinkPvt; - FASTLOCK(&pdynLinkPvt->lock); caStatus = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1; if(caStatus) goto all_done; if(*nRequest > pdynLinkPvt->nRequest) { *nRequest = pdynLinkPvt->nRequest; } + FASTLOCK(&pdynLinkPvt->lock); memcpy(pbuffer,pdynLinkPvt->pbuffer, (*nRequest * dbr_size[mapNewToOld[pdynLinkPvt->dbrType]])); if(timestamp) *timestamp = pdynLinkPvt->timestamp; /*array copy*/ if(status) *status = pdynLinkPvt->status; if(severity) *severity = pdynLinkPvt->severity; -all_done: FASTUNLOCK(&pdynLinkPvt->lock); +all_done: return(caStatus); } -long recDynLinkPut(recDynLink *precDynLink, - short dbrType,void *pbuffer,size_t nRequest) +long recDynLinkPut(recDynLink *precDynLink,void *pbuffer,size_t nRequest) { dynLinkPvt *pdynLinkPvt; long status; ringBufCmd cmd; - FASTLOCK(&lock); pdynLinkPvt = precDynLink->pdynLinkPvt; - status = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1; - if(status) goto all_done; - if(nRequest!=pdynLinkPvt->nRequest - || dbrType!=pdynLinkPvt->dbrType) { - free(pdynLinkPvt->pbuffer); - pdynLinkPvt->pbuffer = calloc(nRequest,dbr_size[mapNewToOld[dbrType]]); - pdynLinkPvt->dbrType = dbrType; - pdynLinkPvt->nRequest = nRequest; + if(pdynLinkPvt->io!=ioOutput || pdynLinkPvt->state!=stateConnected) { + status = -1; + } else { + status = (ca_state(pdynLinkPvt->chid)==cs_conn) ? 0 : -1; } + if(status) goto all_done; + if(pdynLinkPvt->scalar) nRequest = 1; + if(nRequest>ca_element_count(pdynLinkPvt->chid)) + nRequest = ca_element_count(pdynLinkPvt->chid); + pdynLinkPvt->nRequest = nRequest; memcpy(pdynLinkPvt->pbuffer,pbuffer, - (nRequest * dbr_size[mapNewToOld[dbrType]])); - cmd.precDynLink = precDynLink; + (nRequest * dbr_size[mapNewToOld[pdynLinkPvt->dbrType]])); + cmd.data.precDynLink = precDynLink; cmd.cmd = cmdPut; - if(rngBufPut(ringQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) - errMessage(0,"recDynLinkPut: rngBufPut error"); + if(rngBufPut(outRingQ,(void *)&cmd,sizeof(cmd)) != sizeof(cmd)) + errMessage(0,"recDynLinkPut: rngBufPut error"); semGive(wakeUpSem); all_done: - FASTUNLOCK(&lock); + return(status); } -LOCAL void recDynLinkStart(void) +LOCAL void recDynLinkStartInput(void) { - FASTLOCKINIT(&lock); - if((wakeUpSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL) - errMessage(0,"semBcreate failed in recDynLinkStart"); - if((ringQ = rngCreate(sizeof(ringBufCmd) * recDynLinkQsize)) == NULL) { + if((inpRingQ = rngCreate(sizeof(ringBufCmd) * recDynLinkQsize)) == NULL) { errMessage(0,"recDynLinkStart failed"); exit(1); } - taskid = taskSpawn("recDynLink",CA_CLIENT_PRI-1,VX_FP_TASK, - CA_CLIENT_STACK,(FUNCPTR)recDynLinkTask,0,0,0,0,0,0,0,0,0,0); - if(taskid==ERROR) { - errMessage(0,"recDynLinkStart: taskSpawn Failure\n"); + inpTaskId = taskSpawn("recDynINP",CA_CLIENT_PRI-1,VX_FP_TASK, + CA_CLIENT_STACK,(FUNCPTR)recDynLinkInp,0,0,0,0,0,0,0,0,0,0); + if(inpTaskId==ERROR) { + errMessage(0,"recDynLinkStartInput: taskSpawn Failure\n"); } } +LOCAL void recDynLinkStartOutput(void) +{ + if((wakeUpSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL) + errMessage(0,"semBcreate failed in recDynLinkStart"); + if((outRingQ = rngCreate(sizeof(ringBufCmd) * recDynLinkQsize)) == NULL) { + errMessage(0,"recDynLinkStartOutput failed"); + exit(1); + } + outTaskId = taskSpawn("recDynOUT",CA_CLIENT_PRI-1,VX_FP_TASK, + CA_CLIENT_STACK,(FUNCPTR)recDynLinkOut,0,0,0,0,0,0,0,0,0,0); + if(outTaskId==ERROR) { + errMessage(0,"recDynLinkStart: taskSpawn Failure\n"); + } +} + LOCAL void connectCallback(struct connection_handler_args cha) { chid chid = cha.chid; @@ -319,12 +358,12 @@ LOCAL void connectCallback(struct connection_handler_args cha) precDynLink = (recDynLink *)ca_puser(cha.chid); pdynLinkPvt = precDynLink->pdynLinkPvt; if(ca_state(chid)==cs_conn) { + pdynLinkPvt->state = stateGetting; SEVCHK(ca_get_callback(DBR_CTRL_DOUBLE,chid,getCallback,precDynLink), "ca_get_callback"); } else { if(pdynLinkPvt->searchCallback) (pdynLinkPvt->searchCallback)(precDynLink); - pdynLinkPvt->getCompleted=FALSE; } } @@ -333,16 +372,32 @@ LOCAL void getCallback(struct event_handler_args eha) struct dbr_ctrl_double *pdata = (struct dbr_ctrl_double *)eha.dbr; recDynLink *precDynLink; dynLinkPvt *pdynLinkPvt; + size_t nRequest; - precDynLink = (recDynLink *)eha.usr; + precDynLink = (recDynLink *)ca_puser(eha.chid); pdynLinkPvt = precDynLink->pdynLinkPvt; + pdynLinkPvt->state = stateConnected; pdynLinkPvt -> graphicLow = pdata->lower_disp_limit; pdynLinkPvt -> graphHigh = pdata->upper_disp_limit; pdynLinkPvt -> controlLow = pdata->lower_ctrl_limit; pdynLinkPvt -> controlHigh = pdata->upper_ctrl_limit; pdynLinkPvt -> precision = pdata->precision; strncpy(pdynLinkPvt->units,pdata->units,MAX_UNITS_SIZE); - pdynLinkPvt->getCompleted = TRUE; + if(pdynLinkPvt->scalar) { + pdynLinkPvt->nRequest = 1; + } else { + pdynLinkPvt->nRequest = ca_element_count(pdynLinkPvt->chid); + } + nRequest = pdynLinkPvt->nRequest; + pdynLinkPvt->pbuffer = calloc(nRequest,dbr_size[pdynLinkPvt->dbrType]); + if(pdynLinkPvt->io==ioInput) { + SEVCHK(ca_add_array_event( + dbf_type_to_DBR_TIME(mapNewToOld[pdynLinkPvt->dbrType]), + pdynLinkPvt->nRequest, + pdynLinkPvt->chid,monitorCallback,precDynLink, + 0.0,0.0,0.0, + &pdynLinkPvt->evid),"ca_add_array_event"); + } if(pdynLinkPvt->searchCallback) (pdynLinkPvt->searchCallback)(precDynLink); } @@ -356,7 +411,7 @@ LOCAL void monitorCallback(struct event_handler_args eha) void *pdata; short timeType; - precDynLink = (recDynLink *)eha.usr; + precDynLink = (recDynLink *)ca_puser(eha.chid); pdynLinkPvt = precDynLink->pdynLinkPvt; if(pdynLinkPvt->pbuffer) { FASTLOCK(&pdynLinkPvt->lock); @@ -376,7 +431,7 @@ LOCAL void monitorCallback(struct event_handler_args eha) (*pdynLinkPvt->monitorCallback)(precDynLink); } -LOCAL void recDynLinkTask(void) +LOCAL void recDynLinkInp(void) { int status; recDynLink *precDynLink; @@ -387,37 +442,73 @@ LOCAL void recDynLinkTask(void) taskwdInsert(taskIdSelf(),NULL,NULL); SEVCHK(ca_task_initialize(),"ca_task_initialize"); while(TRUE) { - semTake(wakeUpSem,sysClkRateGet()/10); - while (rngNBytes(ringQ)>=sizeof(cmd) && interruptAccept){ - if(rngBufGet(ringQ,(void *)&cmd,sizeof(cmd)) + while (rngNBytes(inpRingQ)>=sizeof(cmd) && interruptAccept){ + if(rngBufGet(inpRingQ,(void *)&cmd,sizeof(cmd)) !=sizeof(cmd)) { errMessage(0,"recDynLinkTask: rngBufGet error"); continue; } - FASTLOCK(&lock); - precDynLink = cmd.precDynLink; - pdynLinkPvt = precDynLink->pdynLinkPvt; - FASTUNLOCK(&lock); - switch(cmd.cmd) { - case(cmdSearch) : - SEVCHK(ca_build_and_connect(pdynLinkPvt->pvname, - TYPENOTCONN,0,&pdynLinkPvt->chid, - NULL,connectCallback,precDynLink), - "ca_build_and_connect"); - break; - case(cmdClear): - SEVCHK(ca_clear_channel(pdynLinkPvt->chid), + if(cmd.cmd==cmdClear) { + pdynLinkPvt = cmd.data.pdynLinkPvt; + if(pdynLinkPvt->chid) + SEVCHK(ca_clear_channel(pdynLinkPvt->chid), "ca_clear_channel"); free(pdynLinkPvt->pbuffer); + free((void *)pdynLinkPvt); + continue; + } + precDynLink = cmd.data.precDynLink; + pdynLinkPvt = precDynLink->pdynLinkPvt; + switch(cmd.cmd) { + case(cmdSearch) : + SEVCHK(ca_search_and_connect(pdynLinkPvt->pvname, + &pdynLinkPvt->chid, connectCallback,precDynLink), + "ca_search_and_connect"); + break; + default: + epicsPrintf("Logic error statement in recDynLinkTask\n"); + } + } + status = ca_pend_event(.1); + if(status!=ECA_NORMAL && status!=ECA_TIMEOUT) + SEVCHK(status,"ca_pend_event"); + } +} + +LOCAL void recDynLinkOut(void) +{ + int status; + recDynLink *precDynLink; + dynLinkPvt *pdynLinkPvt; + ringBufCmd cmd; + int caStatus; + + taskwdInsert(taskIdSelf(),NULL,NULL); + SEVCHK(ca_task_initialize(),"ca_task_initialize"); + while(TRUE) { + semTake(wakeUpSem,sysClkRateGet()/10); + while (rngNBytes(outRingQ)>=sizeof(cmd) && interruptAccept){ + if(rngBufGet(outRingQ,(void *)&cmd,sizeof(cmd)) + !=sizeof(cmd)) { + errMessage(0,"recDynLinkTask: rngBufGet error"); + continue; + } + if(cmd.cmd==cmdClear) { + pdynLinkPvt = cmd.data.pdynLinkPvt; + if(pdynLinkPvt->chid) + SEVCHK(ca_clear_channel(pdynLinkPvt->chid), + "ca_clear_channel"); free(pdynLinkPvt->pbuffer); free((void *)pdynLinkPvt); - precDynLink->pdynLinkPvt = NULL; - break; - case(cmdAddInput) : - SEVCHK(ca_add_event( - dbf_type_to_DBR_TIME(mapNewToOld[pdynLinkPvt->dbrType]), - pdynLinkPvt->chid,monitorCallback,precDynLink, - &pdynLinkPvt->evid),"ca_add_event"); + continue; + } + precDynLink = cmd.data.precDynLink; + pdynLinkPvt = precDynLink->pdynLinkPvt; + switch(cmd.cmd) { + case(cmdSearch) : + SEVCHK(ca_search_and_connect(pdynLinkPvt->pvname, + &pdynLinkPvt->chid, connectCallback,precDynLink), + "ca_search_and_connect"); break; case(cmdPut) : caStatus = ca_array_put( @@ -438,153 +529,3 @@ LOCAL void recDynLinkTask(void) SEVCHK(status,"ca_pend_event"); } } - -/*The remainder of this source module is test code */ -typedef struct userPvt { - int testingInput; - char *pvname; - double *pbuffer; - size_t nRequest; -}userPvt; - -LOCAL void mymonitorCallback(recDynLink *precDynLink) -{ - userPvt *puserPvt; - long status; - size_t nRequest; - TS_STAMP timestamp; - short AlarmStatus,AlarmSeverity; - int i; - char timeStr[40]; - - puserPvt = (userPvt *)precDynLink->puserPvt; - printf("mymonitorCallback: %s\n",puserPvt->pvname); - if(recDynLinkConnectionStatus(precDynLink)!=0) { - printf(" not connected\n"); - return; - } - nRequest = puserPvt->nRequest; - status = recDynLinkGet(precDynLink,puserPvt->pbuffer,&nRequest, - ×tamp,&AlarmStatus,&AlarmSeverity); - if(status) { - printf("recDynLinkGet returned illegal status\n"); - return; - } - tsStampToText(×tamp,TS_TEXT_MMDDYY,timeStr); - printf("date %s status %hd severity %hd ", - timeStr,AlarmStatus,AlarmSeverity); - for(i=0; inRequest; i++) { - printf(" %f",puserPvt->pbuffer[i]); - } - printf("\n"); -} - -LOCAL void mysearchCallback(recDynLink *precDynLink) -{ - userPvt *puserPvt; - size_t nelem; - double controlLow,controlHigh; - double graphicLow,graphicHigh; - int prec; - char units[20]; - long status; - - puserPvt = (userPvt *)precDynLink->puserPvt; - printf("mysearchCallback: %s ",puserPvt->pvname); - if(recDynLinkConnectionStatus(precDynLink)==0) { - printf("connected\n"); - status = recDynLinkGetNelem(precDynLink,&nelem); - if(status) { - printf("recDynLinkGetNelem failed\n"); - }else{ - printf("nelem = %u\n",nelem); - } - status=recDynLinkGetControlLimits(precDynLink,&controlLow,&controlHigh); - if(status) { - printf("recDynLinkGetControlLimits failed\n"); - }else{ - printf("controlLow %f controlHigh %f\n",controlLow,controlHigh); - } - status=recDynLinkGetGraphicLimits(precDynLink,&graphicLow,&graphicHigh); - if(status) { - printf("recDynLinkGetGraphicLimits failed\n"); - }else{ - printf("graphicLow %f graphicHigh %f\n",graphicLow,graphicHigh); - } - status = recDynLinkGetPrecision(precDynLink,&prec); - if(status) { - printf("recDynLinkGetPrecision failed\n"); - }else{ - printf("prec = %d\n",prec); - } - status = recDynLinkGetUnits(precDynLink,units,20); - if(status) { - printf("recDynLinkGetUnits failed\n"); - }else{ - printf("units = %s\n",units); - } - if(puserPvt->testingInput) { - status = recDynLinkAddInput(precDynLink,mymonitorCallback, - newDBR_DOUBLE, puserPvt->nRequest); - if(status) printf("recDynLinkAddInput failed\n"); - } - } else { - printf(" not connected\n"); - } -} - -LOCAL recDynLink getDynlink = {NULL,NULL}; -LOCAL recDynLink putDynlink = {NULL,NULL}; - -int recDynTestInput(char *pvname,int nRequest) -{ - userPvt *puserPvt= getDynlink.puserPvt; - long status; - - if(puserPvt) { - free(puserPvt->pbuffer); - free(getDynlink.puserPvt); - getDynlink.puserPvt = NULL; - recDynLinkClear(&getDynlink); - } - getDynlink.puserPvt = puserPvt = (userPvt *)calloc(1,sizeof(userPvt)); - puserPvt->pbuffer = calloc(nRequest,sizeof(double)); - puserPvt->nRequest = nRequest; - puserPvt->pvname = pvname; - puserPvt->testingInput = TRUE; - status = recDynLinkSearch(&getDynlink,pvname,mysearchCallback,FALSE); - if(status) return(status); - return(status); -} - -int recDynTestNewOutput(char *pvname,int nRequest) -{ - userPvt *puserPvt= putDynlink.puserPvt; - long status; - - if(puserPvt) { - free(puserPvt->pbuffer); - free(putDynlink.puserPvt); - putDynlink.puserPvt = NULL; - recDynLinkClear(&putDynlink); - } - putDynlink.puserPvt = puserPvt = (userPvt *)calloc(1,sizeof(userPvt)); - puserPvt->pbuffer = calloc(nRequest,sizeof(double)); - puserPvt->nRequest = nRequest; - puserPvt->pvname = pvname; - puserPvt->testingInput = FALSE; - status = recDynLinkSearch(&putDynlink,pvname,mysearchCallback,FALSE); - return(status); -} - -int recDynTestOutput(int startValue) -{ - userPvt *puserPvt= putDynlink.puserPvt; - long status; - int i; - - for(i=0; inRequest; i++) puserPvt->pbuffer[i] = startValue + i; - status = recDynLinkPut(&putDynlink,newDBR_DOUBLE,puserPvt->pbuffer, - puserPvt->nRequest); - return(status); -} diff --git a/src/rec/recDynLink.h b/src/rec/recDynLink.h index 8bdbcab0e..e45493331 100644 --- a/src/rec/recDynLink.h +++ b/src/rec/recDynLink.h @@ -8,8 +8,15 @@ typedef struct recDynLink{ } recDynLink; typedef void (*recDynCallback)(recDynLink *); -long recDynLinkSearch(recDynLink *precDynLink,char *pvname, - recDynCallback searchCallback,int dbOnly); +#define rdlDBONLY 0x1 +#define rdlSCALAR 0x2 + +long recDynLinkAddInput(recDynLink *precDynLink,char *pvname, + short dbrType,int options, + recDynCallback searchCallback,recDynCallback monitorCallback); +long recDynLinkAddOutput(recDynLink *precDynLink,char *pvname, + short dbrType,int options, + recDynCallback searchCallback); long recDynLinkClear(recDynLink *precDynLink); /*The following routine returns (0,-1) for (connected,not connected)*/ long recDynLinkConnectionStatus(recDynLink *precDynLink); @@ -24,14 +31,10 @@ long recDynLinkGetGraphicLimits(recDynLink *precDynLink, long recDynLinkGetPrecision(recDynLink *precDynLink,int *prec); long recDynLinkGetUnits(recDynLink *precDynLink,char *units,int maxlen); -/*Each recDynLink allows either recDynLinkAddInput or recDynLinkPut NOT BOTH*/ -long recDynLinkAddInput(recDynLink *precDynLink, - recDynCallback monitorCallback,short dbrType,size_t nRequest); -/*recDynLinkAddInput MUST be called before recDynLinkGet works*/ +/*get only valid mfor rdlINPUT. put only valid for rdlOUTPUT*/ long recDynLinkGet(recDynLink *precDynLink, void *pbuffer, size_t *nRequest, TS_STAMP *timestamp,short *status,short *severity); -long recDynLinkPut(recDynLink *precDynLink, - short dbrType,void *pbuffer,size_t nRequest); +long recDynLinkPut(recDynLink *precDynLink,void *pbuffer,size_t nRequest); #endif /*INCrecDynLinkh*/