/* * Subsystem_psf.c * * Automatically generated s-function with I/O interface for: * Component: Subsystem * Component Simulink Path: Subsystem * */ #define S_FUNCTION_NAME Subsystem_psf #define S_FUNCTION_LEVEL 2 #if !defined(RTW_GENERATED_S_FUNCTION) #define RTW_GENERATED_S_FUNCTION #endif #include "simstruc.h" #include "fixedpoint.h" typedef struct { char * lib; double stationID; double recvTimeout; } rtIOStreamData; MdlRefChildMdlRec childModels[1] = { "Subsystem","Subsystem",0, (NULL)}; /* This function checks the attributes of tunable parameters. */ #define MDL_CHECK_PARAMETERS #if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE) static void mdlCheckParameters(SimStruct *S) { } #endif /* MDL_CHECK_PARAMETERS */ static char * getSimulinkBlockPath(SimStruct *S) { char * simulinkBlockPath = NULL; const char * origBlockPath = ssGetPath(S); const char * searchString = "TmpSFcnForModelReference_"; char * searchPtr; size_t origLength, searchAndNameLength, copyAmount; char * secondPart; size_t nameLength; origLength = strlen(origBlockPath); searchPtr = strstr(origBlockPath, searchString); if (searchPtr == NULL) { return simulinkBlockPath; } searchAndNameLength = strlen(searchPtr); copyAmount = origLength - searchAndNameLength; simulinkBlockPath = (char *) mxCalloc((mwSize) (origLength + 1), sizeof(char)); simulinkBlockPath = strncpy(simulinkBlockPath, origBlockPath, copyAmount); simulinkBlockPath[copyAmount] = '\0'; nameLength = searchAndNameLength - strlen(searchString); secondPart = &simulinkBlockPath[copyAmount]; secondPart = strncpy(secondPart, &origBlockPath[origLength - nameLength], nameLength); secondPart[nameLength] = '\0'; return simulinkBlockPath; } static void mdlInitializeSizes(SimStruct *S) { ssSetNumSFcnParams(S, 0); /* Number of expected parameters */ if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) { #if defined(MDL_CHECK_PARAMETERS) mdlCheckParameters(S); #endif if (ssGetErrorStatus(S) != (NULL)) return; } else { /* Parameter mismatch will be reported by Simulink */ return; } ssSetNumContStates(S, 0); ssSetNumDiscStates(S, 0); /* no support for SimState */ ssSetSimStateCompliance(S, DISALLOW_SIM_STATE); /* Allow signal dimensions greater than 2 */ ssAllowSignalsWithMoreThan2D(S); { mxArray * lhs[1]; mxArray * error = NULL; char * installVersion; error = mexCallMATLABWithTrap(1, lhs, 0, NULL, "rtw.pil.SILPILInterface.getPILVersion"); if (error != NULL) { mxDestroyArray(error); ssSetErrorStatus(S, "Failed to determine the installed PIL version for comparison against the PIL s-function version (release 6.0 (R2011a)_2). To avoid this error, remove the PIL s-function from your MATLAB path (e.g. delete it or move to a clean working directory)."); return; } if (mxIsEmpty(lhs[0])) { ssSetErrorStatus(S, "rtw.pil.SILPILInterface.getPILVersion returned empty!"); return; } installVersion = mxArrayToString(lhs[0]); mxDestroyArray(lhs[0]); if (installVersion == NULL) { ssSetErrorStatus(S, "Failed to determine installed PIL version."); return; } if (strcmp(installVersion, "6.0 (R2011a)_2") != 0) { ssSetErrorStatus(S, "The PIL s-function is incompatible with the installed PIL version (see ver('ecoder')); it was generated for release 6.0 (R2011a)_2. To avoid this error, remove the PIL s-function from your MATLAB path (e.g. delete it or move to a clean working directory)."); return; } mxFree(installVersion); } if (S->mdlInfo->genericFcn != NULL) { _GenericFcn fcn = S->mdlInfo->genericFcn; (fcn)(S, GEN_FCN_CHK_MODELREF_SOLVER_TYPE_EARLY, 2, NULL); } ssSetRTWGeneratedSFcn(S, 2); if (!ssSetNumInputPorts(S, 1)) return; /* Input Port 0 */ /* contiguous inport */ ssSetInputPortRequiredContiguous(S, 0, 1); /* directfeedthrough */ ssSetInputPortDirectFeedThrough(S, 0, 1); if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) { DTypeId dataTypeId = INVALID_DTYPE_ID; /* set datatype */ dataTypeId = 0; ssSetInputPortDataType(S, 0, dataTypeId); } /* dimensions */ { DECL_AND_INIT_DIMSINFO(di); int_T dims[1]; di.numDims = 1; dims[0] = 1; di.dims = dims; di.width = 1; ssSetInputPortDimensionInfo(S, 0, &di); } /* complexity */ ssSetInputPortComplexSignal(S, 0, COMPLEX_NO); /* using port based sample times */ ssSetInputPortSampleTime(S, 0, 0.01); ssSetInputPortOffsetTime(S, 0, 0); /* sampling mode */ ssSetInputPortFrameData(S, 0, FRAME_NO); if (!ssSetNumOutputPorts(S, 1)) return; /* Output Port 0 */ if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) { DTypeId dataTypeId = INVALID_DTYPE_ID; /* set datatype */ dataTypeId = 0; ssSetOutputPortDataType(S, 0, dataTypeId); } /* dimensions */ { DECL_AND_INIT_DIMSINFO(di); int_T dims[1]; di.numDims = 1; dims[0] = 1; di.dims = dims; di.width = 1; ssSetOutputPortDimensionInfo(S, 0, &di); } /* complexity */ ssSetOutputPortComplexSignal(S, 0, COMPLEX_NO); /* using port based sample times */ ssSetOutputPortSampleTime(S, 0, 0.01); ssSetOutputPortOffsetTime(S, 0, 0); /* sampling mode */ ssSetOutputPortFrameData(S, 0, FRAME_NO); /* using port based sample times */ ssSetNumSampleTimes(S, PORT_BASED_SAMPLE_TIMES); ssSetNumPWork(S, 1); ssSetNumRWork(S, 0); ssSetNumIWork(S, 0); ssSetNumModes(S, 0); ssSetNumNonsampledZCs(S, 0); /* this s-function is sample time dependent: do not allow sub-models containing it to inherit sample times */ ssSetModelReferenceSampleTimeInheritanceRule(S, DISALLOW_SAMPLE_TIME_INHERITANCE); { uint_T options = 0; /* do not allow (including inheritance of) constant block-based sample times*/ options |= SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME; options |= SS_OPTION_SUPPORTS_ALIAS_DATA_TYPES; options |= SS_OPTION_CALL_TERMINATE_ON_EXIT; ssSetOptions(S, options); } ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK); { static ssRTWStorageType storageClass[2] = {SS_RTW_STORAGE_AUTO, SS_RTW_STORAGE_AUTO}; ssSetModelRefPortRTWStorageClasses(S, storageClass); } ssSetModelReferenceConsistentOutportInitialization(S, false); ssSetOptimizeModelRefInitCode(S, 1); if (S->mdlInfo->genericFcn != (NULL)) { ssRegModelRefChildModel(S,1,childModels); } ssSetModelRefSignalLoggingSaveFormat(S, SS_MODEL_DATA_LOGS); } #define MDL_SET_INPUT_PORT_SAMPLE_TIME /* Change to #undef to remove function */ #if defined(MDL_SET_INPUT_PORT_SAMPLE_TIME) && defined(MATLAB_MEX_FILE) static void mdlSetInputPortSampleTime(SimStruct *S, int_T portIdx, real_T sampleTime, real_T offsetTime) { /* sample times are fully specified, not inherited */ } #endif /* MDL_SET_INPUT_PORT_SAMPLE_TIME */ #define MDL_SET_OUTPUT_PORT_SAMPLE_TIME /* Change to #undef to remove function */ #if defined(MDL_SET_OUTPUT_PORT_SAMPLE_TIME) && defined(MATLAB_MEX_FILE) static void mdlSetOutputPortSampleTime(SimStruct *S, int_T portIdx, real_T sampleTime, real_T offsetTime) { /* sample times are fully specified, not inherited */ } #endif /* MDL_SET_OUTPUT_PORT_SAMPLE_TIME */ static void mdlInitializeSampleTimes(SimStruct *S) { /* using port based sample times */ } /* forward declaration for mdlProcessParameters */ #define MDL_PROCESS_PARAMETERS /* Change to #undef to remove function */ #if defined(MDL_PROCESS_PARAMETERS) static void mdlProcessParameters(SimStruct *S); #endif /* MDL_PROCESS_PARAMETERS */ #define MDL_START /* Change to #undef to remove function */ #if defined(MDL_START) static void mdlStart(SimStruct *S) { { mxArray *rhs[3]; mxArray *lhs[1]; char * rootLoggingPath; char * simulinkBlockPath = getSimulinkBlockPath(S); if (simulinkBlockPath == NULL) { ssSetErrorStatus(S, "ModelBlock PIL unexpected error: getSimulinkBlockPath returned NULL pointer. Check search string was found in ssGetPath.\n"); return; } rhs[0] = mxCreateLogicalScalar(1); rhs[1] = mxCreateString(simulinkBlockPath); rhs[2] = mxCreateString(ssGetPath(ssGetRootSS(S))); { int error = mexCallMATLAB(1, lhs, 3, rhs, "rtw.pil.SILPILInterface.sfunctionGatewayInitialize"); mxDestroyArray(rhs[0]); mxDestroyArray(rhs[1]); mxDestroyArray(rhs[2]); if (error) { ssSetErrorStatus(S, "Call to rtw.pil.SILPILInterface.sfunctionGatewayInitialize failed!"); return; } } rootLoggingPath = mxArrayToString(lhs[0]); mxDestroyArray(lhs[0]); mxFree((void *) simulinkBlockPath); mxFree(rootLoggingPath); } { mwSize mxInputDataDims[]={1, 5}; mxArray * dataOut = mxCreateNumericArray(2, mxInputDataDims, mxUINT8_CLASS, mxREAL); mxArray * dataInAmount = mxCreateDoubleScalar(1); mxArray * dataIn; uint8_T * mxMemUnitPtr = (uint8_T *) mxGetData(dataOut); mxArray * memUnitType = mxCreateString("uint8"); /* write command id */ *mxMemUnitPtr = 0; mxMemUnitPtr++; { uint8_T * simDataMemUnitPtr; uint32_T commandDataFcnid = 0; simDataMemUnitPtr = (uint8_T *) &commandDataFcnid; memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 4); mxMemUnitPtr = mxMemUnitPtr + 4; } { mxArray *rhs[6]; mxArray *lhs[1]; char * simulinkBlockPath = getSimulinkBlockPath(S); if (simulinkBlockPath == NULL) { ssSetErrorStatus(S, "ModelBlock PIL unexpected error: getSimulinkBlockPath returned NULL pointer. Check search string was found in ssGetPath.\n"); return; } rhs[0] = mxCreateLogicalScalar(1); rhs[1] = mxCreateString(simulinkBlockPath); rhs[2] = mxCreateString("PIL_INIT_COMMAND"); /* input data */ rhs[3] = dataOut; /* dataInAmount */ rhs[4] = dataInAmount; /* memUnitType */ rhs[5] = memUnitType; { int error = mexCallMATLAB(1, lhs, 6, rhs, "rtw.pil.SILPILInterface.sfunctionGateway"); { int i; for (i=0; i<6; i++) { mxDestroyArray(rhs[i]); } } if (error) { ssSetErrorStatus(S, "Call to rtw.pil.SILPILInterface.sfunctionGateway failed!"); return; } } mxFree((void *) simulinkBlockPath); dataIn = lhs[0]; } if (!mxIsEmpty(dataIn)) { if (mxGetClassID(dataIn) != mxUINT8_CLASS) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidTypeDataIn", "Expected Runtime \"dataIn\" to have type: uint8_T, but the actual type was: %s.", mxGetClassName(dataIn)); } if (mxGetNumberOfElements(dataIn) != 1) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidSizeDataIn", "Expected Runtime \"dataIn\" to be of size: 1, but the actual size was: %u.", mxGetNumberOfElements(dataIn)); } mxMemUnitPtr = (uint8_T *) mxGetData(dataIn); if (mxMemUnitPtr[0]) { mexErrMsgIdAndTxt("PIL:pilverification:PILError", "Unrecoverable PIL target error: command error (%u) occurred during cosimulation.", mxMemUnitPtr[0]); } } mxDestroyArray(dataIn); } { mxArray *rhs[2]; mxArray *lhs[3]; char * simulinkBlockPath = getSimulinkBlockPath(S); if (simulinkBlockPath == NULL) { ssSetErrorStatus(S, "ModelBlock PIL unexpected error: getSimulinkBlockPath returned NULL pointer. Check search string was found in ssGetPath.\n"); return; } rhs[0] = mxCreateLogicalScalar(1); rhs[1] = mxCreateString(simulinkBlockPath); { int error = mexCallMATLAB(3, lhs, 2, rhs, "rtw.pil.SILPILInterface.sfunctionGatewayGetRtIOStreamInfo"); mxDestroyArray(rhs[0]); mxDestroyArray(rhs[1]); if (error) { ssSetErrorStatus(S, "Call to rtw.pil.SILPILInterface.sfunctionGatewayGetRtIOStreamInfo failed!"); return; } } mxFree((void *) simulinkBlockPath); { rtIOStreamData * rtIOStreamDataPtr = (rtIOStreamData *) calloc(1, sizeof(rtIOStreamData)); if (rtIOStreamDataPtr == NULL) { ssSetErrorStatus(S, "Error in allocating memory through calloc\n"); return; } rtIOStreamDataPtr->lib = mxArrayToString(lhs[0]); mexMakeMemoryPersistent(rtIOStreamDataPtr->lib); rtIOStreamDataPtr->stationID = *mxGetPr(lhs[1]); rtIOStreamDataPtr->recvTimeout = *mxGetPr(lhs[2]); ssSetPWorkValue(S, 0, rtIOStreamDataPtr); } mxDestroyArray(lhs[0]); mxDestroyArray(lhs[1]); mxDestroyArray(lhs[2]); } /* initialize parameters */ mdlProcessParameters(S); { mwSize mxInputDataDims[]={1, 5}; mxArray * dataOut = mxCreateNumericArray(2, mxInputDataDims, mxUINT8_CLASS, mxREAL); mxArray * dataInAmount = mxCreateDoubleScalar(9); mxArray * dataIn; uint8_T * mxMemUnitPtr = (uint8_T *) mxGetData(dataOut); /* write command id */ *mxMemUnitPtr = 1; mxMemUnitPtr++; { uint8_T * simDataMemUnitPtr; uint32_T commandDataFcnid = 0; simDataMemUnitPtr = (uint8_T *) &commandDataFcnid; memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 4); mxMemUnitPtr = mxMemUnitPtr + 4; } { { rtIOStreamData * rtIOStreamDataPtr = (rtIOStreamData *) ssGetPWorkValue(S, 0); { mxArray *rhs[6]; mxArray *lhs[1]; rhs[0] = mxCreateString(rtIOStreamDataPtr->lib); rhs[1] = mxCreateString("pilsendrecv"); rhs[2] = mxCreateDoubleScalar(rtIOStreamDataPtr->stationID); rhs[3] = dataOut; rhs[4] = dataInAmount; rhs[5] = mxCreateDoubleScalar(rtIOStreamDataPtr->recvTimeout); { int error = mexCallMATLAB(1, lhs, 6, rhs, "rtiostream_wrapper"); { int i; for (i=0; i<6; i++) { mxDestroyArray(rhs[i]); } } if (error) { ssSetErrorStatus(S, "Call to rtiostream_wrapper failed!"); return; } } dataIn = lhs[0]; } } } if (!mxIsEmpty(dataIn)) { if (mxGetClassID(dataIn) != mxUINT8_CLASS) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidTypeDataIn", "Expected Runtime \"dataIn\" to have type: uint8_T, but the actual type was: %s.", mxGetClassName(dataIn)); } if (mxGetNumberOfElements(dataIn) != 9) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidSizeDataIn", "Expected Runtime \"dataIn\" to be of size: 9, but the actual size was: %u.", mxGetNumberOfElements(dataIn)); } mxMemUnitPtr = (uint8_T *) mxGetData(dataIn); if (mxMemUnitPtr[8]) { mexErrMsgIdAndTxt("PIL:pilverification:PILError", "Unrecoverable PIL target error: command error (%u) occurred during cosimulation.", mxMemUnitPtr[8]); } { uint8_T * simDataMemUnitPtr; simDataMemUnitPtr = (uint8_T *) ssGetOutputPortSignal(S, 0); memcpy((void *) simDataMemUnitPtr, (void *) mxMemUnitPtr, 8); mxMemUnitPtr = mxMemUnitPtr + 8; } } mxDestroyArray(dataIn); } } #endif /* MDL_START */ #if defined(MDL_PROCESS_PARAMETERS) static void mdlProcessParameters(SimStruct *S) { { mwSize mxInputDataDims[]={1, 5}; mxArray * dataOut = mxCreateNumericArray(2, mxInputDataDims, mxUINT8_CLASS, mxREAL); mxArray * dataInAmount = mxCreateDoubleScalar(1); mxArray * dataIn; uint8_T * mxMemUnitPtr = (uint8_T *) mxGetData(dataOut); mxArray * memUnitType = mxCreateString("uint8"); /* write command id */ *mxMemUnitPtr = 8; mxMemUnitPtr++; { uint8_T * simDataMemUnitPtr; uint32_T commandDataFcnid = 0; simDataMemUnitPtr = (uint8_T *) &commandDataFcnid; memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 4); mxMemUnitPtr = mxMemUnitPtr + 4; } { mxArray *rhs[6]; mxArray *lhs[1]; char * simulinkBlockPath = getSimulinkBlockPath(S); if (simulinkBlockPath == NULL) { ssSetErrorStatus(S, "ModelBlock PIL unexpected error: getSimulinkBlockPath returned NULL pointer. Check search string was found in ssGetPath.\n"); return; } rhs[0] = mxCreateLogicalScalar(1); rhs[1] = mxCreateString(simulinkBlockPath); rhs[2] = mxCreateString("PIL_PROCESS_PARAMS_COMMAND"); /* input data */ rhs[3] = dataOut; /* dataInAmount */ rhs[4] = dataInAmount; /* memUnitType */ rhs[5] = memUnitType; { int error = mexCallMATLAB(1, lhs, 6, rhs, "rtw.pil.SILPILInterface.sfunctionGateway"); { int i; for (i=0; i<6; i++) { mxDestroyArray(rhs[i]); } } if (error) { ssSetErrorStatus(S, "Call to rtw.pil.SILPILInterface.sfunctionGateway failed!"); return; } } mxFree((void *) simulinkBlockPath); dataIn = lhs[0]; } if (!mxIsEmpty(dataIn)) { if (mxGetClassID(dataIn) != mxUINT8_CLASS) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidTypeDataIn", "Expected Runtime \"dataIn\" to have type: uint8_T, but the actual type was: %s.", mxGetClassName(dataIn)); } if (mxGetNumberOfElements(dataIn) != 1) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidSizeDataIn", "Expected Runtime \"dataIn\" to be of size: 1, but the actual size was: %u.", mxGetNumberOfElements(dataIn)); } mxMemUnitPtr = (uint8_T *) mxGetData(dataIn); if (mxMemUnitPtr[0]) { mexErrMsgIdAndTxt("PIL:pilverification:PILError", "Unrecoverable PIL target error: command error (%u) occurred during cosimulation.", mxMemUnitPtr[0]); } } mxDestroyArray(dataIn); } } #endif /* MDL_PROCESS_PARAMETERS */ #define MDL_INITIALIZE_CONDITIONS /* Change to #undef to remove function */ #if defined(MDL_INITIALIZE_CONDITIONS) static void mdlInitializeConditions(SimStruct *S) { if (!ssIsFirstInitCond(S)) { ssSetErrorStatus(S, "This PIL block cannot be called from within a subsystem that can reset its states because the target code has been optimized to remove zero initialization of states. Turn off optimization setting 'Optimize initialization code for model reference' on the 'Optimization' page of the Configuration Parameters dialog of the referenced model to use this block in a subsystem that can reset its states."); return; } { mwSize mxInputDataDims[]={1, 5}; mxArray * dataOut = mxCreateNumericArray(2, mxInputDataDims, mxUINT8_CLASS, mxREAL); mxArray * dataInAmount = mxCreateDoubleScalar(1); mxArray * dataIn; uint8_T * mxMemUnitPtr = (uint8_T *) mxGetData(dataOut); /* write command id */ *mxMemUnitPtr = 2; mxMemUnitPtr++; { uint8_T * simDataMemUnitPtr; uint32_T commandDataFcnid = 0; simDataMemUnitPtr = (uint8_T *) &commandDataFcnid; memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 4); mxMemUnitPtr = mxMemUnitPtr + 4; } { { rtIOStreamData * rtIOStreamDataPtr = (rtIOStreamData *) ssGetPWorkValue(S, 0); { mxArray *rhs[6]; mxArray *lhs[1]; rhs[0] = mxCreateString(rtIOStreamDataPtr->lib); rhs[1] = mxCreateString("pilsendrecv"); rhs[2] = mxCreateDoubleScalar(rtIOStreamDataPtr->stationID); rhs[3] = dataOut; rhs[4] = dataInAmount; rhs[5] = mxCreateDoubleScalar(rtIOStreamDataPtr->recvTimeout); { int error = mexCallMATLAB(1, lhs, 6, rhs, "rtiostream_wrapper"); { int i; for (i=0; i<6; i++) { mxDestroyArray(rhs[i]); } } if (error) { ssSetErrorStatus(S, "Call to rtiostream_wrapper failed!"); return; } } dataIn = lhs[0]; } } } if (!mxIsEmpty(dataIn)) { if (mxGetClassID(dataIn) != mxUINT8_CLASS) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidTypeDataIn", "Expected Runtime \"dataIn\" to have type: uint8_T, but the actual type was: %s.", mxGetClassName(dataIn)); } if (mxGetNumberOfElements(dataIn) != 1) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidSizeDataIn", "Expected Runtime \"dataIn\" to be of size: 1, but the actual size was: %u.", mxGetNumberOfElements(dataIn)); } mxMemUnitPtr = (uint8_T *) mxGetData(dataIn); if (mxMemUnitPtr[0]) { mexErrMsgIdAndTxt("PIL:pilverification:PILError", "Unrecoverable PIL target error: command error (%u) occurred during cosimulation.", mxMemUnitPtr[0]); } } mxDestroyArray(dataIn); } } #endif /* MDL_INITIALIZE_CONDITIONS */ #define MDL_SET_WORK_WIDTHS /* Change to #undef to remove function */ #if defined(MDL_SET_WORK_WIDTHS) static void mdlSetWorkWidths(SimStruct *S) { if (S->mdlInfo->genericFcn != NULL) { int_T hwSettings[13]; _GenericFcn fcn = S->mdlInfo->genericFcn; boolean_T hasDiscTs = 1; if (!(fcn)(S, GEN_FCN_CHK_MODELREF_SOLVER_TYPE, 2, &hasDiscTs)) return; if (!(fcn)(S, GEN_FCN_CHK_MODELREF_SOLVER_MODE, SOLVER_MODE_SINGLETASKING, NULL)) return; hwSettings[0] = 8; hwSettings[1] = 16; hwSettings[2] = 32; hwSettings[3] = 32; hwSettings[4] = 32; hwSettings[5] = 64; hwSettings[6] = 32; hwSettings[7] = 2; hwSettings[8] = 0; hwSettings[9] = 32; hwSettings[10] = 1; hwSettings[11] = 0; hwSettings[12] = 2; if (!(fcn)(S, GEN_FCN_CHK_MODELREF_HARDWARE_SETTINGS, 13, hwSettings)) return; } } #endif /* MDL_SET_WORK_WIDTHS */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Singlerate scheduling */ /* check for sample time hit associated with task 1 */ if (ssIsSampleHit(S, ssGetInputPortSampleTimeIndex(S, 0), tid)) { { mwSize mxInputDataDims[]={1, 17}; mxArray * dataOut = mxCreateNumericArray(2, mxInputDataDims, mxUINT8_CLASS, mxREAL); mxArray * dataInAmount = mxCreateDoubleScalar(9); mxArray * dataIn; uint8_T * mxMemUnitPtr = (uint8_T *) mxGetData(dataOut); /* write command id */ *mxMemUnitPtr = 3; mxMemUnitPtr++; { uint8_T * simDataMemUnitPtr; uint32_T commandDataFcnidTID[2] = {0, 1}; simDataMemUnitPtr = (uint8_T *) &commandDataFcnidTID[0]; memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 8); mxMemUnitPtr = mxMemUnitPtr + 8; } { uint8_T * simDataMemUnitPtr; simDataMemUnitPtr = (uint8_T *) ssGetInputPortSignal(S, 0); memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 8); mxMemUnitPtr = mxMemUnitPtr + 8; } { { rtIOStreamData * rtIOStreamDataPtr = (rtIOStreamData *) ssGetPWorkValue(S, 0); { mxArray *rhs[6]; mxArray *lhs[1]; rhs[0] = mxCreateString(rtIOStreamDataPtr->lib); rhs[1] = mxCreateString("pilsendrecv"); rhs[2] = mxCreateDoubleScalar(rtIOStreamDataPtr->stationID); rhs[3] = dataOut; rhs[4] = dataInAmount; rhs[5] = mxCreateDoubleScalar(rtIOStreamDataPtr->recvTimeout); { int error = mexCallMATLAB(1, lhs, 6, rhs, "rtiostream_wrapper"); { int i; for (i=0; i<6; i++) { mxDestroyArray(rhs[i]); } } if (error) { ssSetErrorStatus(S, "Call to rtiostream_wrapper failed!"); return; } } dataIn = lhs[0]; } } } if (!mxIsEmpty(dataIn)) { if (mxGetNumberOfElements(dataIn) != 9) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidSizeDataIn", "Expected Runtime \"dataIn\" to be of size: 9, but the actual size was: %u.", mxGetNumberOfElements(dataIn)); } mxMemUnitPtr = (uint8_T *) mxGetData(dataIn); if (mxMemUnitPtr[8]) { mexErrMsgIdAndTxt("PIL:pilverification:PILError", "Unrecoverable PIL target error: command error (%u) occurred during cosimulation.", mxMemUnitPtr[8]); } { uint8_T * simDataMemUnitPtr; simDataMemUnitPtr = (uint8_T *) ssGetOutputPortSignal(S, 0); memcpy((void *) simDataMemUnitPtr, (void *) mxMemUnitPtr, 8); mxMemUnitPtr = mxMemUnitPtr + 8; } } mxDestroyArray(dataIn); } } } static void mdlTerminate(SimStruct *S) { { mwSize mxInputDataDims[]={1, 5}; mxArray * dataOut = mxCreateNumericArray(2, mxInputDataDims, mxUINT8_CLASS, mxREAL); mxArray * dataInAmount = mxCreateDoubleScalar(1); mxArray * dataIn; uint8_T * mxMemUnitPtr = (uint8_T *) mxGetData(dataOut); mxArray * memUnitType = mxCreateString("uint8"); /* write command id */ *mxMemUnitPtr = 4; mxMemUnitPtr++; { uint8_T * simDataMemUnitPtr; uint32_T commandDataFcnid = 0; simDataMemUnitPtr = (uint8_T *) &commandDataFcnid; memcpy((void *) mxMemUnitPtr, (void *) simDataMemUnitPtr, 4); mxMemUnitPtr = mxMemUnitPtr + 4; } { mxArray *rhs[6]; mxArray *lhs[1]; char * simulinkBlockPath = getSimulinkBlockPath(S); if (simulinkBlockPath == NULL) { ssSetErrorStatus(S, "ModelBlock PIL unexpected error: getSimulinkBlockPath returned NULL pointer. Check search string was found in ssGetPath.\n"); return; } rhs[0] = mxCreateLogicalScalar(1); rhs[1] = mxCreateString(simulinkBlockPath); rhs[2] = mxCreateString("PIL_TERMINATE_COMMAND"); /* input data */ rhs[3] = dataOut; /* dataInAmount */ rhs[4] = dataInAmount; /* memUnitType */ rhs[5] = memUnitType; { int error = mexCallMATLAB(1, lhs, 6, rhs, "rtw.pil.SILPILInterface.sfunctionGateway"); { int i; for (i=0; i<6; i++) { mxDestroyArray(rhs[i]); } } if (error) { ssSetErrorStatus(S, "Call to rtw.pil.SILPILInterface.sfunctionGateway failed!"); return; } } mxFree((void *) simulinkBlockPath); dataIn = lhs[0]; } if (!mxIsEmpty(dataIn)) { if (mxGetClassID(dataIn) != mxUINT8_CLASS) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidTypeDataIn", "Expected Runtime \"dataIn\" to have type: uint8_T, but the actual type was: %s.", mxGetClassName(dataIn)); } if (mxGetNumberOfElements(dataIn) != 1) { mexErrMsgIdAndTxt("PIL:pilverification:InvalidSizeDataIn", "Expected Runtime \"dataIn\" to be of size: 1, but the actual size was: %u.", mxGetNumberOfElements(dataIn)); } mxMemUnitPtr = (uint8_T *) mxGetData(dataIn); if (mxMemUnitPtr[0]) { mexErrMsgIdAndTxt("PIL:pilverification:PILError", "Unrecoverable PIL target error: command error (%u) occurred during cosimulation.", mxMemUnitPtr[0]); } } mxDestroyArray(dataIn); } if (ssGetPWork(S) != NULL) { rtIOStreamData * rtIOStreamDataPtr = (rtIOStreamData *) ssGetPWorkValue(S, 0); if (rtIOStreamDataPtr != NULL) { mxFree(rtIOStreamDataPtr->lib); free(rtIOStreamDataPtr); ssSetPWorkValue(S, 0, NULL); } } } #define MDL_ENABLE #if defined(MDL_ENABLE) static void mdlEnable(SimStruct *S) { } #endif /* MDL_ENABLE */ #define MDL_DISABLE #if defined(MDL_DISABLE) static void mdlDisable(SimStruct *S) { } #endif /* MDL_DISABLE */ /* Required S-function trailer */ #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ #include "simulink.c" /* MEX-file interface mechanism */ #include "fixedpoint.c" #else #error Assertion failed: file must be compiled as a MEX-file #endif