static void mca_cleanup(void) { int i, status; mexPrintf("Terminating periodic CA polling\n"); KillTimer(NULL,PollTimerHandle); // Clear persistent memory Arrays for(i=0;i<HandlesUsed;i++) { if(CHNLS[i].EVID) { mexPrintf("Clearing monitor on channel %d\n",i); status = ca_clear_event(CHNLS[i].EVID); if(status!=ECA_NORMAL) mexPrintf("ca_clear_event failed\n"); } if(CHNLS[i].CACHE) mxDestroyArray(CHNLS[i].CACHE); if(CHNLS[i].DataBuffer) mxFree(CHNLS[i].DataBuffer); if(CHNLS[i].MonitorCBString) mxFree(CHNLS[i].MonitorCBString); } mexPrintf("Closing CA connections ...\n"); ca_task_exit(); HandlesUsed = 0; CA_INITIALIZED = false; }
/* * ca_test * * find channel, write a value if supplied, and * read back the current value * */ int ca_test( char *pname, char *pvalue ) { int status; if(pvalue){ status = capft(pname,pvalue); } else{ status = cagft(pname); } ca_task_exit(); return status; }
/* * end channel access: note - should just clean up the CURRENT CONTEXT! */ int end_CA() { int stat; stat = ca_pend_event(0.01); if( stat != ECA_TIMEOUT && stat != ECA_NORMAL) printf("ca_pend_event failed\n"); #if 0 stat = ca_task_exit(); if( stat != ECA_NORMAL) { printf("ca_task_exit failed\n"); return -1; } #endif return 0; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int status; if(!CA_INITIALIZED) // Initialize CA if not initialized (first call) { mexPrintf("Initializing MATLAB Channel Access ... \n"); status = ca_task_initialize(); if(status!=ECA_NORMAL) mexErrMsgTxt("Unable to initialise Challel Access\n"); CA_INITIALIZED = true; // Register a function to be called when a this mex-file is cleared from memory // with 'clear' or when exitting MATLAB } else { CA_INITIALIZED = false; mexPrintf("Closing MATLAB Channel Access ... \n"); ca_task_exit(); } }
void medmCATerminate() { int status; /* Cancel registration of the CA file descriptors */ /* KE: Doesn't cancel it. The first argument should be NULL for cancel */ /* And why do we want to cancel it ? */ status = ca_task_initialize(); if(status != ECA_NORMAL) { medmPostMsg(1,"medmCATerminate: ca_add_fd_registration failed: %s\n", ca_message(status)); } /* Do a pend_event */ /* KE: Why? */ #ifdef __MONITOR_CA_PEND_EVENT__ { double t; t = medmTime(); /* Don't allow early returns */ ca_pend_event(20.0*CA_PEND_EVENT_TIME); t = medmTime() - t; if(t > 0.5) { print("medmCATerminate: time used by ca_pend_event = %8.1f\n",t); } } #else ca_pend_event(20.0*CA_PEND_EVENT_TIME); /* don't allow early returns */ #endif /* Close down channel access */ status = ca_task_exit(); if(status != ECA_NORMAL) { medmPostMsg(1,"medmCATerminate: ca_task_exit failed: %s\n", ca_message(status)); } /* Clean up the memory allocated for Channel's */ /* KE: Used to be done first */ caTaskDelete(); }
int main(int argc, char** argv) { fd_set rfds; int tot; struct timeval tv; if(argc!=3) { fprintf(stderr,"Usage: %s PV_to_monitor script_to_run\n\n",argv[0]); fprintf(stderr,"This program monitored PV PV_to_monitor and\n"); fprintf(stderr,"runs and executes script_to_run, which can be\n"); fprintf(stderr,"any program or executable script.\n"); fprintf(stderr,"The script or program gets invoked with the first\n"); fprintf(stderr,"argument as the PV name and the second argument\n"); fprintf(stderr,"as the value of the PV\n"); fprintf(stderr,"The program or shell script script_to_run is\n"); fprintf(stderr,"run as a separate child process of this program\n"); fprintf(stderr,"This means that your script or program will not\n"); fprintf(stderr,"stop this process from running, if fact your\n"); fprintf(stderr,"script or program can be invoked many times if\n"); fprintf(stderr,"the value of the PV is changing rapidly and\n"); fprintf(stderr,"several instances of your program could be running\n"); fprintf(stderr,"simultaneously.\n"); return -1; } strcpy(pv_name,argv[1]); script_name=argv[2]; pv_value[0]='\0'; if(access(script_name,X_OK)<0) { fprintf(stderr,"Script %s not found or not executable\n",script_name); return -1; } signal(SIGINT,sig_func); signal(SIGQUIT,sig_func); signal(SIGTERM,sig_func); signal(SIGHUP,sig_func); signal(SIGCHLD,sig_chld); FD_ZERO(&all_fds); SEVCHK(ca_task_initialize(),"task initialize"); SEVCHK(ca_add_fd_registration(fdCB,&all_fds),"add fd registration"); SEVCHK(ca_add_exception_event(exCB,NULL),"add exception event"); SEVCHK(ca_search_and_connect(pv_name,&id,conCB,NULL), "search and connect"); SEVCHK(ca_replace_access_rights_event(id,accCB), "replace access rights event"); /* SEVCHK(ca_add_event(DBR_TIME_STRING,data.id,evCB,&data,&data.event), "add event"); */ ca_pend_event(REALLY_SMALL); /* fprintf(stderr,"Monitoring <%s>\n",pv_name); */ while(do_not_exit) { rfds=all_fds; tv.tv_sec=1; tv.tv_usec=0; /*200000*/; switch(tot=select(FD_SETSIZE,&rfds,NULL,NULL,&tv)) { /* case -1: perror("select error - bad"); break; */ case 0: ca_pend_event(REALLY_SMALL); break; default: /* fprintf(stderr,"select data ready\n"); */ ca_pend_event(REALLY_SMALL); break; } } fprintf(stderr,"PV monitor program is exiting!\n"); ca_task_exit(); return 0; }
void mca_close_channels(void) { mexPrintf("Closing CA connections ...\n"); ca_task_exit(); HandlesUsed = 0; CA_INITIALIZED = false; }
int main(int argc,char **argv) { char *pval; double sleepSecs = 0.0; int clearEvery = 0; int indValue = 1; int indNumberCallback = 1; while((argc>1) && (argv[1][0] == '-')) { int i; char option; int narg; option = toupper((argv[1])[1]); pval = argv[2]; argc -= 1; narg = 1; if(option=='S') { sscanf(pval,"%lf",&sleepSecs); argc -= 1; ++narg; } else if(option=='C') { sscanf(pval,"%d",&clearEvery); argc -= 1; ++narg; } else if(option=='V') { verbose = 1; } else { usageExit(); } for(i=1; i<argc; i++) argv[i] = argv[i + narg]; } if(argc != 4) usageExit(); pvname = argv[1]; pvalue1 = argv[2]; pvalue2 = argv[3]; pevent = epicsEventCreate(epicsEventEmpty); SEVCHK(ca_context_create(ca_enable_preemptive_callback), "ca_task_initialize"); while(1) { SEVCHK(ca_search(pvname,&mychid),"ca_search_and_connect"); if(ca_pend_io(3.0)!=ECA_NORMAL) { epicsThreadSleep(5.0); continue; } while(1) { epicsEventWaitStatus status; if(indValue==0) { indValue = 1; pvalue = pvalue2; } else { indValue = 0; pvalue=pvalue1; } if(++indNumberCallback >= MAXnumberCallback) indNumberCallback=0; numberCallback[indNumberCallback] = ++expectedCallback; status = ca_array_put_callback(DBR_STRING,1,mychid, pvalue,putCallback,&numberCallback[indNumberCallback]); if(status!=ECA_NORMAL) { printf("ca_array_put_callback %s\n",ca_message(status)); epicsThreadSleep(2.0); continue; } if((clearEvery>0) && ((expectedCallback % clearEvery)==0)) { ca_flush_io(); epicsThreadSleep(sleepSecs); SEVCHK(ca_clear_channel(mychid),"ca_clear_channel"); ca_flush_io(); expectedCallback = 0; epicsThreadSleep(sleepSecs); if(verbose) { printTime(); printf("Issued ca_clear_channel expectedCallback %d\n", expectedCallback); } break; } ca_flush_io(); if(verbose) { printTime(); printf("Issued ca_put_callback expectedCallback %d\n", expectedCallback); } while(1) { status = epicsEventWaitWithTimeout(pevent,10.0); if(status==epicsEventWaitTimeout) { if(verbose) { printTime(); printf("timeout after 10 seconds\n"); } continue; } break; } if(status!=epicsEventWaitOK) { int i; printTime(); printf("eventWait status %d\n",status); for(i=0; i<MAXnumberCallback; i++) numberCallback[i]=0; } epicsThreadSleep(sleepSecs); } } ca_task_exit(); return(0); }