Ejemplo n.º 1
0
/* 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 */
Ejemplo n.º 2
0
/** 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 */