/* Function: rt_FillStateSigInfoFromMMI ======================================= * Abstract: * * Returns: * == NULL => success. * ~= NULL => failure, the return value is a pointer to the error * message, which is also set in the simstruct. */ const char_T * rt_FillStateSigInfoFromMMI(RTWLogInfo *li, const char_T **errStatus) { int_T i; int_T nSignals = 0; int_T *dims = NULL; BuiltInDTypeId *dTypes = NULL; int_T *cSgnls = NULL; char_T **labels = NULL; char_T **blockNames = NULL; char_T **stateNames = NULL; boolean_T *crossMdlRef = NULL; void **sigDataAddr = NULL; int_T *logDataType = NULL; boolean_T *isVarDims = NULL; const rtwCAPI_ModelMappingInfo *mmi = (const rtwCAPI_ModelMappingInfo *)rtliGetMMI(li); int_T sigIdx = 0; RTWLogSignalInfo * sigInfo; /* reset error status */ *errStatus = NULL; sigInfo = (RTWLogSignalInfo *)calloc(1,sizeof(RTWLogSignalInfo)); if (sigInfo == NULL) goto ERROR_EXIT; nSignals = rtwCAPI_GetNumStateRecordsForRTWLogging(mmi); if (nSignals >0) { /* These are all freed before exiting this function */ dims = (int_T *)calloc(nSignals,sizeof(int_T)); if (dims == NULL) goto ERROR_EXIT; dTypes = (BuiltInDTypeId *)calloc(nSignals,sizeof(BuiltInDTypeId)); if (dTypes == NULL) goto ERROR_EXIT; cSgnls = (int_T *)calloc(nSignals,sizeof(int_T)); if (cSgnls == NULL) goto ERROR_EXIT; labels = (char_T **)calloc(nSignals, sizeof(char_T*)); if (labels == NULL) goto ERROR_EXIT; blockNames = (char_T**)calloc(nSignals, sizeof(char_T*)); if (blockNames == NULL) goto ERROR_EXIT; stateNames = (char_T**)calloc(nSignals, sizeof(char_T*)); if (stateNames == NULL) goto ERROR_EXIT; crossMdlRef = (boolean_T*)calloc(nSignals, sizeof(boolean_T)); if (crossMdlRef == NULL) goto ERROR_EXIT; logDataType = (int_T *)calloc(nSignals,sizeof(int_T)); if (logDataType == NULL) goto ERROR_EXIT; /* Allocate memeory for isVarDims pointer and set all elements to 0's */ isVarDims = (boolean_T *)calloc(nSignals,sizeof(boolean_T)); if (isVarDims == NULL) goto ERROR_EXIT; /* This is freed in stopDataLogging (it's needed in the meantime) */ sigDataAddr = (void **)calloc(nSignals,sizeof(void *)); if (sigDataAddr == NULL) goto ERROR_EXIT; *errStatus = rtwCAPI_GetStateRecordInfo(mmi, (const char_T**) blockNames, (const char_T**) labels, (const char_T**) stateNames, dims, (int_T*)dTypes, logDataType, cSgnls, sigDataAddr, crossMdlRef, NULL, NULL, /* sigSampleTime */ &sigIdx, false, /* crossingModel */ NULL, /* stateDerivVector */ ACCESS_C_API_FOR_RTW_LOGGING); if (*errStatus != NULL) goto ERROR_EXIT; rtliSetLogXSignalPtrs(li,(LogSignalPtrsType)sigDataAddr); } sigInfo->numSignals = nSignals; sigInfo->numCols = dims; sigInfo->numDims = NULL; sigInfo->dims = dims; sigInfo->dataTypes = dTypes; sigInfo->complexSignals = cSgnls; sigInfo->frameData = NULL; sigInfo->labels.ptr = labels; sigInfo->titles = NULL; sigInfo->titleLengths = NULL; sigInfo->plotStyles = NULL; sigInfo->blockNames.ptr = blockNames; sigInfo->stateNames.ptr = stateNames; sigInfo->crossMdlRef = crossMdlRef; sigInfo->dataTypeConvert = NULL; sigInfo->isVarDims = isVarDims; sigInfo->currSigDims = NULL; rtliSetLogXSignalInfo(li,sigInfo); /* Free logDataType it's not needed any more, * the rest of them will be freed later */ FREE(logDataType); return(NULL); /* NORMAL_EXIT */ ERROR_EXIT: if (*errStatus == NULL) { *errStatus = rtMemAllocError; } /* Free local stuff that was allocated. It is no longer needed */ for (i = 0; i < nSignals; ++i) utFree(blockNames[i]); FREE(blockNames); for (i = 0; i < nSignals; ++i) utFree(stateNames[i]); FREE(stateNames); FREE(labels); FREE(dims); FREE(dTypes); FREE(logDataType); FREE(cSgnls); FREE(isVarDims); return(*errStatus); } /* end rt_InitSignalsStruct */
/** Function: rtwCAPI_GetStateRecordInfo ======================================= * */ const char_T* rtwCAPI_GetStateRecordInfo(const rtwCAPI_ModelMappingInfo* mmi, const char_T** sigBlockName, const char_T** sigLabel, const char_T** sigName, int_T* sigWidth, int_T* sigDataType, int_T* logDataType, int_T* sigComplexity, void** sigDataAddr, boolean_T* sigCrossMdlRef, const char_T** sigPathAlias, real_T* sigSampleTime, int_T* sigIdx, boolean_T crossingModel, real_T* contStateDeriv, boolean_T rtwLogging) { int_T i; int_T nCMMI; int_T nStates; const char_T* mmiPath; size_t mmiPathLen; const rtwCAPI_States* states; const rtwCAPI_DimensionMap* dimMap; const uint_T* dimArray; const rtwCAPI_DataTypeMap* dataTypeMap; void** dataAddrMap; const char_T* errstr = NULL; uint8_T isPointer = 0; if (mmi == NULL) goto EXIT_POINT; nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (i = 0; i < nCMMI; ++i) { rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,i); real_T* childContStateDeriv = NULL; if (contStateDeriv) { int_T idx = rtwCAPI_MMIGetContStateStartIndex(cMMI); if(idx == -1) continue; childContStateDeriv = &contStateDeriv[idx]; } errstr = rtwCAPI_GetStateRecordInfo(cMMI, sigBlockName, sigLabel, sigName, sigWidth, sigDataType, logDataType, sigComplexity, sigDataAddr, sigCrossMdlRef, sigPathAlias, sigSampleTime, sigIdx, 0x1, /* true, */ childContStateDeriv, rtwLogging); if (errstr != NULL) goto EXIT_POINT; } nStates = rtwCAPI_GetNumStates(mmi); if (nStates < 1) goto EXIT_POINT; mmiPath = rtwCAPI_GetFullPath(mmi); mmiPathLen = (mmiPath==NULL)? 0 : strlen(mmiPath); states = rtwCAPI_GetStates(mmi); dimMap = rtwCAPI_GetDimensionMap(mmi); dimArray = rtwCAPI_GetDimensionArray(mmi); dataTypeMap = rtwCAPI_GetDataTypeMap(mmi); dataAddrMap = rtwCAPI_GetDataAddressMap(mmi); for (i = 0; i < nStates; ++i) { uint_T mapIdx; /* If collecting continuous states, skip non-continuous states */ if (contStateDeriv && !rtwCAPI_IsAContinuousState(states,i)) continue; /* For RTW logging, skip states that cannot be logged to MAT-File. */ if ((rtwLogging) && (rtwCAPI_CanLogStateToMATFile(dataTypeMap, states, i) == false)) continue; /* BlockPath (caller is responsible for free) */ sigBlockName[*sigIdx] = rtwCAPI_GetFullStateBlockPath(rtwCAPI_GetStateBlockPath(states,i), mmiPath, mmiPathLen, crossingModel); if (sigBlockName[*sigIdx] == NULL) { errstr = rtwCAPI_mallocError; goto EXIT_POINT; } /* Label */ if (rtwCAPI_IsAContinuousState(states,i)){ sigLabel[*sigIdx] = "CSTATE"; } else { sigLabel[*sigIdx] = "DSTATE"; } sigName[*sigIdx] = rtwCAPI_GetStateName(states, i); /* Width */ sigWidth[*sigIdx] = rtwCAPI_GetStateWidth(dimMap, dimArray, states, i); /* DataType and logDataType */ mapIdx = rtwCAPI_GetStateDataTypeIdx(states, i); sigDataType[*sigIdx] = rtwCAPI_GetDataTypeSLId(dataTypeMap, mapIdx); /* this mimics code in simulink.dll:DtGetDataTypeLoggingId() */ if (logDataType) { switch (sigDataType[*sigIdx]) { case SS_DOUBLE: case SS_SINGLE: case SS_INT8: case SS_UINT8: case SS_INT16: case SS_UINT16: case SS_INT32: case SS_UINT32: case SS_BOOLEAN: logDataType[*sigIdx] = sigDataType[*sigIdx]; break; case SS_ENUM_TYPE: logDataType[*sigIdx] = SS_INT32; break; default: logDataType[*sigIdx] = SS_DOUBLE; break; } } /* Complexity */ sigComplexity[*sigIdx] = rtwCAPI_GetDataIsComplex(dataTypeMap, mapIdx); /* Data Access - Pointer or Direct*/ isPointer = ((uint8_T)rtwCAPI_GetDataIsPointer(dataTypeMap, mapIdx)); /* Address */ if (contStateDeriv) { int_T csvIdx = rtwCAPI_GetContStateStartIndex(states,i); utAssert(csvIdx >= 0); sigDataAddr[*sigIdx] = &contStateDeriv[csvIdx]; } else { mapIdx = rtwCAPI_GetStateAddrIdx(states,i); rtwCAPI_GetSigAddrFromMap(isPointer, sigComplexity, sigDataType, sigDataAddr, sigIdx, mapIdx, dataAddrMap); } /* CrossingModelBoundary */ sigCrossMdlRef[*sigIdx] = crossingModel; if (sigPathAlias && rtwCAPI_GetStatePathAlias(states,i) != NULL && rtwCAPI_GetStatePathAlias(states,i)[0] != '\0') { sigPathAlias[*sigIdx] = rtwCAPI_GetFullStateBlockPath(rtwCAPI_GetStatePathAlias(states,i), mmiPath, mmiPathLen, crossingModel); } /* Sample Time */ if (sigSampleTime) { const rtwCAPI_SampleTimeMap* tsMap = rtwCAPI_GetSampleTimeMap(mmi); int_T TID; mapIdx = rtwCAPI_GetStateSampleTimeIdx(states, i); TID = rtwCAPI_GetSampleTimeTID(tsMap, mapIdx); if (TID >= 0) { sigSampleTime[2*(*sigIdx)] = *((const real_T*)rtwCAPI_GetSamplePeriodPtr(tsMap,mapIdx)); sigSampleTime[2*(*sigIdx)+1] = *((const real_T*)rtwCAPI_GetSampleOffsetPtr(tsMap,mapIdx)); } else { /* triggered */ utAssert(TID==-1); sigSampleTime[2*(*sigIdx)] = -1.0; sigSampleTime[2*(*sigIdx)+1] = -1.0; } } ++(*sigIdx); } EXIT_POINT: return(errstr); } /* rtwCAPI_GetStateRecordInfo */