static void KIM_makePersistent() { mexMakeArrayPersistent(mx_data); mexMakeArrayPersistent(mx_SYSfct); mexMakeArrayPersistent(mx_JACfct); mexMakeArrayPersistent(mx_PSETfct); mexMakeArrayPersistent(mx_PSOLfct); mexMakeArrayPersistent(mx_GLOCfct); mexMakeArrayPersistent(mx_GCOMfct); mexMakeMemoryPersistent(kim_Kdata); mexMakeMemoryPersistent(kim_Mdata); return; }
void *AllocMem(size_t n) { void *p; p = mxMalloc( n ); mexMakeMemoryPersistent(p); return p; }
/* memory management */ void* operator new(size_t size) { void *ptr = NULL; // mexWarnMsgTxt("Overloaded new operator"); ptr = mxMalloc(size); mexMakeMemoryPersistent(ptr); return ptr; }
void* operator new[](size_t size) { void *ptr = NULL; // mexWarnMsgTxt("Overloaded new[] operator"); ptr = mxMalloc(size); mxAssert(ptr!=NULL,"memory allocation error"); mexMakeMemoryPersistent(ptr); return ptr; }
/* Loads the given named dynamic library file. Retrieves function pointers to the simengine API calls. */ void init_simengine(const char *name) { char *msg; api = NMALLOC(1, simengine_api); mexMakeMemoryPersistent(api); api->driver = dlopen(name, RTLD_NOW); if(!api->driver) { ERROR(Simatra:SIMEX:HELPER:dynamicLoadError, "dlopen() failed to load %s: %s", name, dlerror()); }
CallbackData * CBDCreate(const mxArray *taskObj, CallbackTypeEnum callbackTypeEnum, const char *callbackFuncProp, mxArray *eventData, void *callbackTypeData) { CallbackData *cbd = (CallbackData*)mxCalloc(1,sizeof(CallbackData)); mexMakeMemoryPersistent(cbd); //Pack callbackData structure cbd->taskObjHandle = mxDuplicateArray(taskObj); mexMakeArrayPersistent(cbd->taskObjHandle); mxArray *mxTaskID = mxGetProperty(taskObj,0,"taskID"); TaskHandle *taskIDPtr = (TaskHandle*)mxGetData(mxTaskID); cbd->taskHandle = *taskIDPtr; mxDestroyArray(mxTaskID); mxArray *callbackFuncs = mxGetProperty(taskObj,0,callbackFuncProp); size_t numCallbacks = mxGetNumberOfElements(callbackFuncs); if (numCallbacks > MAXNUMCALLBACKS) { mexErrMsgTxt("Exceeded the maximum allowed number of callback functions."); /// leak a bunch of memory, no biggie (see doc for fcn) } for (size_t i=0;i<numCallbacks;i++) { cbd->callbackFuncHandles[i] = mxDuplicateArray(mxGetCell(callbackFuncs,i)); mexMakeArrayPersistent(cbd->callbackFuncHandles[i]); } mxDestroyArray(callbackFuncs); for (size_t i=numCallbacks;i<MAXNUMCALLBACKS;++i) { cbd->callbackFuncHandles[i] = NULL; } cbd->numCallbacks = numCallbacks; cbd->callbackType = CallbackTypeStrings[callbackTypeEnum]; if (eventData==NULL) { // use default empty event array mxArray *eventArray = mxCreateStructMatrix(0, 0, 0, 0); mexMakeArrayPersistent(eventArray); cbd->eventData = eventArray; } else { cbd->eventData = eventData; } cbd->callbackTypeData = callbackTypeData; #if DEBUG_MEX mexPrintf("At end of CBDCreate.\n"); CBDDebug(cbd); #endif return cbd; }
char *options_outputs_directory(const mxArray *opts){ char *dir; assert(mxSTRUCT_CLASS == mxGetClassID(opts)); mxArray *outputs = mxGetField(opts, 0, "outputs"); assert(mxCHAR_CLASS == mxGetClassID(outputs)); dir = mxArrayToString(outputs); mexMakeMemoryPersistent(dir); if(!dir){ ERROR("Invalid output directory name.\n"); } return dir; }
/* return a sparse matrix to MATLAB */ mxArray *cs_mex_put_sparse (cs **Ahandle) { cs *A ; mxArray *Amatlab ; A = *Ahandle ; Amatlab = mxCreateSparse (0, 0, 0, mxREAL) ; mxSetM (Amatlab, A->m) ; mxSetN (Amatlab, A->n) ; mxSetNzmax (Amatlab, A->nzmax) ; cs_free (mxGetJc (Amatlab)) ; cs_free (mxGetIr (Amatlab)) ; cs_free (mxGetPr (Amatlab)) ; mxSetJc (Amatlab, A->p) ; /* assign A->p pointer to MATLAB A */ mxSetIr (Amatlab, A->i) ; mxSetPr (Amatlab, A->x) ; mexMakeMemoryPersistent (A->p) ; /* ensure MATLAB does not free A->p */ mexMakeMemoryPersistent (A->i) ; mexMakeMemoryPersistent (A->x) ; cs_free (A) ; /* frees A struct only, not A->p, etc */ *Ahandle = NULL ; return (Amatlab) ; }
extern "C" void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[]) { if (!(nrhs==1 || nrhs==4)) { mexPrintf("%s",usage_string); return; } // Check validity of inputs. if (!mxIsDouble(pma_f) || mxIsSparse(pma_f)) { mexPrintf("%s",usage_string); return; } if (nrhs==4) { if (!cheby_op::is_valid_input(pma_L,pma_c,pma_arange) ) { mexPrintf("%s",usage_string); return; } } // Handle persistent memory if (nrhs==4) { cleanup(); my_cheby_op=new cheby_op(pma_L,pma_c,pma_arange); mexMakeMemoryPersistent(my_cheby_op); mexAtExit(cleanup); initialized=1; } /* at this point, static data should be initialized. If not, then function was called first with only one argument, which is an error */ if (!initialized) mexErrMsgTxt("not initialized : call with L,c,arange at least once first\n"); int N=my_cheby_op->N; int s=my_cheby_op->s; if (mxGetNumberOfElements(pma_f)!=N) mexErrMsgTxt("mismatch between dimensions of f and L\n"); /* now, actually do computation */ plhs[0]=mxCreateDoubleMatrix(N * s,1,mxREAL); // set up array of pointers, each of size N corresponding to // a column of res double *res[s]; for (int ks=0; ks<s; ks++) { res[ks]=mxGetPr(plhs[0])+ks*N; } my_cheby_op->cheby_op_forward(res,mxGetPr(pma_f)); //sgwt_cheby_op(res,mxGetPr(pma_f),L,c,arange); }
/* mexFunction is the gateway routine for the MEX-file. */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *X; double *c,*T,*x,*p; int sizeofT, npts, idx; int mm,nn ; static double *ss; /* Check for proper number of arguments */ if (nrhs != 5) { mexErrMsgTxt("Five input arguments required."); } else if (nlhs > 1) { mexErrMsgTxt("Too many output arguments."); } /* Assign pointers to the input parameters */ c = mxGetPr(C_IN); T = mxGetPr(T_IN); x = mxGetPr(X_IN); p = mxGetPr(P_IN); idx = *mxGetPr(IDX_IN); /* Basis function matrix is DIM = [length(t) npts]. t,npts are row vectors*/ mm = mxGetN(T_IN); sizeofT = mm; nn = mxGetN(P_IN); npts = nn; /* Create a matrix for the return argument */ X_OUT = mxCreateDoubleMatrix(mm,2, mxREAL); /* Assign pointers to the output parameters */ X = mxGetPr(X_OUT); ss = mxGetPr(mxCreateDoubleScalar(0)); mexMakeMemoryPersistent(ss); /* Do the actual computations in a subroutine */ DmodelIntP(X,p,c,T,npts,x,idx,sizeofT,ss); mexAtExit(cleanup); return; }
//--------------------------------------------------------------------++ static void init_function_table() { if(myStaticDataInitialized == 0) { // function_table = new function_table_t; boost::assign::insert(*function_table) (0, &ptu_create_)//self.CREATE = 0; (1, &ptu_open_) //self.OPEN =1 (2, &ptu_close_) //self.CLOSE =2 (3, &ptu_pantilt_) //self.PANTITL =3 ; myStaticDataInitialized = 1; myFuncTableSize = static_cast<int> (function_table->size()); mexMakeMemoryPersistent(&myStaticDataInitialized); mexMakeMemoryPersistent(&myFuncTableSize); mexMakeMemoryPersistent(function_table); mexAtExit(exitFcn); } };
/* Returns a vector comprising the number of quantities for each output represented in a model interface. * Nb caller is responsible for releasing the returned pointer by calling mxFree(). */ unsigned int *iface_output_num_quantities(const mxArray *iface){ assert(mxSTRUCT_CLASS == mxGetClassID(iface)); unsigned int num_out = iface_num_outputs(iface); mxArray *num_quant = mxGetField(iface, 0, "outputNumQuantities"); assert(mxDOUBLE_CLASS == mxGetClassID(num_quant)); double *quants = mxGetPr(num_quant); unsigned int *num_quants = (unsigned int *)mxMalloc(num_out * sizeof(unsigned int)); mexMakeMemoryPersistent(num_quants); unsigned int outputid; for (outputid = 0; outputid < num_out; outputid++){ num_quants[outputid] = (unsigned int)(quants[outputid]); } return num_quants; }
/** Replacement for fftw_malloc in mex files */ void *nfft_mex_malloc(size_t n) { void *p; #pragma omp critical (nfft_omp_matlab) { p = mxMalloc(n); /* Should never be reached if mxMalloc fails (in a mex file) but in Matlab * you never know... */ if (!p) mexErrMsgTxt("Not enough memory."); mexMakeMemoryPersistent(p); } return p; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray* outMxArr; // Pointer for our output data const mwSize dims[2] = {1, 1}; // Size of our output data double x, y; // Input and output variables. double* data; // Pointer type for an intermediate step int i,j; // For loop counters // Argument checking. if(nrhs != 1) // Right hand side (a.k.a. 'argc' or 'nargin') mexErrMsgTxt("Takes exactly one argument."); if(nlhs > 1) // Left hand side (number of return values) mexErrMsgTxt("Only returns one thing."); if(!mxIsDouble(prhs[0])) // Sanitize input. mexErrMsgTxt("Input must be a double."); if(!ioData) // If ioData hasn't been set. { ioData = mxCalloc(sizeof(double), 4); // Allocate memory for the values that need to be remembered by the filter. mexMakeMemoryPersistent(ioData); // Tell MATLAB to persist the memory between calls to this function. mexAtExit(&cleanUp); // Register a function to happen at `clear functions` so as not to leak memory. } x = *((double*)mxGetData(prhs[0])); // Get the input value. // Create our return array // 2 dimensional, 1x1(as declared above in dims), IEEE Double Precision type for each cell, no imaginary parts outMxArr = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); y = .0025*ioData[0] + .005*ioData[1] + .0025*x - .81*ioData[2] + 1.8*ioData[3]; // Actually do the calculation for the filter. *((double*)mxGetData(outMxArr)) = y; // Set the output value. // Remember the necessary values for this filter. ioData[0] = ioData[1]; // x[n-2] (two inputs ago) ioData[1] = x; // x[n-1] (last input) ioData[2] = ioData[3]; // y[n-2] (two outputs ago) ioData[3] = y; // y[n-1] (last output) plhs[0] = outMxArr; return; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i,j, k, status,buflen,Cnt, Hndl, L,M,N, NumHandles, commandswitch; int *HndlArray; mxArray *mymxArray; double *myDblPr; chtype RequestType; char PVName[PV_NAME_LENGTH_MAX+1]; // char MCAMessageString[MCA_MESSAGE_STRING_LENGTH_MAX+1]; dbr_string_t StrBuffer; const char *MCAInfoFields[]={"PVName","ElementCount","NativeType","State","MCAMessage","Host"}; char *NativeTypeStrings[] = {"STRING","INT","FLOAT","ENUM","CHAR","LONG","DOUBLE"}; 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 mexAtExit(mca_cleanup); // Lock the mex-file so that it can not be cleared without explicitly // mexUnclock mexLock(); //start periodic polling: /* PollTimerHandle = SetTimer(NULL,NULL,MCA_POLL_PERIOD,background_poll); if(PollTimerHandle) mexPrintf("Periodic CA polling started! System Timer ID: %u\n",PollTimerHandle); else mexWarnMsgTxt("Failed to start periodic CA polling\n"); */ } commandswitch = (int)mxGetScalar(prhs[0]); switch(commandswitch) { case 0: mexUnlock(); break; case 1: // MCAOPEN - add channel(s) by PV names, all arguments following prhs[0] // must be strings - names of PV's for(i=1;i<nrhs;i++) { mxGetString(prhs[i],PVName,PV_NAME_LENGTH_MAX+1); status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID)); if(status == ECA_NORMAL) // if not - go on to the next PV name { status = ca_pend_io(MCA_SEARCH_TIMEOUT); if (status == ECA_NORMAL) { // Allocate persistent memory for the DataBuffer on this channel // to hold all elements of the DBR_XXX type // nearest to the native type // RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); // Cnt=ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].MonitorEventCount = 0; switch(CHNLS[HandlesUsed].NativeType2DBR) { case DBR_STRING: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); break; case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_FLOAT: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); break; case DBR_ENUM: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); break; case DBR_CHAR: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); break; case DBR_LONG: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_DOUBLE: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); break; } mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer); if(CHNLS[HandlesUsed].NativeType2DBR==DBR_STRING) // CACHE { if(CHNLS[HandlesUsed].NumElements==1) // Create MATLAB string - originally empty CHNLS[HandlesUsed].CACHE = mxCreateString(""); else // Create MATLAB cell array of strings { CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements); for(k=0;k<CHNLS[HandlesUsed].NumElements;k++) { mymxArray = mxCreateString(""); mexMakeArrayPersistent(mymxArray); mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray); } } } else // Make CACHE a numeric mxArray { CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL); } mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE); plhs[i-1]=mxCreateScalarDouble(++HandlesUsed); } else plhs[i-1]=mxCreateScalarDouble(0); } else plhs[i-1]=mxCreateScalarDouble(0); } break; case 2:// MCAOPEN - add channel(s) by PV names. The arguments following prhs[0] // argument must be a cell array of strings - PV names L = mxGetM(prhs[1])*mxGetN(prhs[1]); plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<L;i++) { mymxArray = mxGetCell(prhs[1],i); mxGetString(mymxArray,PVName,PV_NAME_LENGTH_MAX+1); status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID)); if(status == ECA_NORMAL) // if not - go on to the next PV name { status = ca_pend_io(MCA_IO_TIMEOUT); if (status == ECA_NORMAL) { // Allcate persistent memory for the DataBuffer on this channel //RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].MonitorEventCount = 0; //Cnt=ca_element_count(CHNLS[HandlesUsed].CHID); switch(CHNLS[HandlesUsed].NativeType2DBR) { case DBR_STRING: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); break; case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_FLOAT: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); break; case DBR_ENUM: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); break; case DBR_CHAR: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); break; case DBR_LONG: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_DOUBLE: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); break; } mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer); if(CHNLS[HandlesUsed].NativeType2DBR == DBR_STRING) // CACHE { CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements); for(k=0;k<CHNLS[HandlesUsed].NumElements;k++) { mymxArray = mxCreateString(StrBuffer); mexMakeArrayPersistent(mymxArray); mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray); } } else { CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL); } mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE); myDblPr[i] = ++HandlesUsed; } else myDblPr[i] = 0; } else myDblPr[i] = 0; } break; case 3: // MCAOPEN Return names of connected channels as cell array of strings plhs[0] = mxCreateCellArray(1, &HandlesUsed); for(i=0;i<HandlesUsed;i++) { if(CHNLS[i].CHID!=NULL) { mymxArray = mxCreateString(ca_name(CHNLS[i].CHID)); mxSetCell(plhs[0], i, mymxArray); } else { mymxArray = mxCreateString(""); //mexPrintf("Handle: %d PV: %s\n",i+1, "Cleared Channel"); mxSetCell(plhs[0], i, mymxArray); } } break; case 5: // MCACLOSE permanently clear channel Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range"); // If a monitor is installed, set the EVID pointer to NULL // ca_clear_event dos not do it by itself if(CHNLS[Hndl-1].EVID) CHNLS[Hndl-1].EVID = NULL; // If there is Callback String - destroy it if(CHNLS[Hndl-1].MonitorCBString) { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString =NULL; } if(ca_state(CHNLS[Hndl-1].CHID)==3) mexWarnMsgTxt("Channel previously cleared"); else if(ca_clear_channel(CHNLS[Hndl-1].CHID)!=ECA_NORMAL) mexErrMsgTxt("ca_clear_channel failed"); break; case 10: // MCAINFO return channels info as MATLAB structure array if(HandlesUsed>0) { plhs[0] = mxCreateStructMatrix(1,HandlesUsed,6,MCAInfoFields); for(i=0;i<HandlesUsed;i++) { mxSetFieldByNumber(plhs[0],i,0,mxCreateString(ca_name(CHNLS[i].CHID))); mxSetFieldByNumber(plhs[0],i,1,mxCreateScalarDouble(ca_element_count(CHNLS[i].CHID))); mxSetFieldByNumber(plhs[0],i,5,mxCreateString(ca_host_name(CHNLS[i].CHID))); switch(ca_state(CHNLS[i].CHID)) { case 1: // Disconnected due to Server or Network - may reconnect mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Disconnected due to server or network problem")); break; case 2: // Normal connection mxSetFieldByNumber(plhs[0],i,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[i].CHID)])); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("connected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Normal connection")); break; case 3: // Disconnected by user mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Permanently disconnected (cleared) by the user")); break; } } } else { mexWarnMsgTxt("No connected PV's found"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } break; case 11: // MCAINFO return info for 1 channel by handle number Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range"); plhs[0] = mxCreateStructMatrix(1,1,6,MCAInfoFields); mxSetFieldByNumber(plhs[0],0,0,mxCreateString(ca_name(CHNLS[Hndl-1].CHID))); mxSetFieldByNumber(plhs[0],0,1,mxCreateScalarDouble(ca_element_count(CHNLS[Hndl-1].CHID))); mxSetFieldByNumber(plhs[0],0,5,mxCreateString(ca_host_name(CHNLS[Hndl-1].CHID))); switch(ca_state(CHNLS[Hndl-1].CHID)) { case 1: // Disconnected due to Server or Network - may reconnect mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Disconnected due to server or network problem")); break; case 2: // Normal connection mxSetFieldByNumber(plhs[0],0,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[Hndl-1].CHID)])); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("connected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Normal connection")); break; case 3: // Disconnected by user mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Permanently disconnected (cleared) by the user")); break; }; break; case 12: // MCASTATE return an array of status (1 - OK, 0 - disconnected or cleared) if(HandlesUsed>0) { plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<HandlesUsed;i++) myDblPr[i] = (double)(ca_state(CHNLS[i].CHID)==2); } else { mexWarnMsgTxt("No connected PV's found"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } break; case 30: // poll ca_poll(); break; case 50: // MCAGET Get PV values by their MCA handles for(i=0;i<nrhs-1;i++) // First loop: place all ca_get requests in the buffer { Hndl = (int)mxGetScalar(prhs[1+i]); //start from[1]: [0] argument is the commnads switch if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); status = ca_array_get(RequestType,Cnt,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer); if(status!=ECA_NORMAL) mexPrintf("Error in call to ca_array_get\n"); } status = ca_pend_io(MCA_GET_TIMEOUT); if(status!=ECA_NORMAL) mexErrMsgTxt("... ca_pend_io call timed out \n"); for(i=0;i<nrhs-1;i++) // Another loop to copy data from temp structures to MATLAB { Hndl = (int)mxGetScalar(prhs[1+i]); RequestType = RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); if(RequestType==DBR_STRING) { if(Cnt==1) plhs[i] = mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)))); else { plhs[i] = mxCreateCellMatrix(1,Cnt); for(j=0;j<Cnt;j++) mxSetCell(plhs[i], j, mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+j)))); } } else { plhs[i] = mxCreateDoubleMatrix(1,Cnt,mxREAL); myDblPr = mxGetPr(plhs[i]); switch(dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID))) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_FLOAT: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_ENUM: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_CHAR: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_LONG: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_DOUBLE: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; } } } break; case 51: // MCAGET Get scalar PV of the same type // second argument is an array of handles // returns an array of values myDblPr = mxGetPr(prhs[1]); M = mxGetM(prhs[1]); N = mxGetN(prhs[1]); NumHandles = M*N; plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL); for(i=0;i<NumHandles;i++) // First loop: place all ca_get requests in the buffer { Hndl = (int)myDblPr[i]; if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); status = ca_array_get(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(plhs[0])+i); if(status!=ECA_NORMAL) mexPrintf("Error in call to ca_array_get\n"); } status = ca_pend_io(MCA_GET_TIMEOUT); if(status!=ECA_NORMAL) mexErrMsgTxt("... ca_pend_io call timed out \n"); break; case 70: // MCAPUT NumHandles = (nrhs-1)/2; for(i=0;i<NumHandles;i++) { j = 2+i*2; Hndl = (int)mxGetScalar(prhs[1+i*2]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range - no values written"); // Set the status to 0 - mcaput_callback will write 1, if successful CHNLS[Hndl-1].LastPutStatus = 0; RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); // If a value to write is passed as a string - the number of elements to write // is 1 , NOT the length of the string returned by mxGetNumberOfElements if(mxIsChar(prhs[j])) L=1; else L = min(mxGetNumberOfElements(prhs[j]),Cnt); // Copy double or string data from MATLAB prhs[] to DataBuffer // on each channel if(RequestType==DBR_STRING) { // STRING type is is passed as a cell array of strings // A a 1-row MATLAB character array (1 string) may also be passed as a value if(mxIsChar(prhs[j])) { mxGetString(prhs[j], StrBuffer, sizeof(dbr_string_t)); strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))),StrBuffer); } else if(mxIsCell(prhs[j])) { for(k=0;k<L;k++) { mxGetString(mxGetCell(prhs[j],k), StrBuffer, sizeof(dbr_string_t)); strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+k)),StrBuffer); } } } else { myDblPr = mxGetPr(prhs[j]); switch(RequestType) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for(k=0;k<L;k++) *((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_short_t)(myDblPr[k]); break; case DBR_FLOAT: for(k=0;k<L;k++) *((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_float_t)(myDblPr[k]); break; case DBR_ENUM: for(k=0;k<L;k++) *((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_enum_t)(myDblPr[k]); break; case DBR_CHAR: for(k=0;k<L;k++) *((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_char_t)(myDblPr[k]); break; case DBR_LONG: for(k=0;k<L;k++) *((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_long_t)(myDblPr[k]); break; case DBR_DOUBLE: for(k=0;k<L;k++) *((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_double_t)(myDblPr[k]); break; } } // place request in the que status = ca_array_put_callback(RequestType,L,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer, mcaput_callback,&(CHNLS[Hndl-1].LastPutStatus)); if(status!=ECA_NORMAL) mexPrintf("ca_array_put_callback failed\n"); } status = ca_pend_event(MCA_PUT_TIMEOUT); plhs[0]=mxCreateDoubleMatrix(1,NumHandles,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<NumHandles;i++) { Hndl = (int)mxGetScalar(prhs[1+i*2]); myDblPr[i] = (double)CHNLS[Hndl-1].LastPutStatus; } break; case 80: // MCAPUT - fast unconfirmed put for scalar numeric PV's myDblPr = mxGetPr(prhs[1]); M = mxGetM(prhs[1]); N = mxGetN(prhs[1]); NumHandles = M*N; plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<NumHandles;i++) { myDblPr = mxGetPr(plhs[0]); Hndl = (int)(*(mxGetPr(prhs[1])+i)); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range - no values written"); status = ca_array_put(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(prhs[2])+i); if(status!=ECA_NORMAL) { myDblPr[i] = 0; //mexPrintf("ca_array_put_callback failed\n"); } else { myDblPr[i] = 1; } } status = ca_pend_io(MCA_PUT_TIMEOUT); break; case 100: // MCAMON install Monitor or replace MonitorCBString Hndl = (int)mxGetScalar(prhs[1]); // Check if the handle is within range if(Hndl<1 || Hndl>HandlesUsed) { plhs[0]=mxCreateScalarDouble(0); mexErrMsgTxt("Invalid Handle"); } if(CHNLS[Hndl-1].EVID) // if VID is not NULL - another monitor is already installed - replace MonitorCBString { if(CHNLS[Hndl-1].MonitorCBString) // Free memory for occupied by the old MonitorCBString { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString = NULL; } if(nrhs>2) // Check if the new string is specified { if(mxIsChar(prhs[2])) { buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1; CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen); mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString); mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); } else mexErrMsgTxt("Third argument must be a string\n"); } plhs[0]=mxCreateScalarDouble(1); } else // No monitor is presently installed; { RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); // Closest to the native if(nrhs>2) { if(mxIsChar(prhs[2])) { buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1; CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen); mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString); mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); } else mexErrMsgTxt("Third argument must be a string\n"); } else CHNLS[Hndl-1].MonitorCBString = NULL; // Set MonitorCBString to NULL so that mcaMonitorEventHandler only copies data to CACHE // Count argument set to 0 - native count status = ca_add_array_event(RequestType,0,CHNLS[Hndl-1].CHID, mcaMonitorEventHandler, &CHNLS[Hndl-1], 0.0, 0.0, 0.0, &(CHNLS[Hndl-1].EVID)); if(status!=ECA_NORMAL) { mexPrintf("ca_add_array_event failed\n"); plhs[0]=mxCreateScalarDouble(0); } else { ca_poll(); plhs[0]=mxCreateScalarDouble(1); } } break; case 200: // Clear Monitor MCACLEARMON Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); if(!CHNLS[Hndl-1].EVID) mexErrMsgTxt("No monitor installed - can not clear"); status = ca_clear_event(CHNLS[Hndl-1].EVID); if(status!=ECA_NORMAL) mexPrintf("ca_clear_event failed\n"); // Set the EVID pointer to NULL (ca_clear_event dos not do it by itself) // to use as a FLAG that no monitors are installed CHNLS[Hndl-1].EVID = NULL; // Reset CHNLS[Hndl-1].MonitorEventCount = 0; // If there is Callback String - destroy it if(CHNLS[Hndl-1].MonitorCBString) { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString =NULL; } break; case 300: // MCACACHE Get Cached values of a monitored PV for(i=0;i<nrhs-1;i++) { Hndl = (int)mxGetScalar(prhs[1+i]); // if(Hndl<1 || Hndl>HandlesUsed || !CHNLS[Hndl-1].CACHE) if(Hndl<1 || Hndl>HandlesUsed) plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL); else { plhs[i] = mxDuplicateArray(CHNLS[Hndl-1].CACHE); CHNLS[Hndl-1].MonitorEventCount = 0; } } break; case 500: // MCAMON Info on installed monitors L = 0; HndlArray = (int*)mxCalloc(HandlesUsed,sizeof(int)); for(i=0;i<HandlesUsed;i++) // Count installed monitors { if(CHNLS[i].EVID) HndlArray[L++]=i+1; } if(L>0) { plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL); myDblPr = mxGetPr(plhs[0]); plhs[1] = mxCreateCellMatrix(1,L); for(i=0;i<L;i++) { myDblPr[i] = (double)HndlArray[i]; mxSetCell(plhs[1],i,mxCreateString(CHNLS[HndlArray[i]-1].MonitorCBString)); } } else { plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); plhs[1] = mxCreateCellMatrix(0,0); } break; case 510: // MCAMONEVENTS Event count fot monitors plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<HandlesUsed;i++) myDblPr[i]=(double)(CHNLS[i].MonitorEventCount); break; case 1000: // print timeout settings plhs[0] = mxCreateDoubleMatrix(3,1,mxREAL); mexPrintf("MCA timeout settings\n:"); mexPrintf("mcaopen\t%f [s]\n", MCA_SEARCH_TIMEOUT ); mexPrintf("mcaget\t%f [s]\n", MCA_GET_TIMEOUT ); mexPrintf("mcaput\t%f [s]\n", MCA_PUT_TIMEOUT ); myDblPr = mxGetPr(plhs[0]); myDblPr[0] = MCA_SEARCH_TIMEOUT; myDblPr[1] = MCA_GET_TIMEOUT; myDblPr[2] = MCA_PUT_TIMEOUT; break; case 1001: // set MCA_SEARCH_TIMEOUT // return delay value MCA_SEARCH_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_SEARCH_TIMEOUT); break; case 1002: // set MCA_GET_TIMEOUT // return delay value MCA_GET_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_GET_TIMEOUT); break; case 1003: // set MCA_PUT_TIMEOUT // return delay value MCA_PUT_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_PUT_TIMEOUT); break; } }
void PPDEVOpen(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int result, addrStrLen; uint64_T port; char *addrStr; pp_device *newdev = NULL; /* The device number must be noncomplex scalar double */ /* if (nrhs != 1 || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !mxIsScalar(prhs[0])) { */ if (nrhs != 1 || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mxGetN(prhs[0])==1 && mxGetM(prhs[0])==1)) { mexErrMsgTxt("Port number must be noncomplex scalar double."); } /* Assign pointers to each input */ port = *mxGetPr(prhs[0]); if (port < 1 || port > MAX_DEVS) { mexErrMsgTxt("Port number out of range."); } port--; /* Convert port number to string file name */ addrStrLen = strlen(ADDR_BASE) + (port == 0 ? 1 : 1 + floor(log10(port))); /* number digits in port */ addrStr = (char *)mxMalloc(addrStrLen + 1); if (addrStr == NULL) { mexErrMsgTxt("couldn't allocate addrStr"); } mexMakeMemoryPersistent(addrStr); /* result = snprintf(addrStr,addrStrLen+1,"%s%" FMT64 "u",ADDR_BASE,port); /* +1 for null terminator */ result = snprintf(addrStr,addrStrLen+1,"%s%lu",ADDR_BASE,port); /* +1 for null terminator */ if (result != addrStrLen) { printf("%d\t%d\t%s\n",result,addrStrLen,addrStr); mexErrMsgTxt("bad addrStr snprintf"); } if (DEBUG) printf("%d\t%s.\n",addrStrLen,addrStr); /* Allocate memory for new port device */ newdev = (pp_device *)mxMalloc(sizeof(pp_device)); mexMakeMemoryPersistent(newdev); if (newdev != NULL) { mexAtExit(PPDEVCloseAll); newdev->addr = addrStr; /* Open port and get file descriptor */ newdev->parportfd = open(newdev->addr, O_RDWR); if (newdev->parportfd == -1) { printf("%s %s\n",newdev->addr,strerror(errno)); mexErrMsgTxt("couldn't access port"); } /*bug: if the following error out, we won't close parportfd or free addrStr -- need some exceptionish error handling * AW: We can close port and free memory in PPDEVCLose(All). Solved? /* PPEXCL call succeeds, but causes following calls to fail * then dmesg has: parport0: cannot grant exclusive access for device ppdev0 * ppdev0: failed to register device! * * web search suggests this is because lp is loaded -- implications of removing it? * AW: Did not notice any side effects yet */ /* We want exclusive access for triggering */ ppd(newdev->parportfd,PPEXCL,NULL,"couldn't get exclusive access to pport"); /* Claim port and set byte mode */ ppd(newdev->parportfd,PPCLAIM,NULL,"couldn't claim pport"); int mode = IEEE1284_MODE_BYTE; /* or would we want COMPAT? */ ppd(newdev->parportfd,PPSETMODE,&mode,"couldn't set byte mode"); newdev->claimed = true; ppdev_table[0] = newdev; } else { mexErrMsgTxt("Could not allocate memory for new device"); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Variable declarations here */ double pose_distance_x_t; /* pose_distance */ double pose_distance_y_t; /* pose_distance */ double pose_distance_th_t; /* pose_distance */ double wheel_distance_t; /* wheel_distance */ mwSize encoder_ticks_t; /* encoder_ticks */ double wheel_radius_t; /* wheel_radius */ double *dtick_L_t; /* output scalar */ double *dtick_R_t; /* output scalar */ /* Code here */ /* Check for parameters */ if(nrhs!=6){ mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Sixteen inputs required."); } /* if(nlhs!=2){ mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "Two outputs required."); }*/ pose_distance_x_t = mxGetScalar(prhs[0]); pose_distance_y_t = mxGetScalar(prhs[1]); pose_distance_th_t = mxGetScalar(prhs[2]); wheel_distance_t = mxGetScalar(prhs[3]); encoder_ticks_t = mxGetScalar(prhs[4]); wheel_radius_t = mxGetScalar(prhs[5]); if (angL==NULL) { /* since angL is initialized to NULL, we know this is the first call of the MEX-function after it was loaded. Therefore, we should set up angL and the exit function. */ /* Allocate array. Use mexMackMemoryPersistent to make the allocated memory persistent in subsequent calls*/ mexPrintf("First call to MEX-file\n"); angL = mxCalloc(1,8); angR = mxCalloc(1,8); mexMakeMemoryPersistent(angL); mexMakeMemoryPersistent(angR); mexAtExit(exitFcn); } /* mexPrintf("Old string was '%f' and '%f'.\n",angL[0], angR[0]); */ pr_angL = mxGetPr(prhs[0]); pr_angR = mxGetPr(prhs[1]); /* mexPrintf("New string is '%f' and '%f'.\n",pr_angL[0], pr_angR[0]); */ mexPrintf("--------------First angL and angR: '%f' and '%f'.\n",pr_angL[0], pr_angR[0]); /* Create the output vector */ plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL); /* Get pointer to the real data in the output scalar */ dtick_L_t = mxGetPr(plhs[0]); dtick_R_t = mxGetPr(plhs[1]); /* Call the computational routine */ mexEncoder(pose_distance_x_t,pose_distance_y_t,pose_distance_th_t,wheel_distance_t,encoder_ticks_t,wheel_radius_t, dtick_L_t, dtick_R_t); }