diff --git a/RHEL7-x86_64/2018a/macchinettaSwitch.o b/RHEL7-x86_64/2018a/macchinettaSwitch.o new file mode 100644 index 0000000..56d380e Binary files /dev/null and b/RHEL7-x86_64/2018a/macchinettaSwitch.o differ diff --git a/RHEL7-x86_64/2018a/mocha.mexa64 b/RHEL7-x86_64/2018a/mocha.mexa64 new file mode 100755 index 0000000..6f14d6b Binary files /dev/null and b/RHEL7-x86_64/2018a/mocha.mexa64 differ diff --git a/exampleNew.m b/exampleNew.m index c2f09c3..7cece65 100644 --- a/exampleNew.m +++ b/exampleNew.m @@ -38,7 +38,7 @@ % To run this test script, first create 5 soft channels of the given class. % pv(1:2) are scalar numerics, pv(3) is a wf, pv(4) is a mbbo record (enum), % pv(5) is a dbr_string_t, pv(6) does not exist -pv={'ARIDI-BPM-01LE:X-AVG','ARIDI-BPM-01LE:Y-AVG','ARIDI-BPM-01LE:WF-INT-2','caget','ARIDI-BPM-01LE:SET-ENABLE.DESC','PV-JOKE'}; +pv={'ARIDI-BPM-01LE:X-AVG','ARIDI-BPM-01LE:Y-AVG','ARIDI-BPM-01LE:WF-INT-2','ARIDI-BPM-01LE:SET-ENABLE','ARIDI-BPM-01LE:SET-ENABLE.DESC','PV-JOKE'}; % % MATLAB's Run and Advance utility will run each of these 17 sections at the user's prompt. @@ -92,10 +92,10 @@ disp('Section (1) Establishing connections to EPICS Process Variables (PVs) '); disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'); %returns an array of handles (object references) -hpv=mocha('open',pv); +%hpv=mocha('open',pv); %When executing the 'open' message as above, the default behaviour -%is for each 'open' to wait for a fixed amount of time, given by: +%is for each 'open' to wait for a maximum amount of time, given by: openTime = mocha ('getOpenWaitTime'); %currently 0.4s %The 'open' wait time can, however, be configured by the user as follows: mocha ('setOpenWaitTime', 0.2); %set to 0.2s @@ -108,7 +108,7 @@ mocha ('setOpenWaitTime'); %reset to default (0.4s) mocha('openPrepare'); hpv=mocha('open',pv); % and more mocha 'open' messages would follow here... -% Finally send the messages and wait for 0.2s for connections to complete +% Finally send the messages and wait for a maximum of 0.2s for connections to complete mocha('openNowAndWait', 0.2) %There are a number of ways to extract information on the created handles @@ -162,7 +162,7 @@ pvtable %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %(2) Simple single channel operations (and the PVData Object) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'); @@ -245,6 +245,8 @@ pvStruct.epicsTS; %[secPastEpoch, nsec] %END (2) Simple single channel operations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %(3) Understanding the Status Error Code / MATLAB Exceptions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -275,7 +277,7 @@ statusInfo = mocha ('statusInfo', status); %statusArray[2] returns same data as statusInfo above %Status code/name pairs can be listed as follows: -%disp('Listing all possible status code value/name pairs') +disp('Listing all possible status code value/name pairs') [strVal, intVal] = mocha('statusList'); %Alarm conditions and alarm severities can be listed as follows: @@ -467,6 +469,8 @@ disp('Section (8) Multiple Struct operations on several PVS returning PVData Obj disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'); %GET %returns a sequence of pvData structs +%% + [pvData, isAllOK] = mocha ('getPVArray', pv) disp('Display all pvData.val values and statuses:'); %pvData(i) corresponds to the data returned by pv(i) @@ -482,41 +486,52 @@ disp('Display all pvData.val values and statuses:'); %returns a sequence of extended (x) pvData structs -[pvStruct, isAllOK] = mocha ('getStructArray', pv) +%%[pvStruct, isAllOK] = mocha ('getStructArray', pv) %pvStruct(i) corresponds to the data returned by pv(i) -disp('Display all pvStruct as arrays:'); -[pvStruct.handle] -{pvStruct.pv} -{pvStruct.val} -[pvStruct.status] -{pvStruct.status_str} -[pvStruct.alarmStatus] -[pvStruct.alarmStatus_str] -[pvStruct.alarmSeverity] -{pvStruct.alarmSeverity_str} -pvStruct.ts -pvStruct.epicsTS -[pvStruct.alarmSeverity] -{pvStruct.alarmSeverity_str} +%%disp('Display all pvStruct as arrays:'); +%%[pvStruct.handle] +%%{pvStruct.pv} +%%{pvStruct.val} +%%[pvStruct.status] +%%{pvStruct.status_str} +%%[pvStruct.alarmStatus] +%%{pvStruct.alarmStatus_str} +%%[pvStruct.alarmSeverity] +%%{pvStruct.alarmSeverity_str} +%%pvStruct.ts +%%pvStruct.epicsTS +%%[pvStruct.alarmSeverity] +%%{pvStruct.alarmSeverity_str} %pvStruct(1:6).ts %timestamps %[pvStruct(1:6).alarmStatus] +%% %%%% %Note: the following method is equivelent to the above %as it will call getStructArray internally [pvStruct, isAllOK] = mocha ('getStruct', pv); - +%%%%%%%% disp('Alternatively part data (values, statuses only) could also be retrieved with getCellArray:'); +%% %%%% [val, isAllOK, s] = mocha ('getCellArray', hpv) +%%%%%%%%%%%%%% -%SET + + +%SET -overwrite pvData pvData(1).val =0.2345; pvData(2).val =2.6789; pvData(3).val =(256:512); pvData(4).val = 'off'; + +%%%%%% [isAllOK, s] = mocha ('set', hpv, pvData(1:6).val); +%%%%%%%%%%%%%%%%%%% + %Check values were set [val, isAllOK, s] = mocha ('getCellArray', hpv) +%%%%%%%%% + disp('Recall we had previously set an offset for wf of value:'); offset=mocha('getOffset',hpv(3)) disp('Setting new offset/nelem for wf has value:'); @@ -543,6 +558,8 @@ pvData(3).val %END (8) Multiple Struct operations on several PVS returning PVData Objects plus Multiple Sets for Scalars/Vectors %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %(9) Asynchronous interactions and retrieving data from Cache %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -708,7 +725,6 @@ disp('Show members of group gTest (as loaded from test.xml):'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %(11) Monitors, either with or without user supplied callbacks (in essence, matlab scripts) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -720,6 +736,8 @@ monitorID = mocha ('monitor', pv(1)); [monitorIDArray, isAllOK, statusArray] = mocha ('monitor', pv(1:6)); %start monitors for several pvs/handles %Once the monitor is started, data may be retrieved via one of the cache methods +pause(0.1) + [val,s] = mocha('getCache', pv(1)); %Scalar or vector returned in native data type [val,s] = mocha('getCache', pv(1), 'double'); %Scalar or vector returned as a MATLAB double [val,s] = mocha('getCache', pv(1), 'uint8'); %Scalar or vector returned as a MATLAB uint8 @@ -758,14 +776,14 @@ mocha('monitorFlushEvent', pv(1)); %will execute the MATLAB script monitorAction mocha('monitorFlushEvent'); %will execute all 'actions' for all 'handles' that have received new data %The above command is used in conjunction with MATLAB timer (as for MCA's mcamontimer.m) -obj.t = timer('TimerFcn', 'mocha(''monitorFlushEvent'')', 'Period', 1.0, 'ExecutionMode', 'fixedSpacing'); +obj.t = timer('TimerFcn', 'mocha(''monitorFlushEvent'')', 'Period', 2.0, 'ExecutionMode', 'fixedSpacing'); %Else if double quotes cannot be used in the above; here's a way around the problem: %obj.t = timer('TimerFcn', 'mocha(402)', 'Period', 2.0, 'ExecutionMode', 'fixedSpacing'); start(obj.t); disp ('Callback for monitors for 5 seconds') for n=1:5 mocha('set', pv(1), n); %See the script be executed - pause(1); + pause(0.5); end stop(obj.t); @@ -1040,8 +1058,7 @@ disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'); %Stops all monitors (if any) %Closes all channels %Releases all CA resources -mocha ('close'); - +mocha ('close') % %END (17) Gracefully terminate CAFE %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/macchinettaHelper.h b/macchinettaHelper.h index a41c9e2..0defcf0 100644 --- a/macchinettaHelper.h +++ b/macchinettaHelper.h @@ -1,4 +1,5 @@ #include +//include #include "macchinetta.h" #include "containerMochaccino.h" @@ -11,6 +12,7 @@ using namespace std; const unsigned short METHOD_NAME_MAX_SIZE=80; const unsigned short PVNAME_MAX_SIZE=80; +const unsigned short DBR_STRING_MAX_SIZE=40; const unsigned short MONITOR_ACTION_MAX_SIZE=255; const unsigned short ME_MESSAGE_MAX_SIZE=255; @@ -213,8 +215,8 @@ enum mochaIndex {SHOW=1, OPEN, OPEN_ARRAY, OPEN_WAIT, GET_OPEN_WAIT_TIME, SET_NELEM, SET_NELEM_CACHE, SET_OFFSET, GET_NELEM_CLIENT, GET_NELEM_NATIVE, GET_NELEM_REQUEST, GET_NELEM, GET_NELEM_CACHE, GET_OFFSET, - MONITOR=400, MONITOR_STOP, MONITOR_FLUSH_EVENT, - GET_MONITOR_HANDLES, GET_MONITOR_HANDLES_AND_ACTIONS, + MONITOR=400, MONITOR_STOP, MONITOR_FLUSH_EVENT, + GET_MONITOR_HANDLES, GET_MONITOR_HANDLES_AND_ACTIONS, GET_NO_MONITORS, IS_CONNECTED=500, ALL_CONNECTED, PRINT_STATUS=600, PRINT_MONITORS, PRINT_HANDLE, PRINT_HANDLES, PRINT_DISCONNECTED_HANDLES,GET_HANDLES,GET_HANDLE_STATES, @@ -397,10 +399,12 @@ void msInsert() ms.insert(mochaccino(GET_OFFSET, "getoffset")); + ms.insert(mochaccino(MONITOR, "monitorstart")); ms.insert(mochaccino(MONITOR, "monitor")); ms.insert(mochaccino(MONITOR_STOP, "monitorstop")); ms.insert(mochaccino(MONITOR_FLUSH_EVENT, "monitorflushevent")); - + + ms.insert(mochaccino(GET_NO_MONITORS, "getnomonitors")); ms.insert(mochaccino(GET_MONITOR_HANDLES, "getmonitorhandles")); ms.insert(mochaccino(GET_MONITOR_HANDLES_AND_ACTIONS, "getmonitorhandlesandactions")); @@ -456,6 +460,15 @@ void printStatus(int status ) } +void printStringInputError() +{ + mexPrintf("Error in intepreting pv in input argument:\n"); + mexPrintf("PV name does not have a char value \n"); + mexPrintf("MATLAB mx library does not support string/mxSTRING_CLASS as input\n"); + mexPrintf("Please use char/mxCHAR_CLASS as data type instead\n"); + mexPrintf("i.e., use single quotes instead of double quotes in input argument!\n"); +} + std::string prepareExceptionID(int status ) { std::string exID="CAFE_"; @@ -771,6 +784,56 @@ unsigned int getNObjectsFromDataCell(const mxArray * thisCell) } +char getEscapeSequence(char cNext, bool & recognizedFlag) { + char wfChar = cNext; + recognizedFlag = true; + + switch (cNext) { + case '0': + wfChar = '\0'; + break; + case '\'': + wfChar = '\''; + break; + case '"': + wfChar = '\"'; + break; + case '?': + wfChar = '\?'; + break; + case '\\': + wfChar = '\\'; + break; + case 'a': + wfChar = '\a'; + break; + case 'b': + wfChar = '\b'; + break; + case 'f': + wfChar = '\f'; + break; + case 'n': + wfChar = '\n'; + break; + case 'r': + wfChar = '\r'; + break; + case 't': + wfChar = '\t'; + break; + case 'v': + wfChar = '\v'; + break; + default: + // Unrecognized escape sequence; print slash + wfChar = '\\'; + recognizedFlag = false; + break; + } + + return wfChar; +} /* @@ -910,15 +973,93 @@ void cellToString(const mxArray * thisCell) break; case mxCHAR_CLASS: - ne=1; - dbr_string_t * strBuffer = new dbr_string_t[ne]; - mxGetString(newCell, *strBuffer, sizeof(dbr_string_t)*ne); - for (mwIndex j=0; j< ne; ++j ) - { - strcpy(inputStringCell[iWithinAllCells],strBuffer[j]); + unsigned int neLocal=1; + + if (ne > (DBR_STRING_MAX_SIZE-1)) { + mexPrintf("Exceeded (with %d) max limit of %d chars. Ignoring this element of cell\n", + ne, (DBR_STRING_MAX_SIZE-1)); + break; + } + + + dbr_string_t * strBuffer = new dbr_string_t[neLocal]; + mxGetString(newCell, *strBuffer, sizeof(dbr_string_t)*neLocal); + //mexPrintf("ne %d\n", ne); + //mexPrintf("strBuffer %d\n", *strBuffer[0]); + //mexPrintf("strBuffer %c \n", *strBuffer[0]); + char c = strBuffer[0][0]; + char cNext; + if (c == '\\' && ne > neLocal) { + + cNext = strBuffer[0][1]; + //mexPrintf("char cNext %c\n", cNext); + bool recognizedFlag = true; + + char cNew = NS_MOCHA::getEscapeSequence(cNext, recognizedFlag); + //Must loop over all ne! + for (unsigned int i=0; i < ne; ++i) { + strBuffer[0][i] = cNew; + } + /* Must loop over all ne + switch (cNext) { + case '0': + strBuffer[0][0] = '\0'; + break; + case '\'': + strBuffer[0][1] = '\''; + break; + case '"': + strBuffer[0][1] = '\"'; + break; + case '?': + strBuffer[0][1] = '\?'; + break; + case '\\': + strBuffer[0][1] = '\\'; + break; + case 'a': + strBuffer[0][1] = '\a'; + break; + case 'b': + strBuffer[0][1] = '\b'; + break; + case 'f': + strBuffer[0][1] = '\f'; + break; + case 'n': + //strBuffer[0][0] = '\n'; + for (unsigned int i=0; i < ne; ++i) { + strBuffer[0][i] = '\n'; + } + break; + case 'r': + strBuffer[0][1] = '\r'; + break; + case 't': + //strBuffer[0][0] = '\t'; + for (unsigned int i=0; i < ne; ++i) { + strBuffer[0][i] = '\t'; + } + break; + case 'v': + strBuffer[0][1] = '\v'; + break; + default: + // Unrecognized escape sequence; print slAH + strBuffer[0][1] = '\\'; + break; + } + */ + } + + + for (mwIndex j=0; j< neLocal; ++j ) + { + strcpy(inputStringCell[iWithinAllCells], strBuffer[j]); ++iWithinAllCells; } delete [] strBuffer; + break; } @@ -1188,6 +1329,7 @@ unsigned int checkForHandleNoOpen(const mxArray * inputValue) if (mxIsNumeric(inputValue) ) { _handle = (uint32_T) mxGetScalar(inputValue); + } else if (mxIsChar(inputValue) ) @@ -1206,6 +1348,8 @@ unsigned int checkForHandleNoOpen(const mxArray * inputValue) } } + + else if (mxIsCell(inputValue) ) { @@ -1231,8 +1375,21 @@ unsigned int checkForHandleNoOpen(const mxArray * inputValue) mexPrintf("PV=%s has not yet been opened by user!\n", pv ); } } + + else if (strcmp (mxGetClassName(newCell),"string") ==0 ) { + printStringInputError(); + return _handle;; + } + } + else if (strcmp (mxGetClassName(inputValue),"string") ==0 ) { + printStringInputError(); + return _handle;; + } + + + else { mexPrintf("Error in checkForHandleNoOpen:\n"); @@ -1248,6 +1405,8 @@ unsigned int checkForHandle(const mxArray * inputValue) { unsigned int _handle=0; + + if (mxIsNumeric(inputValue) ) { @@ -1297,7 +1456,20 @@ unsigned int checkForHandle(const mxArray * inputValue) _handle=open(pv); } } + + else if (strcmp (mxGetClassName(newCell),"string") ==0 ) { + printStringInputError(); + return _handle;; + } + } + + + else if (strcmp (mxGetClassName(inputValue),"string") ==0 ) { + printStringInputError(); + return _handle;; + } + else { mexPrintf("Error in checkForHandle:\n"); @@ -1305,9 +1477,11 @@ unsigned int checkForHandle(const mxArray * inputValue) mexPrintf("or PV name does not have a char value \n"); return _handle; } - if (_handle==0) + if (_handle<1) { mexPrintf("Handle in input argument not given! \n"); + mexPrintf("Handle should be a positive integer. \n"); + mexPrintf("Alternatively enter the pv name in single quotes\n"); } return _handle; } diff --git a/macchinettaSwitch.cpp b/macchinettaSwitch.cpp index 512d5d2..a4ae28d 100644 --- a/macchinettaSwitch.cpp +++ b/macchinettaSwitch.cpp @@ -12,7 +12,6 @@ //#include //#endif - extern void _main(); using namespace NS_MOCHA; @@ -43,33 +42,31 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh mexPrintf("Please use the method name (MATLAB char) as input to the first argument. \n"); mexPrintf("The command: mocha \'show\' will display the methods available. \n"); - mexPrintf("1st input argument Class Name: %s\n", mxGetClassName(prhs[0])); - mexPrintf("1st input argument Class ID: %d\n", mxGetClassID(prhs[0])); - mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n"); + //mexPrintf("1st input argument given has Class Name: %s\n", mxGetClassName(prhs[0])); + //mexPrintf("1st input argument given has Class ID: %d\n", mxGetClassID(prhs[0])); + //mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n"); return; } } - - - /* + + if (strcmp (mxGetClassName(prhs[0]),"string") ==0 ) { - mxChar * mess2 = static_cast(mxGetData(prhs[0])); - mData = (mxArray *) mess2; - messLength = METHOD_NAME_MAX_SIZE+1; + //mxChar * mess2 = static_cast(mxGetData(prhs[0])); + //mData = (mxArray *) mess2; + //messLength = METHOD_NAME_MAX_SIZE+1; - if ( mxGetString(mData, mess, messLength) == 1) { - mexPrintf ("mxGetString has failed; input is not of mxChar type\n"); - } + //if ( mxGetString(mData, mess, messLength) == 1) { + // mexPrintf ("mxGetString has failed; input is not of mxChar type\n"); + //} - mexPrintf ("mocha does not support string/mxSTRING_CLASS as input\n"); - mexPrintf ("Please use char/mxCHAR_CLASS as data type for input\n"); + mexPrintf ("MATLAB mx library does not support string/mxSTRING_CLASS as input\n"); + mexPrintf ("Please use char/mxCHAR_CLASS as data type instead\n"); + mexPrintf("i.e., use single quotes instead of double quotes in input argument!\n"); return; - } - else { - */ + } //message //Trick to handle mocha(402) input from monitor Action @@ -77,14 +74,32 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh messLength = METHOD_NAME_MAX_SIZE+1; if (mxIsChar(prhs[0]) ) { - mData = (mxArray *) prhs[0]; + mData = (mxArray *) prhs[0]; mxGetString(mData, mess, messLength); } + else if (!strcmp(mxGetClassName(prhs[0]), "string") ) + { + + mexPrintf("1st input argument given has Class Name: %s\n", mxGetClassName(prhs[0])); + mexPrintf("1st input argument given has Class ID: %d\n", mxGetClassID(prhs[0])); + mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n"); + mexPrintf("Please use single quotes instead of double quotes in input argument!\n"); + + return; + } else if (mochaIndex ==MONITOR_FLUSH_EVENT) { strcpy(mess,"monitorflushevent"); } + else + { + mexPrintf("1st input argument given has Class Name: %s\n", mxGetClassName(prhs[0])); + mexPrintf("1st input argument given has Class ID: %d\n", mxGetClassID(prhs[0])); + mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n"); + return; + } + char messOriginal[METHOD_NAME_MAX_SIZE+1]; strcpy(messOriginal,mess); @@ -167,6 +182,7 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh //mexPrintf("message %s\n", mess); //mexPrintf("message %s\n", messString.c_str()); + it_name = name_index.find(mess); @@ -325,14 +341,12 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh case SET: - if (nrhs<3) { mexPrintf("Invalid Number of argument %d. Input: 'set', handle/pv, data \n", nrhs); return; } - if (mxIsChar(prhs[1])) { nh=1; @@ -421,9 +435,7 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh } else { - nh=mxGetNumberOfElements (prhs[1]); - } ///mexPrintf("nh=%d, nargin=%d\n", nh, nrhs); @@ -489,7 +501,7 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh break; case MOCHA_VERSION: - plhs[0]=mxCreateString((char *) "mocha-1.8.0 : 14 December 2018"); + plhs[0]=mxCreateString((char *) "mocha-1.12.5 (Qt5 compatible) : 15 March 2021"); break; case SHOW: @@ -1044,8 +1056,9 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh xData = (mxArray *) prhs[1]; pvLength = PVNAME_MAX_SIZE+1; mxGetString(xData, pv, pvLength); - + handle=NS_MOCHA::open(pv); + //return handle //plhs[0] = mxCreateDoubleScalar(handle); @@ -1351,7 +1364,6 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh (du[j].getPVName(),pvgroup.getGroupHandle()); - //Match INPUT to CAFE DATATYPE if (mdtIndexOriginal==MOCHA_NATIVE) { @@ -2599,19 +2611,14 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh case GET: { - - if (nrhs<2) { mexPrintf("Invalid Number of argument %d. Input: message, handle/pv \n", nrhs); return; } - - handle=checkForHandle(prhs[1]); - if(handle==0) { mexPrintf("Handle does not exist!\n"); @@ -2640,11 +2647,8 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh if (mdtIndex==MOCHA_NATIVE) { - - status=cafe.getHandleHelper().getDataTypeRequest(handle, rdt); - if (status!=ICAFE_NORMAL) { mexPrintf("Error for handle input= %d \n", (uint32_T) mxGetScalar(prhs[1]) ); @@ -2657,14 +2661,11 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh CAFE_DATATYPE cdt = (CAFE_DATATYPE) rdt; - mdtIndex=getMdtIndexFromCafeDataType(cdt); - if (cafe.getHandleHelper().isEnum(handle)) { - mdtIndex=MOCHA_STRING; } } @@ -2672,7 +2673,6 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh nelem = cafe.getHandleHelper().getNelemClient(handle); //Change Request to Client - if (cafe.getHandleHelper().getOffset(handle) > 0 ) { @@ -2697,12 +2697,10 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh //mexPrintf("get Cache: nelem = %d \n", nelem); - if ( (cafe.getHandleHelper().getOffsetLast(handle) > 0) || (cafe.getHandleHelper().getNelemToRetrieveFromCache(handle) > cafe.getHandleHelper().getNelemRequest(handle))) { - //if (nelem > cafe.getHandleHelper().getNelemRequest(handle) ) { nelemPrevious=cafe.getHandleHelper().getNelemToRetrieveFromCache(handle); nelem = min( (unsigned int) nelem, cafe.getHandleHelper().getNelemRequest(handle)-cafe.getHandleHelper().getOffsetLast(handle)); @@ -2716,6 +2714,14 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh } + //special case for wf with dbr_char_t + ChannelRegalia channelInfo; + status=cafe.getChannelInfo(handle, channelInfo); + unsigned int WFWithString = 0; + if (channelInfo.getClassNameAsString().compare("waveform") ==0) { + WFWithString = 1; + } + switch (mdtIndex) { case MOCHA_DOUBLE: @@ -2786,57 +2792,91 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh break; case MOCHA_UCHAR: - plhs[0] = mxCreateNumericMatrix(1,nelem,mxUINT8_CLASS, mxREAL); - ucharArray = (uint8_T *) mxGetData (plhs[0]); - if(cacheFlag) - { - status=cafe.getCache(handle,ucharArray); - } - else - { - status=cafe.get(handle,ucharArray); - } + + //special case for wf with dbr_char_t + /* + if (WFWithString == 1) { + + string wfStr; + + if (cacheFlag) + { + status=cafe.getWFAsStringCache(handle,wfStr); + } + else + { + status=cafe.getWFAsString(handle,wfStr); + } + + plhs[0] = mxCreateString( wfStr.c_str() ); + } + else { + */ + plhs[0] = mxCreateNumericMatrix(1,nelem,mxUINT8_CLASS, mxREAL); + ucharArray = (uint8_T *) mxGetData (plhs[0]); + if(cacheFlag) + { + status=cafe.getCache(handle,ucharArray); + } + else + { + status=cafe.get(handle,ucharArray); + } + //} break; case MOCHA_STRING: { - dbr_string_t * stringArrayc = new dbr_string_t[nelem]; - if(cacheFlag) - { - status=cafe.getCache(handle,stringArrayc); - } - else - { - status=cafe.get(handle,stringArrayc); - } + if (WFWithString ==1) { - //char *test[40]; - //test[0]="test"; - //test[1]="again"; - //mxChar *pr; - //char *ptr_to_seed_data; - //int c; + string wfStr; - - if (status==ICAFE_NORMAL) - { - - if (nelem==1) + if (cacheFlag) { - plhs[0]=mxCreateString( stringArrayc[0] ); + status=cafe.getWFAsStringCache(handle,wfStr); } else { - plhs[0] = mxCreateCellMatrix(1,nelem); - for (mwSignedIndex i=0; i 2) + { + mexPrintf("Ignoring arguments after the 2nd from the %d entered. Input: 'getNoMonitors', handle/pv \n", nrhs); + } + + handle=checkForHandle(prhs[1]); + if(handle==0) + { + return; + } + + + unsigned int nm; + nm=cafe.getHandleHelper().getNmonitor(handle); + + //number of monitors for this handle + plhs[0] = mxCreateNumericMatrix(1,1,mxUINT32_CLASS,mxREAL); + ulongArray = (uint32_T *) mxGetData(plhs[0]); + + ulongArray[0]=nm; + + break; + } + case PRINT_MONITORS: { diff --git a/makefile b/makefile deleted file mode 100644 index 6e6952c..0000000 --- a/makefile +++ /dev/null @@ -1,135 +0,0 @@ -# -# Jan Chrin -# New Version: June 2016 -# -# makefile to build mocha mex file -# printenv | grep MATLAB to reveal your MATLAB Directory -# -# e.g. on sf-lc we have -# MATLAB=/afs/psi.ch/sys/linux/opt/matlab/2015a.x86_64 -# -# local executables are built in ./${EPICS_HOST_ARCH}/$(MVER) -# where the MATLAB version is grepped from $(MATLAB) - -MATLAB_ROOT=${MATLAB} -MATLAB_VERSION=$(notdir $(MATLAB_ROOT)) - -##### CHANGE AS APPROPRIATE ################# -#Mocha Version to install -MOCHA_VERSION=mocha-noqt-1.8.0-gcc-6.3.0 -#CAFE version to link to -CAFE_VERSION=cafe-noqt-1.8.0-gcc-6.3.0 - - -EPICS_BASE=${EPICS}/base -#CAFE project base -CAFE_BASE=/opt/gfa/cafe -CAFE_MOCHA_BASE=${CAFE_BASE}/mocha -CAFE_CPP_BASE=$(CAFE_BASE)/cpp/$(CAFE_VERSION) -BOOST_BASE=${CAFE_BASE}/boost/boost_1_61_0/include - - -INSTALL_MOCHA_LIBDIR= $(CAFE_MOCHA_BASE)/$(MOCHA_VERSION)/lib/$(MATLAB_VERSION) -############################################# - - -#First deteremine if we are on a 32/64 bit machine -#as mex file extensions are named differently -pattern64=x86_64 -pattern32=i386 - -PWD=$(shell pwd) - #hardware platform - HW=$(shell uname -i) - ifeq ($(pattern64),$(findstring $(pattern64), $(HW))) - MEXE=mexa64 - MATLAB_LIB = $(MATLAB_ROOT)/bin/glnxa64 - else - ifeq ($(pattern32),$(findstring $(pattern32), $(HW))) - MEXE=mexglx - MATLAB_LIB = $(MATLAB_ROOT)/bin/glnxa86 - endif - endif - - -INSTALL_PATH?=$(INSTALL_MOCHA_LIBDIR) -OBJ_DIR= ${EPICS_HOST_ARCH}/$(MATLAB_VERSION) - -INCLUDEPATH_MOCHA += -I$(MATLAB_ROOT)/extern/include \ - -I$(CAFE_CPP_BASE)/include -I./ \ - -I$(EPICS_BASE)/include -I$(EPICS_BASE)/include/os/Linux - - -INCLUDEPATH_MACHINETTA += $(INCLUDEPATH_MOCHA) -I$(BOOST_BASE) -I$(BOOST_BASE)/boost - - -LIB_DIR += \ - -L$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \ - -Wl,-rpath,$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \ - -L$(MATLAB_LIB) -Wl,-rpath,$(MATLAB_LIB) - - - -#-lboost_system -lboost_thread-mt -LIBS += -ldl -lca -lCom -lmx -lmex -lmat - -LIB_INSTALL = $(LIB_DIR) -L$(INSTALL_PATH) -Wl,-rpath,$(INSTALL_PATH) - -LIB_LOCAL = $(LIB_DIR) - -CPP_OBJS=../cpp/src/libs/cafe/$(CAFE_VERSION_M) - -#CAFE_OBJS_DIR = $(CPP_OBJS)/cafe.o $(CPP_OBJS)/cafeCache.o $(CPP_OBJS)/cafeGroup.o $(CPP_OBJS)/cafeVectors.o \ -# $(CPP_OBJS)/cafeXML.o $(CPP_OBJS)/callbackHandlerCreate.o $(CPP_OBJS)/callbackHandlerMonitor.o \ -# $(CPP_OBJS)/conduitGroup.o $(CPP_OBJS)/conduit.o \ -# $(CPP_OBJS)/connectCallbacks.o $(CPP_OBJS)/connectGroup.o \ -# $(CPP_OBJS)/connect.o $(CPP_OBJS)/exceptionsHelper.o $(CPP_OBJS)/granules.o $(CPP_OBJS)/handleHelper.o \ -# $(CPP_OBJS)/helper.o \ -# $(CPP_OBJS)/loadCollectionXMLParser.o $(CPP_OBJS)/loadGroupXMLParser.o $(CPP_OBJS)/methodCallbacks.o \ -# $(CPP_OBJS)/policyHelper.o \ -# $(CPP_OBJS)/restorePVGroupXMLParser.o $(CPP_OBJS)/transpose.o - - -CAFE_OBJS_DIR = $(CAFE_BASE)/cpp/$(CAFE_VERSION)/lib/libcafe.a - -# MATLAB Versions 2014 onwards, use -# LDFLAGS='$(LIB_LOCAL) $(LIBS) instead of $(LIB_LOCAL) $(LIBS) -# LDFLAGS='$(LIB_LOCAL) $(LIBS) instead of $(LIB_INSTALL) $(LIBS) - - -$(OBJ_DIR)/mocha.$(MEXE): mocha.cpp $(OBJ_DIR)/macchinettaSwitch.o - mex -largeArrayDims CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread' \ - mocha.cpp $(OBJ_DIR)/macchinettaSwitch.o $(CAFE_OBJS_DIR) -outdir $(OBJ_DIR) -output mocha.$(MEXE) \ - $(INCLUDEPATH_MOCHA) \ - LDFLAGS='$(LIB_LOCAL) $(LIBS)' - - - -#$(OBJ_DIR)/libmacchinetta.so: $(OBJ_DIR)/macchinettaSwitch.o -# g++ -shared -Wl,-soname,libmacchinetta.so \ -# $(OBJ_DIR)/macchinettaSwitch.o -o $(OBJ_DIR)/libmacchinetta.so - - -$(OBJ_DIR)/macchinettaSwitch.o: macchinettaSwitch.cpp macchinettaHelper.h \ - macchinetta.h containerMochaccino.h - mex CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread' \ - -c macchinettaSwitch.cpp $(INCLUDEPATH_MACHINETTA) -outdir $(OBJ_DIR) - -install: $(OBJ_DIR)/mocha.$(MEXE) - mkdir -p $(INSTALL_PATH) - mex CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread' \ - mocha.cpp $(OBJ_DIR)/macchinettaSwitch.o $(CAFE_OBJS_DIR) -outdir $(INSTALL_PATH) -output mocha.$(MEXE) \ - $(INCLUDEPATH_MOCHA) \ - LDFLAGS='$(LIB_INSTALL) $(LIBS)' - cp example.m $(INSTALL_PATH) - cp scripts/monitorAction.m $(INSTALL_PATH) - cp scripts/pvtable.m $(INSTALL_PATH) - cp scripts/test.xml $(INSTALL_PATH) - -install_lib: $(OBJ_DIR)/libmacchinetta.so - mkdir -p $(INSTALL_PATH) - cp $(OBJ_DIR)/libmacchinetta.so $(INSTALL_PATH) - -clean: - rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.so $(OBJ_DIR)/*.$(MEXE) - diff --git a/makefile b/makefile new file mode 120000 index 0000000..84f8d55 --- /dev/null +++ b/makefile @@ -0,0 +1 @@ +makefile_rel_1.12-gcc-6.3.0 \ No newline at end of file