%selectfile NULL_FILE
%if EXISTS("_SFCNLIB_") == 0
%assign _SFCNLIB_ = 1
%include "sfcnutil.tlc"
%include "prm_sfcntunable.tlc"
%function SLibDumpSfcnInpDims(S, pIdx, width, nDims, dims) Output
%if %<nDims> == matrixDimensionThreshhold
if(!ssSetInputPortMatrixDimensions(%<S>, %<pIdx>, %, %)) /
return;
%elseif %<nDims> > matrixDimensionThreshhold
{
DimsInfo_T inpDims;
%assign dimsStr = "{"
%foreach dIdx = nDims
%if dIdx != 0
%assign dimsStr = dimsStr + ", "
%endif
%assign dimsStr = dimsStr + "%"
%endforeach
%assign dimsStr = dimsStr + "}"
int_T inpDimsVals[%<nDims>] = %<dimsStr>;
inpDims.width = %<width>;
inpDims.numDims = %<nDims>;
inpDims.dims = inpDimsVals;
inpDims.nextSigDims = %<SLibGetNullDefinitionFromTfl()>;
if (!ssSetInputPortDimensionInfo(%<S>, %<pIdx>, &inpDims)) return;
}
%else
if(!ssSetInputPortVectorDimension(%<S>, %<pIdx>, %<width>)) return;
%endif
%endfunction
%function SLibDumpSfcnOutDims(S, pIdx, width, nDims, dims) Output
%if %<nDims> == matrixDimensionThreshhold
if(!ssSetOutputPortMatrixDimensions(%<S>, %<pIdx>, %, %)) /
return;
%elseif %<nDims> > matrixDimensionThreshhold
{
DimsInfo_T outDims;
%assign dimsStr = "{"
%foreach dIdx = nDims
%if dIdx != 0
%assign dimsStr = dimsStr + ", "
%endif
%assign dimsStr = dimsStr + "%"
%endforeach
%assign dimsStr = dimsStr + "}"
int_T outDimsVals[%<nDims>] = %<dimsStr>;
outDims.width = %<width>;
outDims.numDims = %<nDims>;
outDims.dims = outDimsVals;
outDims.nextSigDims = %<SLibGetNullDefinitionFromTfl()>;
if (!ssSetOutputPortDimensionInfo(%<S>, %<pIdx>, &outDims)) return;
}
%else
if(!ssSetOutputPortVectorDimension(%<S>, %<pIdx>, %<width>)) return;
%endif
%endfunction
%function SLibLocalSDeclaration(usingStatic) void
%endfunction
%function SLibLocalSRegistration(usingStatic) void
%openfile tmpBuffer
/* Local SimStruct for the generated S-Function */
%if usingStatic
static LocalS slS;
LocalS *lS = &slS;
ssSetUserData(%<::tSimStruct>, lS);
%else
LocalS *lS = (LocalS *) malloc(sizeof(LocalS));
%<RTMChkMemAndReturnIfErr("lS")>;
%if ::GenCPP == 0
(void) %<LibGenMemFcnCall("memset", "(char *) lS", "0", ...
"sizeof(LocalS)")>;
ssSetUserData(%<::tSimStruct>, lS);
%elseif SLibIsRTMZeroInitCppEnabled()
(void) %<LibGenMemFcnCall("memset", "(void *) lS", "0", ...
"sizeof(LocalS)")>;
ssSetUserData(%<::tSimStruct>, lS);
%else
ssSetUserData(%<::tSimStruct>, lS);
ssSetLocalBlockIO(%<::tSimStruct>, 0);
ssSetLocalDefaultParam(%<::tSimStruct>, 0);
ssSetLocalNonContDerivSig(%<::tSimStruct>, 0);
%endif
%endif
%if !LibBlockIOStructIsEmpty()
/* block I/O */
{
%assign varName = "b"
%if usingStatic
static %<::tBlockIOType> sfcnB;
void *%<varName> = (real_T *) &sfcnB;
%else
void *%<varName> = malloc(sizeof(%<::tBlockIOType>));
%<RTMChkMemAndReturnIfErr(varName)>;
%endif
ssSetLocalBlockIO(%<::tSimStruct>, %<varName>);
%assign unused = SLibInitBlockIO(varName)
}
%endif
%if !LibConstBlockIOStructIsEmpty()
_ssSetConstBlockIO(%<::tSimStruct>, &%<::tInvariantSignals>);
%endif
%if !LibParametersStructIsEmpty()
/* model parameters */
ssSetLocalDefaultParam(%<::tSimStruct>, (real_T *) &%<::tDefaultParameters>);
%endif
%if SolverType == "VariableStep" && ...
SolverResetInfo.NumNonContDerivSignals > 0
%assign dU = "nonContDerivSigCache_%<LibGetModelName()>_T"
{
%assign varName = "pNonContDerivSig"
%if usingStatic
static %<dU> nonContDerivSigs;
void *%<varName> = (void *) &nonContDerivSigs;
%else
void *%<varName> = (void *)malloc(sizeof(%<dU>));
%<RTMChkMemAndReturnIfErr(varName)>;
%endif
(void) %<LibGenMemFcnCall("memset", "(char *) %<varName>", "0", ...
"sizeof(%<dU>)")>;
ssSetLocalNonContDerivSig(%<::tSimStruct>, %<varName>);
}
%endif
%if !LibPrevZCStatesStructIsEmpty()
%assign prevZCStatesInRTM = FcnGetPrevZCSigStateType()
/* previous zero-crossing states */
{
int_T i;
%if usingStatic
static %<::tPrevZCStateType> %<::tPrevZCState>;
%<prevZCStatesInRTM> *zc = (%<prevZCStatesInRTM> *) &%<::tPrevZCState>;
%else
%<prevZCStatesInRTM> *zc = (%<prevZCStatesInRTM> *) malloc(sizeof(%<::tPrevZCStateType>));
%<RTMChkMemAndReturnIfErr("zc")>;
%endif
_ssSetPrevZCSigState(%<::tSimStruct>, zc);
for(i = 0; i < %<NumZCEvents>; i++) {
zc[i] = UNINITIALIZED_ZCSIG;
}
}
%endif
%<SLibDumpModelMappingInfo()>
/* model checksums */
ssSetChecksumVal(%<::tSimStruct>, 0, %);
ssSetChecksumVal(%<::tSimStruct>, 1, %);
ssSetChecksumVal(%<::tSimStruct>, 2, %);
ssSetChecksumVal(%<::tSimStruct>, 3, %);
%closefile tmpBuffer
%return tmpBuffer
%endfunction
%function FcnContextErr(simStructName,curContext, generatedContext) Output
ssSetErrorStatus(%<simStructName>, "This Simulink Coder generated " ...
"S-Function cannot be used in a simulation with " ...
"%<curContext> " ...
"because this S-Function was created from a model with " ...
"%<generatedContext>. " ...
"See the Solver page of the simulation parameters dialog.");
%endfunction
%function SLibGenerateSolverChecks(simStructName) Output
%if SolverType == "FixedStep"
%if LibIsContinuous(0)
/* Check for invalid switching between solver types */
if (ssIsVariableStepSolver(%<simStructName>)) {
%<FcnContextErr(simStructName,"a solver type of variable-step", ...
"solver type of fixed-step and it has continuous time blocks")>
return;
}
%endif
%if (FixedStepOpts.SolverMode == "SingleTasking") && (NumSynchronousSampleTimes > 1)
if (ssGetSolverMode(%<simStructName>) == SOLVER_MODE_MULTITASKING) {
%<FcnContextErr(simStructName,"solver mode set to auto or multitasking", ...
"solver mode set to singletasking")>
return;
}
%endif
%if SLibIsPeriodicRateGrouping()
if (ssGetSolverMode(%<simStructName>) == SOLVER_MODE_SINGLETASKING) {
%<FcnContextErr(simStructName,"solver mode set to singletasking", ...
"solver mode set to auto or multitasking")>
return;
}
%endif
%if (FixedStepOpts.DoRTWSFcnTID01EQCheck)
%assign fs = FixedStepOpts.FixedStep
if (fabs(ssGetFixedStepSize(%<::tSimStruct>) - %<fs>) > mxGetEps()*100*%<fs>) {
%<FcnContextErr(simStructName, "the current fixed step size", ...
"a fixed step size of %<FixedStepOpts.FixedStep> and had both /"/n" ...
"/"continuous blocks and discrete blocks running at this rate")>
return;
}
%endif
%else
%if LibIsContinuous(0)
/* Check for invalid switching between solver types */
if (!ssIsVariableStepSolver(%<simStructName>)) {
%<FcnContextErr(simStructName,"a solver type of fixed-step", ...
"solver type of variable-step solver and it has continuous time blocks")>
return;
}
%endif
%endif
%endfunction
%function LibDumpSfunTargetChecks() Output
%assign nonFinitesBuffer = SLibGetSFcnNonFinite()
/* instance underlying S-Function data */
#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
# if defined(MATLAB_MEX_FILE)
%<nonFinitesBuffer>/
%<SLibGenerateSolverChecks(::tSimStruct)>
# endif
%<LibGetModelName()>_malloc(%<::tSimStruct>);
if( ssGetErrorStatus(%<::tSimStruct>) != %<SLibGetNullDefinitionFromTfl()> ) {
return;
}
#endif
%endfunction
%function SLibCreateSfcnTunablePrmWSVariable(mdlName, numTunablePrms, prmIdxVec) void
%assign GenCodeOnly = FEVAL("get_param",mdlName,"RTWGenerateCodeOnly")
%if GenCodeOnly != "on"
%matlab evalin("base","clear global rtwsfcn_%<mdlName>")
%if numTunablePrms > 0
%matlab evalin("base","global rtwsfcn_%<mdlName>")
%endif
%with ModelParameters
%foreach prmIdx = numTunablePrms
%<FcnCacheNameAndValueStrForSFcnParam(mdlName, prmIdxVec[prmIdx])>
%endforeach
%endwith
%endif
%endfunction
%function LegacyFixptValueConversion(aDataTypeIdx, aValueStr)
%assert (GenerateErtSFunction == 1)
%assign valueStr = aValueStr
%assign dType = FixPt_GetDataTypeFromIndex(aDataTypeIdx)
%if (dType.FixedExp > 0)
%assign valueStr = "(2^%<dType.FixedExp>)*%<valueStr>"
%elseif (dType.FixedExp < 0)
%assign valueStr = "(2^(%<dType.FixedExp>))*%<valueStr>"
%endif
%if (dType.FracSlope != 1)
%assign valueStr = "%<dType.FracSlope>*%<valueStr>"
%endif
%if (dType.Bias != 0)
%assign valueStr = "%<dType.Bias> + %<valueStr>"
%endif
%return valueStr
%endfunction
%function SLibGetFxptValueStr(aMLType, aIsSigned, aNumBits, aFracSlope, ...
aFixedExp, aBias, aValueStr, aIsComplex, numElements) void
%assign valueStr = FEVAL("strrep", aValueStr, "(", "")
%assign valueStr = FEVAL("strrep", valueStr, ")", "")
%assign valueStr = FEVAL("strrep", valueStr, ...
"MIN_" + aMLType + "_T", "intmin('" + aMLType + "')")
%assign valueStr = FEVAL("strrep", valueStr, ...
"MAX_" + aMLType + "_T", "intmax('" + aMLType + "')")
%assign isLargeInt = (aNumBits > 53)
%if isLargeInt || aFracSlope != 1 || aFixedExp != 0 || aBias != 0
%assign fiCall = "fi([], %<aIsSigned>, %<aNumBits>, " ...
"%<aFracSlope>, %<aFixedExp>, %<aBias>, 'int', "
%if aIsComplex
%assign valueStr = FEVAL("regexprep", valueStr, ...
"((-|)[0-9]+)//s*//+//s*((-|)[0-9]+)//s*//*//s*i", "complex($1, $2)")
%if isLargeInt
%assign valueStr = FEVAL("regexprep", valueStr, ...
"(//(|//[| )((-|)[0-9]+)", "$1%<fiCall>%<aMLType>($2))")
%else
%assign valueStr = FEVAL("regexprep", valueStr, ...
"(//(|//[| )((-|)[0-9]+)", "$1%<fiCall>$2)")
%endif
%else
%if isLargeInt
%assign valueStr = FEVAL("regexprep", valueStr, ...
"(//[| )((-|)[0-9]+)", "$1%<aMLType>($2)")
%endif
%assign valueStr = fiCall + valueStr + ")"
%endif
%endif
%return valueStr
%endfunction
%function SLibGetMLIntegerValueStr(aDataTypeIdx, aMLType, aValueStr, ...
aIsComplex, numEl) void
%assign valueStr = FEVAL("strrep", "%<aValueStr>","U", "")
%assign valueStr = FEVAL("strrep", valueStr, "L", "")
%if LibIsDataTypeFixpt(aDataTypeIdx)
%assign dType = FixPt_GetDataTypeFromIndex(aDataTypeIdx)
%if dType.RequiredBits > 53
%assign valueStr = SLibGetFxptValueStr(aMLType, dType.IsSigned, ...
dType.RequiredBits, dType.FracSlope, dType.FixedExp, dType.Bias, ...
valueStr, aIsComplex, numEl)
%else
%assign valueStr = LegacyFixptValueConversion(aDataTypeIdx, valueStr)
%endif
%elseif aMLType == "int64"
%assign valueStr = SLibGetFxptValueStr(aMLType, 1, 64, 1, 0, 0, ...
valueStr, aIsComplex, numEl)
%elseif aMLType == "uint64"
%assign valueStr = SLibGetFxptValueStr(aMLType, 0, 64, 1, 0, 0, ...
valueStr, aIsComplex, numEl)
%else
%assign valueStr = FEVAL("strrep", valueStr, ...
"(MIN_" + aMLType + "_T)", "intmin('" + aMLType + "')")
%assign valueStr = FEVAL("strrep", valueStr, ...
"(MAX_" + aMLType + "_T)", "intmax('" + aMLType + "')")
%assign valueStr = aMLType + "(" + valueStr + ")"
%endif
%return valueStr
%endfunction
%function FcnCacheNameAndValueStrForSFcnParam(modelName, mdlPrmIdx) void
%assign mdlPrm = ModelParameters.Parameter[mdlPrmIdx]
%assign pName = LibGetRecordIdentifier(mdlPrm)
%assign dataTypeIdx = ...
LibGetDataTypeIdAliasedThruToFromId(mdlPrm.OriginalDataTypeIdx)
%if (FcnParamMatchesVariableInGlobalScope(pName,mdlPrm) && ...
(!EXISTS(ConfigSet.UseParamValues) || ...
(EXISTS(ConfigSet.UseParamValues) && ...
ConfigSet.UseParamValues == 0)))
%if (FcnIsParamAlias(mdlPrm))
%assign nameStr = mdlPrm.WorkspaceVarName
%else
%assign nameStr = pName
%endif
%assign valueStr = ""
%else
%assign nameStr = ""
%assign isComplex = LibGetRecordIsComplex(mdlPrm)
%assign mdlPrmValue = SLibGetValueFromParamRec(mdlPrm, TLC_FALSE)
%assign valueStr = FEATURE("expandparameter", mdlPrmValue)
%if LibIsNonBuiltInTypeNeededForFixpt(dataTypeIdx)
%assign valueStr = FEVAL("strrep","%<valueStr>"," i","/*i")
%endif
%if LibIsDataTypeMultiWordFixpt(dataTypeIdx)
%assign valueStr = FEVAL("fixptGetMultiWordValue", valueStr, ...
IntegerSizes.LongNumBits)
%assign valueStr = FcnReshapeValueStr(valueStr, mdlPrm)
%if LibIsDataTypeFixpt(dataTypeIdx)
%assign valueStr = LegacyFixptValueConversion(dataTypeIdx, valueStr)
%endif
%elseif LibIsEnumDataType(dataTypeIdx)
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
LibGetDataTypeNameFromId(dataTypeIdx), valueStr, isComplex, LibGetRecordWidth(mdlPrm))
%assign valueStr = FcnReshapeValueStr(valueStr, mdlPrm)
%else
%assign numElement = LibGetRecordWidth(mdlPrm)
%switch LibGetDataTypeNameFromId(dataTypeIdx)
%case "int64_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"int64", valueStr, isComplex, numElement)
%break
%case "uint64_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"uint64", valueStr, isComplex, numElement)
%break
%case "int32_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"int32", valueStr, isComplex, numElement)
%break
%case "uint32_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"uint32", valueStr, isComplex, numElement)
%break
%case "int16_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"int16", valueStr, isComplex, numElement)
%break
%case "uint16_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"uint16", valueStr, isComplex, numElement)
%break
%case "int8_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"int8", valueStr, isComplex, numElement)
%break
%case "uint8_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"uint8", valueStr, isComplex, numElement)
%break
%case "boolean_T"
%assign valueStr = SLibGetMLIntegerValueStr(dataTypeIdx, ...
"logical", valueStr, isComplex, numElement)
%break
%case "real32_T"
%assign valueStr = FEVAL("strrep","%<valueStr>","F","")
%assign valueStr = FEVAL("strrep", valueStr, "rtInfF", "inf")
%assign valueStr = FEVAL("strrep", valueStr, "rtMinusInfF","-inf")
%assign valueStr = FEVAL("strrep", valueStr, "rtNaNF", "nan")
%assign valueStr = "single(" + valueStr + ")"
%break
%default
%assign valueStr = FEVAL("strrep", valueStr, "rtInf", "inf")
%assign valueStr = FEVAL("strrep", valueStr, "rtMinusInf","-inf")
%assign valueStr = FEVAL("strrep", valueStr, "rtNaN", "nan")
%break
%endswitch
%assign valueStr = FcnReshapeValueStr(valueStr, mdlPrm)
%endif
%endif
%matlab evalin("base", ...
"rtwsfcn_%<modelName>(end+1).Name = '%<pName>';")
%matlab evalin("base", ...
"rtwsfcn_%<modelName>(end).NameStr = '%<nameStr>';")
%matlab assignin("base", "rtw_sfunction_temp_var", valueStr)
%matlab evalin("base", ...
"rtwsfcn_%<modelName>(end).ValueStr = rtw_sfunction_temp_var;")
%matlab evalin("base", "clear rtw_sfunction_temp_var;")
%endfunction
%function SLibGenRTWSFcnParamHandlingFcns() void
%assert ((CodeFormat == "S-Function") && !Accelerator)
%assign result = [0, ""]
%assign numTunablePrms = 0
%with ModelParameters
%if InlineParameters != 0 && NumParameters > 0
%assign prmIdxVec = ...
Vector(%<NumParameters>) [0:%]
%foreach prmIdx = NumParameters
%assign mdlPrm = Parameter[prmIdx]
%if mdlPrm.StorageClass == "Auto_SFCN" && mdlPrm.Tunable == "yes"
%assert !LibGetRecordIsComplex(mdlPrm)
%assert LibIsBuiltInDataType(mdlPrm.OriginalDataTypeIdx)
%assign prmIdxVec[numTunablePrms] = prmIdx
%assign numTunablePrms = numTunablePrms + 1
%endif
%endforeach
%endif
%endwith
%if numTunablePrms > 0
%assert(numTunablePrms == ::CompiledModel.ModelParameters.SfcnParamIdx)
%<SLibCreateSfcnTunablePrmWSVariable(LibGetModelName(), numTunablePrms, prmIdxVec)>
%openfile fcnBuffer
%<FcnGenRTWSFcnCheckParamsFcn(numTunablePrms, prmIdxVec)>
%closefile fcnBuffer
%assign result[0] = %<numTunablePrms>
%assign result[1] = "%<fcnBuffer>"
%endif
%return result
%endfunction
%function FcnGenRTWSFcnCheckParamsFcn(numTunablePrms, prmIdxVec) Output
%if numTunablePrms > 0
%with ModelParameters
%assign fcnAbstract = "This function checks the attributes of tunable parameters."
%assign fcnName = "mdlCheckParameters"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<::tSimStruct>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "model"; GeneratedBy "sfcnlib.tlc"; Type "Model parameter check"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%foreach sfcnPrmIdx = numTunablePrms
%assign mdlPrm = Parameter[prmIdxVec[sfcnPrmIdx]]
%<FcnGenRTWSFcnParamChecks(mdlPrm, sfcnPrmIdx)>
%endforeach
}
#endif /* MDL_CHECK_PARAMETERS */
%endwith
%endif
%endfunction
%function FcnGenRTWSFcnParamChecks(mdlPrm, sfcnPrmIdx) Output
%assign pName = LibGetRecordIdentifier(mdlPrm)
/* Parameter check for '%<pName>' */
%assert !SLibGetRecordIsComplex(mdlPrm)
if (mxIsComplex(ssGetSFcnParam(%<::tSimStruct>, %<sfcnPrmIdx>))) {
ssSetErrorStatus(%<::tSimStruct>,"Parameter '%<pName>' has to be a non complex array.");
return;
}
%assign dataTypeIdx = mdlPrm.OriginalDataTypeIdx
%assert LibIsBuiltInDataType(dataTypeIdx)
%assign mxClassOfVar = SLibGetMLDataTypeFromId(dataTypeIdx)
%assign mxFcnName = SLibGetMLidentFcnFromId(dataTypeIdx)
if (!%<mxFcnName>(ssGetSFcnParam(%<::tSimStruct>, %<sfcnPrmIdx>))) {
ssSetErrorStatus(%<::tSimStruct>,"Parameter '%<pName>' has to be a %<mxClassOfVar> array.");
return;
}
%assign dims = FcnGetMatlabSafeDimensions(mdlPrm)
%assign numOfDims = SIZE(dims,1)
%assign dimsStr = "[%"
%foreach dimsIdx = (numOfDims-1)
%assign dimsStr = dimsStr + "x%"
%endforeach
%assign dimsStr = dimsStr + "]"
if ((mxGetNumberOfDimensions(ssGetSFcnParam(%<::tSimStruct>, %<sfcnPrmIdx>)) != %<numOfDims>)/
%foreach dimsIdx = numOfDims
||
(mxGetDimensions(ssGetSFcnParam(%<::tSimStruct>, %<sfcnPrmIdx>))[%<dimsIdx>] != %)/
%endforeach
)
{
ssSetErrorStatus(%<::tSimStruct>,"Parameter '%<pName>' has to be a %<dimsStr> array.");
return;
}
%endfunction
%function FcnParamMatchesVariableInGlobalScope(varName, param) void
%if ((InlineParameters >= 1) && ...
(( FcnIsParamAlias(param) && ...
FEVAL("existsInGlobalScope", LibGetModelName(), param.WorkspaceVarName)) || ...
(!FcnIsParamAlias(param) && ...
FEVAL("existsInGlobalScope", LibGetModelName(), varName))))
%return TLC_TRUE
%else
%return TLC_FALSE
%endif
%endfunction
%function FcnIsParamAlias(param) void
%if (EXISTS(param.Object.ObjectProperties.CoderInfo.Object.ObjectProperties.Alias))
%return TLC_TRUE
%else
%return TLC_FALSE
%endif
%endfunction
%function FcnGetMatlabSafeDimensions(mdlPrm)
%assign dims = LibGetRecordDimensions(mdlPrm)
%if (SIZE(dims) == [1,1])
%assign dims = [1, %]
%endif
%return dims
%endfunction
%function FcnReshapeValueStr(valueStr, mdlPrm) void
%assign dims = FcnGetMatlabSafeDimensions(mdlPrm)
%assign prmSize = SLibGetSizeOfValueFromParamRec(mdlPrm)
%if (prmSize != dims)
%assign valueStr = "reshape(%<valueStr>"
%foreach dimsIdx = SIZE(dims)[1]
%assign valueStr = "%<valueStr>, %"
%endforeach
%assign valueStr = "%<valueStr>)"
%endif
%return valueStr
%endfunction
%function SLibRegisterDataStores(simStructArg) Output
%if ::CompiledModel.DWorks.NumSFcnWrapperDWorks > 0
{
boolean_T success;
%with ::CompiledModel.DWorks
ssSetNumDataStores(%<simStructArg>, %<NumSFcnWrapperDWorks>);
%foreach idx = NumSFcnWrapperDWorks
%with DWork[SFcnWrapperDWIndices[idx]]
%switch SFcnWrapperMode
%case "read"
%assign rwMode = "SS_READER_ONLY"
%break
%case "write"
%case "readwrite"
%assign rwMode = "SS_READER_AND_WRITER"
%break
%case "none"
%continue
%break
%default
%assert "Unknown SFcnWrapperMode /"%<SFcnWrapperMode>/""
%endswitch
%if GlobalDSM
%assign fcnName = "ssRegisterGlobalDataStoreFromName"
%else
%assign fcnName = "ssRegisterDataStoreFromName"
%endif
%assign dsmName = SFcnWrapperDSMName
%<fcnName>(%<simStructArg>, %<idx>, "%<dsmName>",%<rwMode>, %, &success);
if (!success) return;
%endwith
%endforeach
%endwith
}
%endif
%endfunction
%function SLibGenDataStoreChecks(simStructArg) Output
%if ::CompiledModel.DWorks.NumSFcnWrapperDWorks > 0
{
const SFcnDataStoreInfo *info;
int dIdx;
int compWidth;
%with ::CompiledModel.DWorks
%foreach idx = NumSFcnWrapperDWorks
%assign dw = DWork[SFcnWrapperDWIndices[idx]]
%assign dsName = dw.SFcnWrapperDSMName
%assign dtId = ...
LibGetDataTypeIdAliasedThruToFromId(SLibGetRecordDataTypeId(dw))
ssGetDataStoreInfo(%<simStructArg>,%<idx>,&info);
%if LibIsBuiltInDataType(dtId)
if (ssGetDataTypeIdAliasedThruTo(%<simStructArg>,info->dataTypeId) != %<dtId>) {
ssSetErrorStatus(%<simStructArg>,
"Data-Store Memory '%<dsName>' is registered with a "
"'%<LibGetDataTypeNameFromId(dtId)>' data type.");
return;
}
%endif
compWidth = 1;
for (dIdx=0; dIdxnumDims; dIdx++) {
compWidth *= info->dims[dIdx];
}
if (compWidth != %<SLibDWorkWidth(dw)>) {
ssSetErrorStatus(%<simStructArg>,
"Data-Store Memory '%<dsName>' is registered as a "
"'%<SLibDWorkWidth(dw)>' wide signal.");
return;
}
%assign isComplex = SLibGetRecordIsComplex(dw)
if (info->complex != %<isComplex>) {
%assign none = isComplex ? "" : "none "
ssSetErrorStatus(%<simStructArg>,
"Data-Store Memory '%<dsName>' is registered as a "
"%<none>complex signal.");
return;
}
%endforeach
%endwith
}
%endif
%endfunction
%function AccessDSMWithStorageClass(simStructArg, dwRec, dsmIdx, dsmRW, cscOP) Output
%if SLibGetRecordIsComplex(dwRec)
%assign errMsg = ...
"Data-Store Memory blocks with a non-addressable custom storage " + ...
"class and complex variable type is currently not supported by the " + ...
"ERT S-Function."
%<LibReportError(errMsg)>
%endif
%assign dtName = SLibGetRecordDataTypeName(dwRec, "")
%assign dwWidth = SLibDWorkWidth(dwRec)
%assign optWith = LibOptionalVectorWidth(dwWidth)
%assign optZero = dwWidth > 1 ? "[0]" : ""
%assign varName = "_localDS%<dsmRW>Var"
{
%<dtName> %<varName>%<optWith>;
%if cscOP == "set"
ss%<dsmRW>DataStore(%<simStructArg>, %<dsmIdx>, &_localDS%<dsmRW>Var%<optZero>);
%endif
%if dwWidth > 1
{
int i;
for (i = 0; i < %<dwWidth>; i++) {
%if cscOP == "set"
%<SLibAssignCustomData(dwRec, "[i]", "", "%<varName>[i]")>
%else
%<varName>[i] = ...
%<LibAccessCustomData(dwRec, cscOP, "[i]", "", "")>;
%endif
}
}
%else
%if cscOP == "set"
%<SLibAssignCustomData(dwRec, "", "", varName)>
%else
%<varName> = %<LibAccessCustomData(dwRec, cscOP, "", "", "")>;
%endif
%endif
%if cscOP != "set"
ss%<dsmRW>DataStore(%<simStructArg>, %<dsmIdx>, &_localDS%<dsmRW>Var%<optZero>);
%endif
}
%endfunction
%function SLibGenDataStoreReads(simStructArg) Output
%if ::CompiledModel.DWorks.NumSFcnWrapperDWorks > 0
%foreach idx = ::CompiledModel.DWorks.NumSFcnWrapperDWorks
%assign dwIdx = ::CompiledModel.DWorks.SFcnWrapperDWIndices[idx]
%assign dwRec = ::CompiledModel.DWorks.DWork[dwIdx]
%if LibHasCustomStorage(dwRec) && !LibCustomDataIsAddressable(dwRec)
%<AccessDSMWithStorageClass(simStructArg, dwRec, idx, "ReadFrom", "set")>
%else
%assign sigAddr = SLibGetGlobalDWorkAddr(dwIdx, TLC_FALSE)
ssReadFromDataStore(%<simStructArg>, %<idx>, %<sigAddr>);
%endif
%endforeach
%endif
%endfunction
%function SLibGenDataStoreWrites(simStructArg) Output
%if ::CompiledModel.DWorks.NumSFcnWrapperDWorks > 0
%foreach idx = ::CompiledModel.DWorks.NumSFcnWrapperDWorks
%assign dwIdx = ::CompiledModel.DWorks.SFcnWrapperDWIndices[idx]
%assign dwRec = ::CompiledModel.DWorks.DWork[dwIdx]
%switch dwRec.SFcnWrapperMode
%case "write"
%case "readwrite"
%if LibHasCustomStorage(dwRec) && !LibCustomDataIsAddressable(dwRec)
%<AccessDSMWithStorageClass(simStructArg, dwRec, idx, "WriteTo", "contents")>
%else
%assign sigAddr = SLibGetGlobalDWorkAddr(dwIdx, TLC_FALSE)
ssWriteToDataStore(%<simStructArg>, %<idx>, %<sigAddr>);
%break
%endif
%case "read"
%break
%case "none"
%break
%default
%error "Unknown SFcnWrapperMode /"%<dwRec.SFcnWrapperMode>/""
%endswitch
%endforeach
%endif
%endfunction
%function SLibSetSfcnExternProtos(mdlName) void
%openfile tmpBuf
#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
%<LibExternInFcnDecls()>void *%<mdlName>_malloc(SimStruct *%<::tSimStruct>);
#endif
#ifndef __RTW_UTFREE__
#if defined (MATLAB_MEX_FILE)
%if ::GenCPP
#ifdef __cplusplus
extern "C" {
#endif
%endif
%<LibExternInFcnDecls()>void * utMalloc(size_t);
%<LibExternInFcnDecls()>void utFree(void *);
%if ::GenCPP
#ifdef __cplusplus
}
#endif
%endif
#endif
#endif /* #ifndef __RTW_UTFREE__ */
%closefile tmpBuf
%<SLibCacheCodeToFile("baseMdl_src_extern_fcn_decl", tmpBuf)>
%endfunction
%function SLibSfcnWideInit() void
%assign save_UsingMalloc = UsingMalloc
%assign save_tSimStruct = ::tSimStruct
%assign save_tChildSimStruct = ::tChildSimStruct
%assign save_tConstBlockIOStruct = ::tConstBlockIOStruct
%assign ::tSimStruct = ::tChildSimStruct
%assign ::tConstBlockIOStruct = "%<::tConstBlockIODefine>(%<::tChildSimStruct>)"
%assign ::tChildSimStruct = "childS"
%assign ::CompiledModel.UsingMalloc = 0
%<LibCacheChildSFunctionRegistration(::tChildSimStruct, LibGetModelName())>
%<LibCacheBlockInstanceData()>
%openfile SIDSFunctionRegistration
%<LibDumpSFunctionRegistration()>/
%closefile SIDSFunctionRegistration
%<LibAddToCompiledModel("SIDSFunctionRegistration", SIDSFunctionRegistration)>
%openfile SIDBlockInstanceData
%<LibDumpBlockInstanceData()>/
%closefile SIDBlockInstanceData
%<LibAddToCompiledModel("SIDBlockInstanceData", SIDBlockInstanceData)>
%assign SfcnParamIdx = 0
%assign ::CompiledModel.ModelParameters = ModelParameters + SfcnParamIdx
%<SLibCacheDataBuffers()>
%<LibAddToCompiledModel("SIDLocalSDeclarations", SLibLocalSDeclaration(1))>
%<LibAddToCompiledModel("SIDLocalSRegistration", SLibLocalSRegistration(1))>
%assign ::CompiledModel.UsingMalloc = 1
%<LibCacheChildSFunctionRegistration(::tChildSimStruct, LibGetModelName())>
%<LibCacheBlockInstanceData()>
%openfile MIDSFunctionRegistration
%<LibDumpSFunctionRegistration()>/
%closefile MIDSFunctionRegistration
%<LibAddToCompiledModel("MIDSFunctionRegistration", MIDSFunctionRegistration)>
%openfile MIDBlockInstanceData
%<LibDumpBlockInstanceData()>/
%closefile MIDBlockInstanceData
%<LibAddToCompiledModel("MIDBlockInstanceData", MIDBlockInstanceData)>
%<LibAddToCompiledModel("MIDLocalSDeclarations", SLibLocalSDeclaration(0))>
%<LibAddToCompiledModel("MIDLocalSRegistration", SLibLocalSRegistration(0))>
%assign ::CompiledModel.UsingMalloc = save_UsingMalloc
%assign ::tSimStruct = save_tSimStruct
%assign ::tChildSimStruct = save_tChildSimStruct
%assign ::tConstBlockIOStruct = save_tConstBlockIOStruct
%endfunction
%endif
/% LocalWords: sfcnutil sfcntunable Deriv zc rtwsfcn expandparameter dsm SLib
% LocalWords: sfunction readwrite dw RW decl SDeclarations SRegistration
% LocalWords: MIDS singletasking
%/