Still new

This commit is contained in:
Marty Kraimer
1995-08-30 21:17:46 +00:00
parent e635080cef
commit adffe02a2d
3 changed files with 217 additions and 271 deletions

View File

@@ -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

View File

@@ -7,6 +7,7 @@
#include <rngLib.h>
#include <vxLib.h>
#include <semLib.h>
#include <sysLib.h>
#include <dbDefs.h>
#include <taskwd.h>
@@ -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(maxlen<maxToCopy) maxToCopy = maxlen;
strncpy(units,pdynLinkPvt->units,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,
&timestamp,&AlarmStatus,&AlarmSeverity);
if(status) {
printf("recDynLinkGet returned illegal status\n");
return;
}
tsStampToText(&timestamp,TS_TEXT_MMDDYY,timeStr);
printf("date %s status %hd severity %hd ",
timeStr,AlarmStatus,AlarmSeverity);
for(i=0; i<puserPvt->nRequest; 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; i<puserPvt->nRequest; i++) puserPvt->pbuffer[i] = startValue + i;
status = recDynLinkPut(&putDynlink,newDBR_DOUBLE,puserPvt->pbuffer,
puserPvt->nRequest);
return(status);
}

View File

@@ -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*/