%include "sfcnlib.tlc"
%include "prm_sfcntunable.tlc"
%assign ROLL_LIMIT = ::CompiledModel.RollThreshold
%if ::GenerateClassInterface
%assign classConfObj = FcnGetRTWCPPStepPrototypeRecord()
%assign theClassName = classConfObj.ModelClassName
%assign theObjectName = ::CompiledModel.GlobalScope.tModelObject
%endif
%assign tSimStructArg = GlobalScope.tSimStructArg
%<LibAddToCompiledModel("tSimStructArg", tSimStructArg)>
%function GetERTSFcnNumExtInputs() void
%assign numExtInps = ExternalInputs.NumExternalInputs
%if ExportFunctionsMode == 1
%assign rootSystem = System[NumSystems-1]
%foreach id = rootSystem.NumChildSystems
%assign systemId = rootSystem.ChildSystems[id][0]
%assign system = System[systemId]
%if system.Type == "function-call" && system.Exported == "yes"
%assign numExtInps = numExtInps + 1
%endif
%endforeach
%endif
%return numExtInps
%endfunction
%function DumpErtSFcnExternalInputs() Output
%with ExternalInputs
/* Number of input ports */
if (!ssSetNumInputPorts(%<tSimStructArg>, %<GetERTSFcnNumExtInputs()>)) return;
%if NumExternalInputs > 0
%foreach idx = NumExternalInputs
%assign extInp = ExternalInput[idx]
%with extInp
%assign pIdx = idx
%if ExportFunctionsMode == 1
%assign pIdx = extInp.ExportedId - 1
%endif
%assign portWidth = LibGetRecordWidth(extInp)
%assign sampleTime = SampleTime[TID].PeriodAndOffset[0]
%assign offsetTime = SampleTime[TID].PeriodAndOffset[1]
%assign isComplex = LibGetRecordIsComplex(extInp)
%assign dataTypeIdx= LibGetRecordDataTypeId(extInp)
%assign isFrame = FrameData == "yes"
%assign dims = LibGetRecordDimensions(extInp)
%assign numDimensions = SIZE(%<dims>,1)
%assign isBus = LibDataTypeIsBus(dataTypeIdx)
%if ISFIELD(extInp, "HasVarDims")
ssSetInputPortRequiredContiguous(%<tSimStructArg>, %<pIdx>, %);
%if isBus == TLC_FALSE
ssSetInputPortDimensionsMode(%<tSimStructArg>, %<pIdx>, VARIABLE_DIMS_MODE)
%endif
%endif
%<SLibDumpSfcnInpDims("%<tSimStructArg>",pIdx,portWidth,numDimensions,dims)>
%<SLibSfunRegisterAndSetDataType("input","%<tSimStructArg>",pIdx,dataTypeIdx,"namedObject")>
ssSetBusInputAsStruct(%<tSimStructArg>, %<pIdx>, 1);
%if isComplex
ssSetInputPortComplexSignal(%<tSimStructArg>, %<pIdx>, COMPLEX_YES);
%endif
%if isFrame
ssSetInputPortFrameData(%<tSimStructArg>, %<pIdx>, FRAME_YES);
%endif
ssSetInputPortDirectFeedThrough(%<tSimStructArg>, %<pIdx>, 1);
%if AllSampleTimesInherited == "yes" || ExportFunctionsMode == 1
ssSetInputPortSampleTime(%<tSimStructArg>, %<pIdx>, -1);
%else
ssSetInputPortSampleTime(%<tSimStructArg>, %<pIdx>, %<sampleTime>);
ssSetInputPortOffsetTime(%<tSimStructArg>, %<pIdx>, %<offsetTime>);
%endif
%if TYPE(TID) == "Number"
%assign ::CompiledModel.IsSampleTimeOnPort[TID]=1
%endif
%endwith
%endforeach
%endif
%endwith
%if ExportFunctionsMode == 1
/* Register exported function-call wrappers. */
%assign rootSystem = System[NumSystems-1]
%foreach id = rootSystem.NumChildSystems
%assign systemId = rootSystem.ChildSystems[id][0]
%assign system = System[systemId]
%if system.Type == "function-call" && system.Exported == "yes"
%assign pIdx = System[systemId].ExportedId - 1
ssSetInputPortDataType(%<tSimStructArg>, %<pIdx>, SS_FCN_CALL);
ssSetInputPortWidth(%<tSimStructArg>, %<pIdx>, 1);
ssSetInputPortSampleTime(%<tSimStructArg>, %<pIdx>, -1);
ssSetInputPortDirectFeedThrough(%<tSimStructArg>, %<pIdx>, 1);
ssExportOutputFcn(%<tSimStructArg>, %<pIdx>, mdlExportedOutputFcn%<pIdx>);
%if !LibSystemFcnIsEmpty(System[systemId],"Enable")
ssExportEnableFcn(%<tSimStructArg>, %<pIdx>, mdlExportedEnableFcn%<pIdx>);
%endif
%if !LibSystemFcnIsEmpty(System[systemId],"Disable")
ssExportDisableFcn(%<tSimStructArg>, %<pIdx>, mdlExportedDisableFcn%<pIdx>);
%endif
%endif
%endforeach
%openfile latchBuffer
%if NumModelInputs > 0
%foreach extIdx = ExternalInputs.NumExternalInputs
%assign inputIsLatched = 1
%assign rootSystem = System[NumSystems-1]
%foreach id = rootSystem.NumChildSystems
%assign sysId = rootSystem.ChildSystems[id][0]
%assign system = System[sysId]
%if system.Type == "function-call" && system.Exported == "yes" && ...
ISFIELD(system, "NonLatchedInputs")
%foreach latchIdx = SIZE(system.NonLatchedInputs, 1)
%if extIdx == system.NonLatchedInputs[latchIdx]
%assign inputIsLatched = 0
%break
%endif
%endforeach
%if inputIsLatched == 0
%break
%endif
%endif
%endforeach
%if inputIsLatched == 1
%assign sfcnIdx = ExternalInputs.ExternalInput[extIdx].ExportedId - 1
ssInportIsLatched(%<tSimStructArg>, %<sfcnIdx>);
%endif
%endforeach
%endif
%closefile latchBuffer
%if !WHITE_SPACE(latchBuffer)
/* Declare latched input ports. */
%<latchBuffer>
%endif
%endif
%endfunction
%function DumpErtSFcnExternalOutputs() Output
%with ExternalOutputs
/* Number of output ports */
if (!ssSetNumOutputPorts(%<tSimStructArg>, %<NumExternalOutputs>)) return;
%if NumExternalOutputs > 0
%foreach idx = ExternalOutputs.NumExternalOutputs
%assign extOut = ExternalOutputs.ExternalOutput[idx]
%assign sysIdx = extOut.Block[0]
%assign blkIdx = extOut.Block[1]
%assign outportBlock = System[sysIdx].Block[blkIdx]
%with System[sysIdx]
%with outportBlock
%assign portWidth = LibBlockInputSignalWidth(0)
%assign dataTypeIdx = LibBlockInputSignalDataTypeId(0)
%assign numDimensions = LibBlockInputSignalNumDimensions(0)
%assign isComplex = LibBlockInputSignalIsComplex(0)
%assign isFrame = extOut.FrameData == "yes"
%assign isBus = LibDataTypeIsBus(dataTypeIdx)
%if TYPE(TID) == "Number"
%assign sampleTime = SampleTime[TID].PeriodAndOffset[0]
%assign offsetTime = SampleTime[TID].PeriodAndOffset[1]
%else
%assign sampleTime = "mxGetInf()"
%assign offsetTime = 0
%endif
%if ISFIELD(extOut, "HasVarDims")
%if GenerateClassInterface
%<SLibReportErrorWithId("RTW:tlc:ERTSfcnCPPVarSize")>
%endif
%if !isBus
ssSetOutputPortDimensionsMode(%<tSimStructArg>, %<idx>, VARIABLE_DIMS_MODE);
%endif
%endif
%assign dims = LibBlockInputSignalDimensions(0)
%<SLibDumpSfcnOutDims("%<tSimStructArg>",idx,portWidth,numDimensions,dims)>
%<SLibSfunRegisterAndSetDataType("output","%<tSimStructArg>",idx,dataTypeIdx,"namedObject")>
%assign locBusObj = LibBlockParamSetting("Outport", "BusObject")
%if !WHITE_SPACE(locBusObj)
ssSetBusObjectName(%<tSimStructArg>, %<idx>, (void *)"%<locBusObj>");
%assign locOutStruct = LibBlockParamSetting("Outport", "OutputAsStructure")
ssSetBusOutputAsStruct(%<tSimStructArg>, %<idx>, %<locOutStruct>);
%endif
%if isComplex
ssSetOutputPortComplexSignal(%<tSimStructArg>, %<idx>, COMPLEX_YES);
%endif
%if isFrame
ssSetOutputPortFrameData(%<tSimStructArg>, %<idx>, FRAME_YES);
%endif
%if ExportFunctionsMode == 1
ssSetOutputPortOptimOpts(%<tSimStructArg>, %<idx>, SS_NOT_REUSABLE_AND_GLOBAL);
%endif
%if AllSampleTimesInherited == "yes" || ExportFunctionsMode
ssSetOutputPortSampleTime(%<tSimStructArg>, %<idx>, -1);
%else
ssSetOutputPortSampleTime(%<tSimStructArg>, %<idx>, %<sampleTime>);
ssSetOutputPortOffsetTime(%<tSimStructArg>, %<idx>, %<offsetTime>);
%endif
%if TYPE(TID) == "Number"
%assign ::CompiledModel.IsSampleTimeOnPort[TID]=1
%endif
%endwith
%endwith
%endforeach
%undef extOut, sysIdx, blkIdx
%endif
%endwith
%endfunction
%function GetInputPtrTypeFromId(id) void
%assign storageDataType = ...
LibGetDataTypeStorageIdFromId(...
LibGetDataTypeIdAliasedThruToFromId(id))
%switch storageDataType
%case tSS_DOUBLE
%return "InputRealPtrsType"
%case tSS_SINGLE
%return "InputReal32PtrsType"
%case tSS_UINT8
%return "InputUInt8PtrsType"
%case tSS_UINT16
%return "InputUInt16PtrsType"
%case tSS_UINT32
%return "InputUInt32PtrsType"
%case tSS_BOOLEAN
%return "InputBooleanPtrsType"
%case tSS_INT8
%return "InputInt8PtrsType"
%case tSS_INT16
%return "InputInt16PtrsType"
%case tSS_INT32
%return "InputInt32PtrsType"
%default
%if LibIsStructDataType(id)
%return "const char * const *"
%else
%return "const %<LibGetDataTypeNameFromId(id)> * const *"
%endif
%endswitch
%endfunction
%function GenerateImportedExternalSignalDefinition(signal) Output
%if signal.StorageClass == "ImportedExtern" || ...
signal.StorageClass == "ImportedExternPointer"
%assign dataType = SLibGetRecordDataTypeName(signal, "")
%assign optWidth = LibOptionalVectorWidth(LibGetRecordWidth(signal))
%assign id = LibGetRecordIdentifier(signal)
%if signal.StorageClass == "ImportedExternPointer"
/* %<::CompiledModel.Name> imported external pointer */
static %<dataType> %<id>_value%<optWidth>;
%<dataType> *%<id> = /
%if LibGetRecordWidth(signal) == 1
&%<id>_value;
%else
%<id>_value;
%endif
%else
/* %<::CompiledModel.Name> imported external `*/
%<dataType> %<id>%<optWidth>;
%endif
%endif
%endfunction
%function GenerateImportedExternalParameterDefinition(mdlPrm) Output
%assign dataType = SLibGetRecordDataTypeName(mdlPrm, "")
%assign numOfElements = LibBlockParameterWidth(mdlPrm)
%assign optWidth = LibOptionalVectorWidth(numOfElements)
%assign id = LibGetRecordIdentifier(mdlPrm)
%if mdlPrm.StorageClass == "ImportedExternPointer"
/* %<::CompiledModel.Name> imported external pointer */
static %<dataType> %<id>_value%<optWidth>;
%<dataType> *%<id> = /
%if numOfElements == 1
&%<id>_value;
%else
%<id>_value;
%endif
%else
/* %<::CompiledModel.Name> imported external `*/
%<dataType> %<id>%<optWidth>;
%endif
%endfunction
%function DumpImportedExternalSignalDeclaration() Output
%if ExternalInputs.NumImportedExternSignals > 0 || ...
ExternalInputs.NumImportedExternPointerSignals > 0
/* Imported external inputs */
%foreach idx = ExternalInputs.NumExternalInputs
%assign extInp = ExternalInputs.ExternalInput[idx]
%<GenerateImportedExternalSignalDefinition(extInp)>
%endforeach
%endif
%if BlockOutputs.NumImportedExternSignals > 0 || ...
BlockOutputs.NumImportedExternPointerSignals > 0
/* Imported output signals */
%foreach boIdx = BlockOutputs.NumExternalBlockOutputs
%assign bo = BlockOutputs.ExternalBlockOutput[boIdx]
%<GenerateImportedExternalSignalDefinition(bo)>
%endforeach
%endif
%foreach dwIdx = DWorks.NumDWorks
%assign dw = DWorks.DWork[dwIdx]
%<GenerateImportedExternalSignalDefinition(dw)>
%endforeach
%endfunction
%function DumpImportedExternalParameterDeclaration() Output
%with ::CompiledModel.ModelParameters
%if (NumImportedExtern + NumImportedExternPointer) > 0
/* Imported parameters */
%foreach parIdx = NumParameters
%if ((Parameter[parIdx].StorageClass == "ImportedExtern" || ...
Parameter[parIdx].StorageClass == "ImportedExternPointer") && ...
!SLibIsModelParamConst(Parameter[parIdx]))
%<GenerateImportedExternalParameterDefinition(Parameter[parIdx])>
%endif
%endforeach
%endif
%endwith
%endfunction
%function GenerateTmpSFunctionInputSignalDef(idx) Output
%assign extInp = ExternalInputs.ExternalInput[idx]
%assign sfcnIdx = idx
%if ExportFunctionsMode == 1
%assign sfcnIdx = extInp.ExportedId - 1
%endif
%with extInp
%assign dataTypeIdx = SLibGetRecordDataTypeId(extInp)
%assign dataTypeEnum = LibGetDataTypeEnumFromId(dataTypeIdx)
%if dataTypeEnum == "SS_FCN_CALL"
%return
%endif
((%<GetInputPtrTypeFromId(dataTypeIdx)>) ...
ssGetInputPortSignalPtrs(%<tSimStructArg>, %<sfcnIdx>))/
%endwith
%endfunction
%function GenerateSFunctionInputSignalDefinition(prefix,idx) Output
%assign extInp = ExternalInputs.ExternalInput[idx]
%assign dataTypeIdx = SLibGetRecordDataTypeId(extInp)
%assign dataTypeEnum = LibGetDataTypeEnumFromId(dataTypeIdx)
%if dataTypeEnum == "SS_FCN_CALL"
%return
%endif
%if !ISFIELD(extInp, "HasVarDims")
%<GetInputPtrTypeFromId(dataTypeIdx)> %<prefix>%<idx> = ...
(%<GetInputPtrTypeFromId(dataTypeIdx)>) ...
ssGetInputPortSignalPtrs(%<tSimStructArg>, %<idx>);
%else
%assign storageType = LibGetDataTypeStorageIdFromId(...
LibGetDataTypeIdAliasedThruToFromId(dataTypeIdx))
%if LibIsStructDataType(storageType)
%assign dataType = "char"
%else
%assign dataType = LibGetDataTypeNameFromId(storageType)
%endif
const %<dataType> *%<prefix>%<idx> = ...
(const %<dataType> *) ...
ssGetInputPortSignal(%<tSimStructArg>, %<idx>);
%if ISFIELD(extInp, "SizeVarGroupIdx")
%assign cgTypeIdx = SLibCGVarGroupMemberCGTypeIdx(...
extInp.SizeVarGroupIdx[0], ...
extInp.SizeVarGroupIdx[1])
%elseif ISFIELD(extInp,"DimSizeDWork")
%assign cgTypeIdx = LibGetRecordCGTypeIdx(::CompiledModel.DWorks.DWork[extInp.DimSizeDWork])
%endif
%if EXISTS(cgTypeIdx)
const %<LibCGTypeName(cgTypeIdx)> * %<prefix>%<idx>_Size = ...
(const %<LibCGTypeName(cgTypeIdx)> *) ...
& ...
ssGetCurrentInputPortDimensions(%<tSimStructArg>, %<idx>, 0);
%endif
%endif
%endfunction
%function GenerateTmpSFunctionOutputSignalDef(idx) Output
%assign extOut = ExternalOutputs.ExternalOutput[idx]
%assign sysIdx = extOut.Block[0]
%assign blkIdx = extOut.Block[1]
%assign outportBlock = System[sysIdx].Block[blkIdx]
%with System[sysIdx]
%with outportBlock
%assign dTypeId = LibBlockInputSignalDataTypeId(0)
%assign isStruct = LibIsStructDataType(dTypeId)
%if isStruct
%assign dataType = "char"
%else
%assign dataType = LibBlockInputSignalDataTypeName(0, "")
%endif
((%<dataType> *)ssGetOutputPortSignal(%<tSimStructArg>, %<idx>))/
%endwith
%endwith
%endfunction
%function GenerateSFunctionOutputSignalDefinition(prefix,idx) Output
%assign extOut = ExternalOutputs.ExternalOutput[idx]
%assign sysIdx = extOut.Block[0]
%assign blkIdx = extOut.Block[1]
%assign outportBlock = System[sysIdx].Block[blkIdx]
%with System[sysIdx]
%with outportBlock
%assign dTypeId = LibBlockInputSignalDataTypeId(0)
%assign isStruct = LibIsStructDataType(dTypeId)
%if isStruct
%assign dataType = "char"
%else
%assign dataType = LibBlockInputSignalDataTypeName(0, "")
%endif
%<dataType> *%<prefix>%<idx> = (%<dataType> *)ssGetOutputPortSignal(%<tSimStructArg>, %<idx>);
%if ISFIELD(extOut, "HasVarDims")
%if ISFIELD(extOut, "SizeVarGroupIdx")
%assign cgTypeIdx = SLibCGVarGroupMemberCGTypeIdx(...
extOut.SizeVarGroupIdx[0], ...
extOut.SizeVarGroupIdx[1])
%assign width = LibCGTypeWidth(cgTypeIdx)
%<LibCGTypeName(cgTypeIdx)> * %<prefix>%<idx>_Size = ...
(%<LibCGTypeName(cgTypeIdx)> *) ...
& ...
ssGetCurrentOutputPortDimensionsAndRecordIndex(%<tSimStructArg>, %<idx>, 0);
%endif
%endif
%endwith
%endwith
%endfunction
%function FcnIndexSimStructCallResult(isContiguous, isComplex, elemIdx) void
%if isContiguous
%if !isComplex
%assign indexReal = "[%<elemIdx>]"
%assign indexImg = ""
%else
%assign indexReal = "[2*%<elemIdx>]"
%assign indexImg = "[2*%<elemIdx>+1]"
%endif
%else
%assign indexReal = "[%<elemIdx>][0]"
%assign indexImg = "[%<elemIdx>][1]"
%endif
%return ["%<indexReal>", "%<indexImg>"]
%endfunction
%function GenerateTmpInputSignalConditioning(tmpVar, rolllimit, idx) Output
%if MultiInstanceERTCode && !RootIOStructures
%assign localUQualifier = "_"
%else
%assign localUQualifier = "."
%endif
%assign extInp = ExternalInputs.ExternalInput[idx]
%assign fpcWithArgs = TLC_FALSE
%if FcnConditionRootInputsAsSeparateArgs()
%assign localVarName = "localIn%<idx>"
%assign fpcWithArgs = TLC_TRUE
%endif
%assign portWidth = LibGetRecordWidth(extInp)
%assign isComplex = LibGetRecordIsComplex(extInp)
%assign dotReal = "." + tRealPart
%assign dotImag = "." + tImagPart
%assign dTypeId = SLibGetRecordDataTypeId(extInp)
%assign dataTypeEnum = LibGetDataTypeEnumFromId(dTypeId)
%if dataTypeEnum == "SS_FCN_CALL"
%return
%endif
%assign nameOrQualifier = fpcWithArgs ? localVarName : localUQualifier
%if ISFIELD(extInp, "SizeVarGroupIdx")
%assign sizeCGType = SLibCGVarGroupMemberCGTypeIdx(...
extInp.SizeVarGroupIdx[0], ...
extInp.SizeVarGroupIdx[1])
%elseif ISFIELD(extInp, "DimSizeDWork")
%assign sizeCGType = LibGetRecordCGTypeIdx(::CompiledModel.DWorks.DWork[extInp.DimSizeDWork])
%endif
%if EXISTS(sizeCGType)
%assign sizeVecLen = LibCGTypeWidth(sizeCGType)
%if LibIsStructDataType(dTypeId) && portWidth == 1 ...
&& sizeVecLen == 1
%<SLibGetInportSize(idx, 1, "", -1, "", 0)> = *%<tmpVar>_Size;
%else
%foreach dimIdx = sizeVecLen
%<SLibGetInportSize(idx, sizeVecLen, "", -1, "", dimIdx)> = %<tmpVar>_Size[%<dimIdx>];
%endforeach
%endif
%endif
%if LibIsStructDataType(dTypeId)
%if ISFIELD(extInp, "HasVarDims")
%assign rhs = tmpVar
%else
%assign rhs = "&" + tmpVar + "[0][0]"
%endif
%<FcnGenSigAssignment(extInp, 0, "", nameOrQualifier,rhs,rolllimit)>
%elseif portWidth < rolllimit
%assign varDims = ISFIELD(extInp, "HasVarDims")
%foreach sigIdx = portWidth
%assign indices = FcnIndexSimStructCallResult(varDims, isComplex, sigIdx)
%assign indexReal = indices[0]
%assign indexImg = indices[1]
%assign rhs = tmpVar + indexReal
%if isComplex
%<FcnGenSigAssignment(extInp, sigIdx, dotReal, nameOrQualifier,rhs,rolllimit)>
%assign rhs = tmpVar + indexImg
%<FcnGenSigAssignment(extInp, sigIdx, dotImag, nameOrQualifier,rhs,rolllimit)>
%else
%<FcnGenSigAssignment(extInp, sigIdx, "", nameOrQualifier,rhs,rolllimit)>
%endif
%endforeach
%else
%assign sigIdx = "i"
%assign varDims = ISFIELD(extInp, "HasVarDims")
%assign indices = FcnIndexSimStructCallResult(varDims, isComplex, sigIdx)
%assign indexReal = indices[0]
%assign indexImg = indices[1]
%assign rhs = tmpVar + indexReal
{
int i = 0;
for(i = 0; i < %<portWidth>; i++) {
%if isComplex
%<FcnGenSigAssignment(extInp, sigIdx, dotReal, nameOrQualifier,rhs,rolllimit)>
%assign rhs = tmpVar + indexImg
%<FcnGenSigAssignment(extInp, sigIdx, dotImag, nameOrQualifier,rhs,rolllimit)>
%else
%<FcnGenSigAssignment(extInp, sigIdx, "", nameOrQualifier,rhs,rolllimit)>
%endif
}
}
%endif
%endfunction
%function GenerateInputSignalConditioning(prefix, rolllimit,idx) Output
%assign tmpVar = prefix + "%<idx>"
%<GenerateTmpInputSignalConditioning(tmpVar,rolllimit,idx)>
%endfunction
%function FcnGenSigAssignment(sigRec,sigIdx,reim,localUQualifier,rhs,rolllimit) void
%assign dTypeId = SLibGetRecordDataTypeId(sigRec)
%assign isStructOrBus = LibIsStructDataType(dTypeId)
%assign isComplex = LibGetRecordIsComplex(sigRec)
%assign id = LibGetRecordIdentifier(sigRec)
%with sigRec
%if CGMODEL_ACCESS("CGModel.isIndividualFunctionMappingEnabled")
%assign isFPC = CGMODEL_ACCESS("CGModel.FunctionPrototype.hasFunctionPrototype")
%else
%assign isFPC = ISFIELD(::CompiledModel, "RTWFcnClass")
%endif
%if isFPC && ...
StorageClass != "Auto"
%assign errTxt = ...
"Model step function prototype control does not support " + ...
"non-Auto custom storage classes for root-level I/O ports."
%<LibReportFatalError(errTxt)>
%endif
%if LibGetRecordWidth(sigRec) == 1
%assign sigIdx = ""
%elseif isStructOrBus
%assign sigIdx = ""
%else
%assign sigIdx = "[%<sigIdx>]"
%endif
%if StorageClass == "Custom"
%if (CustomStorageClassVersion > 1)
%if rhs[0] == "&"
%assign rhs = "(*((" + LibGetDataTypeNameFromId(dTypeId) + "*)" + rhs + "))"
%endif
%return LibAccessCustomData(sigRec, "set", sigIdx, reim, rhs)
%endif
%assign fullId = LibCustomData(sigRec,"contents",sigIdx,reim)
%else
%switch StorageClass
%case "Auto"
%if !SLibFcnProtoCtrlActive() && ...
!GenerateClassInterface
%assign baseId = LibGetExternalInputStruct() + ...
localUQualifier + id
%elseif GenerateClassInterface
%if classConfObj.hasGlobalAccessForInport
%assign baseId = ::CompiledModel.GlobalScope.tModelObject + ...
"." + LibGetExternalInputStruct() + "." + id
%else
%assign baseId = localUQualifier
%endif
%else
%assign baseId = localUQualifier
%endif
%break
%case "ImportedExternPointer"
%assign baseId = id + "_value"
%break
%default
%assign baseId = id
%break
%endswitch
%assign fullId = baseId + sigIdx + reim
%endif
%endwith
%if isStructOrBus
%assign retVal = ""
%openfile retVal
%<SLibAssignSLStructToUserStructND(dTypeId, LibGetRecordWidth(sigRec), ...
fullId, rhs, Matrix(1,1) [0], 0, isComplex)>
%closefile retVal
%return retVal
%else
%return fullId + " = " + rhs + ";"
%endif
%endfunction
%function GenerateTmpOutputSignalConditioning(tmpVar, rolllimit,idx) Output
%if MultiInstanceERTCode && !RootIOStructures
%assign localYQualifier = "_"
%else
%assign localYQualifier = "."
%endif
%assign extOut = ExternalOutputs.ExternalOutput[idx]
%assign sysIdx = extOut.Block[0]
%assign blkIdx = extOut.Block[1]
%assign outportBlock = System[sysIdx].Block[blkIdx]
%assign id = LibGetRecordIdentifier(outportBlock)
%assign fpcWithArgs = TLC_FALSE
%if FcnConditionRootOutputsAsSeparateArgs()
%assign localVarName = "localOut%<idx>"
%assign fpcWithArgs = TLC_TRUE
%endif
%with System[sysIdx]
%assign id = LibGetRecordIdentifier(outportBlock)
%with outportBlock
%assign portWidth = LibBlockInputSignalWidth(0)
%assign dTypeId = LibBlockInputSignalDataTypeId(0)
%assign isStructOrBus = LibIsStructDataType(dTypeId)
%if ISFIELD(extOut, "SizeVarGroupIdx")
%assign sizeCGType = SLibCGVarGroupMemberCGTypeIdx(...
extOut.SizeVarGroupIdx[0], ...
extOut.SizeVarGroupIdx[1])
%assign sizeVecLen = LibCGTypeWidth(sizeCGType)
%if isStructOrBus && portWidth == 1 ...
&& sizeVecLen == 1
*%<tmpVar>_Size = %<SLibGetOutportSize(idx, 1, "", -1, "", 0)>;
%else
%foreach dimIdx = sizeVecLen
%<tmpVar>_Size[%<dimIdx>] = %<SLibGetOutportSize(idx, sizeVecLen, "", -1, "", dimIdx)>;
%endforeach
%endif
%endif
%if isStructOrBus
%assign dst = "&%<tmpVar>[0]"
%if !fpcWithArgs
%assign objPrefix=""
%if GenerateClassInterface
%assign objPrefix = "%<::CompiledModel.GlobalScope.tModelObject>."
%endif
%if SLibExternalOutputIsVirtual(outportBlock)
%assign src = LibBlockInputSignal(0, "", "", 0)
%else
%assign src = "%<LibGetExternalOutputStruct()>%<localYQualifier>%<id>"
%endif
%assign src = "%<objPrefix>%<src>"
%else
%assign src = localVarName
%endif
%assign isComplex = LibGetRecordIsComplex(extOut)
%if SLibExternalOutputIsVirtual(outportBlock) && (ISEQUAL(portWidth,1)==TLC_FALSE)
%assign src = "(%<LibBlockInputSignalAddr(0, "", "", 0)>)"
%endif
%<SLibAssignUserStructToSLStructND(dTypeId, portWidth, dst, src, Matrix(1,1) [0], 0, isComplex)>
%else
%if portWidth == 1
%<tmpVar>[0] = /
%if !fpcWithArgs
%assign objPrefix=""
%if GenerateClassInterface
%assign objPrefix = "%<::CompiledModel.GlobalScope.tModelObject>."
%endif
%if SLibExternalOutputIsVirtual(outportBlock)
%<objPrefix>%<LibBlockInputSignal(0, "", "", 0)>;
%else
%<objPrefix>%<LibGetExternalOutputStruct()>%<localYQualifier>%<id>;
%endif
%else
%<localVarName>;
%endif
%elseif portWidth < rolllimit
%foreach sigIdx = portWidth
%<tmpVar>[%<sigIdx>] = /
%if !fpcWithArgs
%assign objPrefix=""
%if GenerateClassInterface
%assign objPrefix = "%<::CompiledModel.GlobalScope.tModelObject>."
%endif
%if SLibExternalOutputIsVirtual(outportBlock)
%<objPrefix>%<LibBlockInputSignal(0, "", "", sigIdx)>;
%else
%<objPrefix>%<LibGetExternalOutputStruct()>%<localYQualifier>%<id>[%<sigIdx>];
%endif
%else
%<localVarName>[%<sigIdx>];
%endif
%endforeach
%else
{
int i = 0;
for(i = 0; i < %<portWidth>; i++) {
%<tmpVar>[i] = /
%if !fpcWithArgs
%assign objPrefix=""
%if GenerateClassInterface
%assign objPrefix = "%<::CompiledModel.GlobalScope.tModelObject>."
%endif
%if SLibExternalOutputIsVirtual(outportBlock)
%<objPrefix>%<LibBlockInputSignal(0, "i", "", 0)>;
%else
%<objPrefix>%<LibGetExternalOutputStruct()>%<localYQualifier>%<id>[i];
%endif
%else
%<localVarName>[i];
%endif
}
}
%endif
%endif
%endwith
%endwith
%endfunction
%function GenerateOutputSignalConditioning(prefix, rolllimit,idx) Output
%<GenerateTmpOutputSignalConditioning("%<prefix>%<idx>",rolllimit,idx)>
%endfunction
%function DumpTimeConditioningCode(localTid) Output
int_T %<localTid> = %;
%foreach idx = NumRuntimeExportedRates
if (ssIsSampleHit(%<tSimStructArg>, %<idx>, %<LibTID()> )) {
%<localTid> = %<idx>;
}
%endforeach
%endfunction
%function FcnGenModelParameterAssignment(mdlPrm, idx, reim, rhs) Output
%if mdlPrm.StorageClass == "Custom"
%if mdlPrm.CustomStorageClassVersion > 1
%<LibAccessCustomData(mdlPrm, "set", idx, reim, rhs)>
%else
%assign lhs = LibCustomData(mdlPrm, "contents", idx, reim)
%<lhs> = %<rhs>;
%endif
%else
%assign lhs = FcnAccessModelParameter(mdlPrm, idx) + reim
%<lhs> = %<rhs>;
%endif
%endfunction
%function CopyRunTimeStructParamToGlobalVar(mdlPrm, rtpIdx) Output
%assign dtId = mdlPrm.OriginalDataTypeIdx
%assert(LibDataTypeIsBus(dtId) == TLC_TRUE)
%assign tmpVarDType = "const char *"
%assign tmpVar="rtp_%<rtpIdx>"
%assign rhs = "((%<tmpVarDType>) ssGetRunTimeParamInfo(%<tSimStructArg>,%<rtpIdx>)->data)"
%if mdlPrm.StorageClass == "Custom"
%assign isGetSetStorageClass = (mdlPrm.CustomStorageClassVersion > 1) && ...
!(LibGetRTWInfoObjectPackage(mdlPrm) == "AUTOSAR")
%assert(!isGetSetStorageClass)
%assign paramVar= LibCustomData(mdlPrm, "contents","", "")
%else
%assign paramVar= FcnAccessModelParameter(mdlPrm,"")
%endif
{
%<tmpVarDType> %<tmpVar> = %<rhs>;
%<SLibAssignSLStructToUserStructND(dtId, LibBlockParameterWidth(mdlPrm), ...
paramVar, tmpVar, Matrix(1,1) [0], 0, LibBlockParameterIsComplex(mdlPrm))>
}
%endfunction
%function CopyRunTimeParamToGlobalVar(mdlPrm, rtpIdx, index) Output
%assign isBus = LibDataTypeIsBus(mdlPrm.OriginalDataTypeIdx)
%if isBus
%assert(index == "")
%return CopyRunTimeStructParamToGlobalVar(mdlPrm, rtpIdx)
%endif
%assign rtpDType = LibGetDataTypeNameFromId(mdlPrm.OriginalDataTypeIdx)
%assign rtpPtr = "((%<rtpDType> *) ssGetRunTimeParamInfo(%<tSimStructArg>,%<rtpIdx>)->data)"
%if index == ""
%assign LHSIdx = ""
%assign realRHS = "(%<rtpPtr>[0])"
%assign imagRHS = "(%<rtpPtr>[1])"
%else
%assign LHSIdx = "[%<index>]"
%if SLibGetRecordIsComplex(mdlPrm)
%assign realRHS = "(%<rtpPtr>[2*%<index>])"
%assign imagRHS = "(%<rtpPtr>[2*%<index>+1])"
%else
%assign realRHS = "(%<rtpPtr>[%<index>])"
%endif
%endif
%if SLibGetRecordIsComplex(mdlPrm)
%assign realSuffix = ".%<tRealPart>"
%assign imagSuffix = ".%<tImagPart>"
%<FcnGenModelParameterAssignment(mdlPrm, LHSIdx, realSuffix, realRHS)>
%<FcnGenModelParameterAssignment(mdlPrm, LHSIdx, imagSuffix, imagRHS)>
%else
%<FcnGenModelParameterAssignment(mdlPrm, LHSIdx, "", realRHS)>
%endif
%endfunction
%function FcnGenErtSFcnParamChecks(mdlPrm, sfcnPrmIdx) Output
%assign pName = LibGetRecordIdentifier(mdlPrm)
%assign dims = FcnGetMatlabSafeDimensions(mdlPrm)
%assign nDims = SIZE(dims,1)
%assign dimsStr = "%"
%foreach dimsIdx = (nDims-1)
%assign dimsStr = dimsStr + ", %"
%endforeach
%if SLibGetRecordIsComplex(mdlPrm)
%assign isComplex = "true"
%else
%assign isComplex = "false"
%endif
/* Check attributes of parameter '%<pName>' */
{
int dimsArray[%<nDims>] = {%<dimsStr>};
ssCheckSFcnParamValueAttribs(%<tSimStructArg>, %<sfcnPrmIdx>, "%<pName>", DYNAMICALLY_TYPED,
%<nDims>, dimsArray, %<isComplex>);
}
%endfunction
%function FcnGenErtSFcnCheckParamsFcn(numTunablePrms, prmIdxVec) Output
%if numTunablePrms > 0
%with ModelParameters
%assign fcnName = "mdlCheckParameters"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%assign fcnAbstract = "This function checks the attributes of tunable parameters."
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.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]]
%<FcnGenErtSFcnParamChecks(mdlPrm, sfcnPrmIdx)>
%endforeach
}
#endif /* MDL_CHECK_PARAMETERS */
%endwith
%endif
%endfunction
%function FcnGenErtSFcnRunTimePrmReg(numTunablePrms, prmIdxVec, callToLocalFcn) Output
%if numTunablePrms > 0
%with ModelParameters
/* Set number of run-time parameters */
if (!ssSetNumRunTimeParams(%<tSimStructArg>, %<numTunablePrms>)) return;
%foreach sfcnPrmIdx = numTunablePrms
%assign mdlPrm = Parameter[prmIdxVec[sfcnPrmIdx]]
%assign prmName = "P%<sfcnPrmIdx>_%<LibGetRecordIdentifier(mdlPrm)>"
%assign dtId = mdlPrm.OriginalDataTypeIdx
%assign dtStr = ""
%if !ISEMPTY(mdlPrm.WorkspaceVarName)
{
%if LibIsBuiltInDataType(dtId)
%assign dtStr = LibGetDataTypeEnumFromId(dtId)
%elseif LibIsEnumDataType(dtId)
%assign dtName = LibGetDataTypeNameFromId(dtId)
DTypeId dtId = INVALID_DTYPE_ID;
ssRegisterTypeFromNamedObject(%<tSimStructArg>, "%<dtName>", &dtId);
if(dtId == INVALID_DTYPE_ID) return;
%assign dtStr = "dtId"
%elseif LibDataTypeIsBus(dtId)
%assign dtChecksum = DataTypes.DataType[dtId].StructDtChecksum
%assign dtChecksumStr = ...
"%,%,%,%"
uint32_T dtChecksum[4] = {%<dtChecksumStr>};
DTypeId dtId = INVALID_DTYPE_ID;
ssGetSFcnParamDataType(%<tSimStructArg>, %<sfcnPrmIdx>, &dtId);
if(dtId == INVALID_DTYPE_ID) return;
ssCheckStructParamChecksum(%<tSimStructArg>, %<sfcnPrmIdx>, dtChecksum);
%assign dtStr = "dtId"
%elseif LibIsHalfDataType(dtId)
%assign dtOverride = 0
DTypeId halfID = ssRegisterDataTypeHalfPrecision(%<tSimStructArg>, %<dtOverride>);
if (halfID == INVALID_DTYPE_ID) return;
ssRegDlgParamAsRunTimeParam(%<tSimStructArg>, %<sfcnPrmIdx>, %<sfcnPrmIdx>, /
"%<prmName>", halfID);
%endif
%if !WHITE_SPACE(dtStr)
ssRegDlgParamAsRunTimeParam(%<tSimStructArg>, %<sfcnPrmIdx>, %<sfcnPrmIdx>, /
"%<prmName>", %<dtStr>);
%else
%assign curDT = FixPt_GetDataTypeFromIndex(dtId)
%if curDT.IsFixedPoint
%assign dtOverride = 0
%if FixPt_DataTypeIsFloat(curDT)
DTypeId fixptDTId = ssRegisterDataTypeFxpScaledDouble(%<tSimStructArg>, /
%<curDT.IsSigned>, %<curDT.RequiredBits>, /
(double) %<curDT.FracSlope>, %<curDT.FixedExp>, /
(double) %<curDT.Bias>, %<dtOverride>);
if (fixptDTId == INVALID_DTYPE_ID) return;
ssRegDlgParamAsRunTimeParam(%<tSimStructArg>, %<sfcnPrmIdx>, %<sfcnPrmIdx>, /
"%<prmName>", fixptDTId);
%else
DTypeId fixptDTId = ssRegisterDataTypeFxpFSlopeFixExpBias(%<tSimStructArg>, /
%<curDT.IsSigned>, %<curDT.RequiredBits>, /
(double) %<curDT.FracSlope>, %<curDT.FixedExp>, /
(double) %<curDT.Bias>, %<dtOverride>);
if (fixptDTId == INVALID_DTYPE_ID) return;
ssRegDlgParamAsRunTimeParam(%<tSimStructArg>, %<sfcnPrmIdx>, %<sfcnPrmIdx>, /
"%<prmName>", fixptDTId);
%endif
%else
%assign errTxt = ...
"User-defined data types not supported for ERT S-Function parameters."
%<LibReportFatalError(errTxt)>
%endif
%endif
if (ssGetErrorStatus(%<tSimStructArg>) != (NULL) || ssGetLocalErrorStatus(%<tSimStructArg>) != (NULL)) { return; }
}
%endif
%endforeach
%if !WHITE_SPACE(callToLocalFcn)
%<callToLocalFcn>
%endif
%endwith
%endif
%endfunction
%function FcnGenErtSFcnLocalProcessParamsFcn(numTunablePrms, prmIdxVec) Output
%if numTunablePrms > 0
%with ModelParameters
%assign fcnName = "updateGlobalVarsFromRunTimeParams"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%assign fcnAbstract = "Copy parameter values from run-time parameters to global variables."
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Update"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
int_T i;
%foreach sfcnPrmIdx = numTunablePrms
%assign mdlPrm = Parameter[prmIdxVec[sfcnPrmIdx]]
%assign numOfElements = LibBlockParameterWidth(mdlPrm)
%assign vcRecord = SLibGetDataInlineVariantNetConditions(mdlPrm)
%<vcRecord.ifCond>
/* Update parameter '%<LibGetRecordIdentifier(mdlPrm)>' */
%if numOfElements > 1
for (i=0; i<%<numOfElements>; i++) {
%<CopyRunTimeParamToGlobalVar(mdlPrm, sfcnPrmIdx, "i")>
}
%else
%<CopyRunTimeParamToGlobalVar(mdlPrm, sfcnPrmIdx, "")>
%endif
%<vcRecord.endIfCond>
%endforeach
}
%endwith
%endif
%endfunction
%function FcnGenErtSFcnProcessParamsFcn(numTunablePrms, callToLocalFcn) Output
%if numTunablePrms > 0
%assign fcnName = "mdlProcessParameters"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%assign fcnAbstract = "This function updates tunable parameter values during simulation."
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Update"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
#define MDL_PROCESS_PARAMETERS
#if defined(MDL_PROCESS_PARAMETERS) && defined(MATLAB_MEX_FILE)
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
ssUpdateAllTunableParamsAsRunTimeParams(%<tSimStructArg>);
%if !WHITE_SPACE(callToLocalFcn)
%<callToLocalFcn>
%endif
}
#endif /* MDL_PROCESS_PARAMETERS */
%endif
%endfunction
%function FcnConditionRootInputsAsSeparateArgs() void
%return SLibFcnProtoCtrlActive() || ...
(GenerateClassInterface && !(classConfObj.hasGlobalAccessForInport))
%endfunction
%function FcnConditionRootOutputsAsSeparateArgs() void
%return SLibFcnProtoCtrlActive() || ...
(GenerateClassInterface && !(classConfObj.hasGlobalAccessForOutport))
%endfunction
%function GenErtSFcnParamHandlingFcns() void
%assign result = [0, "", ""]
%assign numTunablePrms = 0
%with ModelParameters
%if (NumParameters > 0)
%assign prmIdxVec = ...
Vector(%<NumParameters>) [0:%]
%foreach prmIdx = NumParameters
%assign mdlPrm = Parameter[prmIdx]
%assign origDtypeIdx = mdlPrm.OriginalDataTypeIdx
%assign isGetSetStorageClass = (mdlPrm.StorageClass == "Custom") && ...
(mdlPrm.CustomStorageClassVersion > 1) && ...
!(LibGetRTWInfoObjectPackage(mdlPrm) == "AUTOSAR")
%assign isTunable = (mdlPrm.Tunable == "yes") && !ISEMPTY(mdlPrm.WorkspaceVarName) && ...
(LibIsDataTypeBuiltinOrFixpt(origDtypeIdx) || ...
LibIsEnumDataType(origDtypeIdx) || ...
(LibDataTypeIsBus(origDtypeIdx) && !isGetSetStorageClass))
%if isTunable && ...
LibBlockParameterWidth(mdlPrm) > 0 && ...
!SLibIsModelParamConst(mdlPrm) && ...
!SLibIsModelParamMacro(mdlPrm) && ...
!SLibIsModelParamFileOrAutoScope(mdlPrm)
%assert ((prmIdx < NumInrtP) || (mdlPrm.StorageClass != "Auto") || mdlPrm.InModelRefGlobalSection)
%if ((prmIdx < NumInrtP) || (mdlPrm.StorageClass != "Auto") || mdlPrm.InModelRefGlobalSection)
%assign prmIdxVec[numTunablePrms] = prmIdx
%assign numTunablePrms = numTunablePrms + 1
%endif
%endif
%endforeach
%else
%assign prmIdxVec = 0
%endif
%endwith
%if numTunablePrms > 0
%assign locProcPrmsFcn = "updateGlobalVarsFromRunTimeParams(%<tSimStructArg>);"
%assign origName = ::CompiledModel.Name
%<SLibCreateSfcnTunablePrmWSVariable(origName, numTunablePrms, prmIdxVec)>
%assign fcnBuffer = ""
%openfile fcnBuffer
%<FcnGenErtSFcnCheckParamsFcn(numTunablePrms, prmIdxVec)>
%<FcnGenErtSFcnLocalProcessParamsFcn(numTunablePrms, prmIdxVec)>
%<FcnGenErtSFcnProcessParamsFcn(numTunablePrms, locProcPrmsFcn)>
%closefile fcnBuffer
%assign mdlWorkWidthBuffer = ""
%openfile mdlWorkWidthBuffer
%<FcnGenErtSFcnRunTimePrmReg(numTunablePrms, prmIdxVec, locProcPrmsFcn)>
%closefile mdlWorkWidthBuffer
%assign result[0] = numTunablePrms
%assign result[1] = fcnBuffer
%assign result[2] = mdlWorkWidthBuffer
%endif
%return result
%endfunction
%function FcnErtSfcnDeclareSimStruc()
%openfile retBuf
%assign rootSystem = System[NumSystems-1]
%assign reqInsts = LibGetSystemField(rootSystem, "ReqRootPrmHdrDataInsts")
%if !reqInsts.SimStructInst && !EmptyRealTimeObject
%<::tSimStructType> *const %<::tSimStruct> = &%<tSimStruct>_;
%endif
%closefile retBuf
%return retBuf
%endfunction
%function SLibCPPClassNeedERTSfcnZeroInternalMemory()
%assign retVal = TLC_FALSE
%if GenerateClassInterface && ::GenerateErtSFunction && ...
!(ConfigSet.ZeroInternalMemoryAtStartup)
%assign retVal = TLC_TRUE
%endif
%return retVal
%endfunction
%function SLibCPPClassNeedERTSfcnZeroIOMemory()
%assign retVal = TLC_FALSE
%if GenerateClassInterface && ::GenerateErtSFunction && ...
(!(ConfigSet.ZeroExternalMemoryAtStartup) && ...
(classConfObj.hasGlobalAccessForOutport || ...
classConfObj.hasGlobalAccessForInport))
%assign retVal = TLC_TRUE
%endif
%return retVal
%endfunction
%function SLibCPPClassNeedsDerivedClassWithERTSfcnZeroMem()
%return GenerateClassInterface && SLibCPPClassNeedSubclass() && ...
!(ConfigSet.ZeroExternalMemoryAtStartup)
%endfunction
%function GenLocalVariablesForCPPClass()
%openfile tempBuf
%if GenerateClassInterface && ...
( SLibCPPClassNeedERTSfcnZeroIOMemory() || ...
SLibCPPClassNeedERTSfcnZeroInternalMemory() )
%assign targetObj = ::CompiledModel.GlobalScope.tModelObject
%assign typePrefix = SLibGetModelTypesNamespacePrefix()
%if !(ConfigSet.ZeroInternalMemoryAtStartup)
%if !LibBlockIOStructIsEmpty()
%if CGMODEL_ACCESS("CGModel.getGenerateInternalMemberAccessMethods")!= "None"
%<typePrefix>%<::tBlockIOType> &%<::tBlockIO> = (%<typePrefix>%<tBlockIOType> &)%<targetObj>.getBlockSignals();
%else
%<typePrefix>%<::tBlockIOType> &%<::tBlockIO> = %<targetObj>.%<tBlockIO>;
%endif
%endif
%if NumContStates>0
%if CGMODEL_ACCESS("CGModel.getGenerateInternalMemberAccessMethods") != "None"
%<typePrefix>%<::tContStateType> &%<::tContState> = (%<tContStateType> &)%<targetObj>.getContinuousStates();
%else
%<typePrefix>%<::tContStateType> &%<::tContState> = %<targetObj>.%<tContState>;
%endif
%endif
%if !LibDWorkStructIsEmpty()
%if CGMODEL_ACCESS("CGModel.getGenerateInternalMemberAccessMethods") != "None"
%<typePrefix>%<::tDWorkType> &%<::tDWork> = (%<typePrefix>%<tDWorkType> &)%<targetObj>.getDWork();
%else
%<typePrefix>%<::tDWorkType> &%<::tDWork> = %<targetObj>.%<tDWork>;
%endif
%if CPPEncapNeedsLocalVars(TLC_TRUE)
%assign cppEncapLocalVars = SLibGetCPPEncapInitLocalVars(TLC_TRUE)
%if !WHITE_SPACE(cppEncapLocalVars)
%<cppEncapLocalVars>
%endif
%endif
%endif
%endif
%if !(ConfigSet.ZeroExternalMemoryAtStartup)
%assign classConfObj = FcnGetRTWCPPStepPrototypeRecord()
%if ( classConfObj.hasGlobalAccessForOutport || ...
classConfObj.hasGlobalAccessForInport ) && ...
(CGMODEL_ACCESS("CGModel.getGenerateExternalIOAccessMethods") == "None")
%if classConfObj.hasGlobalAccessForInport
%<typePrefix>%<::tInputType> &%<::tInput> = %<targetObj>.%<::tInput>;
%endif
%if classConfObj.hasGlobalAccessForOutport
%<typePrefix>%<::tOutputType> &%<::tOutput> = %<targetObj>.%<::tOutput>;
%endif
%endif
%endif
%endif
%closefile tempBuf
%return tempBuf
%endfunction
%function ERTSfcnGenInitializeConditionCode(origERTInitFcnArg, ROLL_LIMIT)
%openfile retBuf
%if !GenerateClassInterface
%assign modelInitFcn = GenerateModelInitFcnName()
%<modelInitFcn>(%<origERTInitFcnArg>);
%else
%<::CompiledModel.GlobalScope.tModelObject>.initialize();
%endif
%if ExportFunctionsMode == 1 && NumModelOutputs > 0
/* Initialize block output signals. */
%foreach idx = ExternalOutputs.NumExternalOutputs
%assign extIdx = idx
%openfile tmpVar
%<GenerateTmpSFunctionOutputSignalDef(extIdx)>/
%closefile tmpVar
%<GenerateTmpOutputSignalConditioning(tmpVar, ROLL_LIMIT, extIdx)>/
%endforeach
%endif
%closefile retBuf
%return retBuf
%endfunction
%with ::CompiledModel
%assign ROLL_LIMIT = RollThreshold
%assign instanceCounter = "%<Name>_sf_counter"
%if CombineOutputUpdateFcns
%assign modelStepFcn = SLibModelStepFcnName("")
%else
%assign modelStepFcn = "%<Name>_output"
%endif
%assign modelUpdtFcn = "%<Name>_update"
%assign modelTermFcn = "%<Name>_terminate"
%assign modelRtObject = "%<Name>_rtO"
%assign modelEnable = "%<Name>_enable"
%assign modelDisable = "%<Name>_disable"
%assign modelZeroMemory = "%<Name>_ertSfcnZeroMemory"
%assign sFunctionName = "%<Name>_sf"
%<LibWriteToStandardOutput("### Creating ERT S-Function wrapper %<sFunctionName>.%<LangFileExt>")>
%assign prmHandlingInfo = GenErtSFcnParamHandlingFcns()
%assign numTunablePrms = prmHandlingInfo[0]
%assign prmHandlingBuffer = prmHandlingInfo[1]
%assign mdlWorkWidthFcnBody = prmHandlingInfo[2]
%<SetCurrentUtilsIncludesIdx("ertSfcn_util_incl")>
%openfile ModelSfu = "%<sFunctionName>.%<LangFileExt>"
/*
* %<sFunctionName>.%<LangFileExt>
*
* This file contains a "wrapper style S-Function" for testing the generated
* code from Simulink. Simulink invokes the generated code through its
* S-Function API. Note that this file is not required for deployment
* of the generated code outside of Simulink.
*
%<SLibCommonHeaderInfo()>/
*
*/
#if !defined(S_FUNCTION_NAME)
#define S_FUNCTION_NAME %<sFunctionName>
#endif
#define S_FUNCTION_LEVEL 2
/* So mdlEnable and mdlDisable will be defined in the simstruc.h */
#if !defined(RTW_GENERATED_S_FUNCTION)
#define RTW_GENERATED_S_FUNCTION
#endif
%if ExportFunctionsMode == 1
#define S_FUNCTION_EXPORTS_FUNCTION_CALLS
%endif
#include
#include
%if ::GenCPP && (::RTWTypesStyle == "minimized")
/* Ensure typedef signedness matches rtwtypes.h */
%assign typeINT8_T = SLibGetANSICDataTypeFromId(tSS_INT8)
%if !ISEMPTY(typeINT8_T)
#define INT8_T %<typeINT8_T>
%endif
%endif
/* Remove defines that are incompatible with mex compilation */
#undef MT
#undef RT
#undef USE_RTMODEL
/* For compatibility with packngo, MATLAB_MEX_FILE must always be defined */
#ifndef MATLAB_MEX_FILE
#define MATLAB_MEX_FILE
#endif
#include "simstruc.h"
#include "fixedpoint.h"
#include "rtwtypes_sf.h"
#define rt_logging_h
#define RTWSfcnInfo void *
%if GenerateClassInterface && SLibCPPClassNeedSubclass()
static void mdlOutputs(SimStruct *%<tSimStructArg>, int_T %<::CompiledModel.GlobalScope.tTID>);
static void mdlStart(SimStruct *%<tSimStructArg>);
%endif
#include "%<Name>.h"
%assign ertSFcnFile = SLibDoesModelFileExist("SystemHeader", sFunctionName)
%if (TYPE(ertSFcnFile) == "Scope")
#include "%<sFunctionName>.h"
%endif
%<SLibDeclareModelFcnArgs(TLC_TRUE)>/
%<DumpImportedExternalSignalDeclaration()>
%<DumpImportedExternalParameterDeclaration()>
%if EXISTS(::NamespaceName) && (::NamespaceName != "")
using namespace %<::NamespaceName>;
%endif
static int8_T %<instanceCounter> = 0;
%if GenerateClassInterface && SLibCPPClassNeedSubclass()
class %<theClassName>_sf : public %<theClassName> {
friend void mdlOutputs(SimStruct *, int_T);
friend void mdlStart(SimStruct *);
%if !(ConfigSet.ZeroExternalMemoryAtStartup)
public:
void ertSfcnZeroMemory(void);
%endif
};
%endif
%if GenerateClassInterface
%if !SLibCPPClassNeedSubclass()
static %<theClassName> %<::CompiledModel.GlobalScope.tModelObject>;
%else
static %<theClassName>_sf %<::CompiledModel.GlobalScope.tModelObject>;
%endif
%assign reqInsts = LibGetSystemField(rootSystem, "ReqRootPrmHdrDataInsts")
%if !reqInsts.ParamsInst && ...
!SLibPrmBufferIsEmpty("SimulinkGlobal", "Instance")
%if CGMODEL_ACCESS("CGModel.getParameterMemberVisibility") == "private" || ...
CGMODEL_ACCESS("CGModel.getParameterMemberVisibility") == "protected"
static %<::tParametersType>& %<::tParameters> = const_cast<%<tParametersType>&>(%<::CompiledModel.GlobalScope.tModelObject>.getBlockParameters());
%else
static %<::tParametersType>& %<::tParameters> = %<::CompiledModel.GlobalScope.tModelObject>.%<tParameters>;
%endif
%endif
%endif
%if FcnConditionRootInputsAsSeparateArgs()
%foreach idx = ExternalInputs.NumExternalInputs
%assign extInp = ExternalInputs.ExternalInput[idx]
%assign portWidth = LibGetRecordWidth(extInp)
%if portWidth > 1
%assign coll = "[%<portWidth>]"
%else
%assign coll = ""
%endif
static %<LibGetRecordDataTypeName(extInp, "")> localIn%<idx>%<coll>;
%endforeach
%endif
%if FcnConditionRootOutputsAsSeparateArgs()
%foreach idx = ExternalOutputs.NumExternalOutputs
%assign extOutp = ExternalOutputs.ExternalOutput[idx]
%assign portWidth = LibGetRecordWidth(extOutp)
%assign sysIdx = extOutp.Block[0]
%assign blkIdx = extOutp.Block[1]
%assign outportBlock = System[sysIdx].Block[blkIdx]
%if portWidth > 1
%assign coll = "[%<portWidth>]"
%else
%assign coll = ""
%endif
static %<LibGetRecordDataTypeName(extOutp, "")> localOut%<idx>%<coll>;
%endforeach
%endif
%assign origERTInitFcnArg = SLibModelFcnArgs("Initialize",TLC_TRUE,"")
%assign ertSfcnNeedZeroInitialization = TLC_FALSE
%if (!ZeroExternalMemoryAtStartup || !ZeroInternalMemoryAtStartup)
%assign ::GenerateInitCodeRemoved = TLC_TRUE
%openfile tmpBuf2
%if RealTimeModelAccessed && SLibZeroMemory("RTM")
%assign baseSysIdx = GetBaseSystemIdx()
/* initialize real-time model */
%if !GenerateClassInterface
%if !MultiInstanceERTCode || UsingMalloc || SLibUseBackwardCompatibleReusableInterface()
(void) %<LibGenMemFcnCall("memset", "(void *)%<::tSimStruct>", ...
"0", "sizeof(%<::tSimStructType>)")>;
%endif
%else
(void) %<LibGenMemFcnCall("memset", ...
"(void *)%<::CompiledModel.GlobalScope.tModelObject>.getRTM()", ...
"0", "sizeof(%<SLibGetModelTypesNamespacePrefix()>%<::tSimStructType>)")>;
%endif
%endif
%closefile tmpBuf2
%assign ::BlockFcn = "Initialize"
%assign tmpBuf = SLibDumpERTAndModelrefInitMemoryCode(TLC_TRUE, TLC_TRUE, 1)
%assign ::GenerateInitCodeRemoved = TLC_FALSE
%openfile tmpBuf3
%if GenerateClassInterface
%if SLibCPPClassNeedsDerivedClassWithERTSfcnZeroMem()
%assign fcnName = "%<theClassName>_sf::ertSfcnZeroMemory"
%assign fcnReturns = "void"
%assign fcnParams = "void"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract ""; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Initialize"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>) {
%openfile tmpBufRtUY
%<SLibInitExternalInputs(1,FcnConditionRootInputsAsSeparateArgs(),1)>/
%<SLibInitExternalOutputs(1,FcnConditionRootOutputsAsSeparateArgs(),1)>/
%closefile tmpBufRtUY
%if !WHITE_SPACE(tmpBufRtUY)
%<tmpBufRtUY>
%endif
}
%endif
%endif
%closefile tmpBuf3
%assign ::BlockFcn = "Unknown"
%if !WHITE_SPACE(tmpBuf) || !WHITE_SPACE(tmpBuf2) || !WHITE_SPACE(tmpBuf3)
%<LibDumpGroundDeclarations(1)>
%<tmpBuf3>
%assign fcnName = modelZeroMemory
%assign fcnReturns = "static void"
%assign fcnParams = "%<SLibModelFcnArgs("Initialize",TLC_FALSE,"")>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract ""; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Initialize"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>) {
%openfile localVariables
%if (MultiInstanceERTCode || ::CompiledModel.ModelRefSimpInterface)&& !GenerateClassInterface
%<SLibDumpLocalVariablesForBlockFcn(System[NumSystems-1],"Initialize")>
%endif
%closefile localVariables
%if !WHITE_SPACE(localVariables)
%<localVariables>
%endif
%if GenerateClassInterface
%assign localVarBuf = GenLocalVariablesForCPPClass()
%if !ISEMPTY(localVarBuf)
%<localVarBuf>
%endif
%endif
%<tmpBuf2>
%if !GenerateClassInterface
%<tmpBuf>
%else
%if SLibCPPClassNeedSubclass() && ...
!(ConfigSet.ZeroExternalMemoryAtStartup)
%<::CompiledModel.GlobalScope.tModelObject>.ertSfcnZeroMemory();
%endif
%if CPPEncapNeedsLocalVars(TLC_TRUE) && !WHITE_SPACE(tmpBuf)
%assign cppEncapCopyCode = SLibGetCPPEncapInitCopyCode(TLC_TRUE, TLC_TRUE)
%if !WHITE_SPACE(cppEncapCopyCode)
%<cppEncapCopyCode>
%endif
%endif
%<tmpBuf>
%if CPPEncapNeedsLocalVars(TLC_TRUE) && !WHITE_SPACE(tmpBuf)
%assign cppEncapRestoreCode = SLibGetCPPEncapInitCopyCode(TLC_FALSE, TLC_TRUE)
%if !WHITE_SPACE(cppEncapRestoreCode)
%<cppEncapRestoreCode>
%endif
%endif
%endif
}
%assign ertSfcnNeedZeroInitialization = TLC_TRUE
%endif
%endif
%assign rootSystem = System[NumSystems-1]
%if numTunablePrms > 0
%<prmHandlingBuffer>/
%endif
%function GetERTExportedFcnArgEl(origName) void
%assign argEl = "ssEl"
%if origName == argEl
%assign argEl = "ssElt"
%endif
%return argEl
%endfunction
%function GetERTExportedFcnArgTid(origName) void
%assign argTid = "ssTid"
%if origName == argTid
%assign argTid = "ssTaskId"
%endif
%return argTid
%endfunction
%function DumpERTExportedFcns(sysId, ROLL_LIMIT) Output
%assign driverPortIdx = System[sysId].ExportedId - 1
%assign fcallSysId = sysId
%if !LibSystemFcnIsEmpty(System[sysId],"Enable")
%openfile fcnAbstract
This function is a wrapper around the 'enable' function for system
'%<LibGetRecordIdentifier(System[sysId])>'. This function is explicitly called
by the function-call initiator which drives input port '%<driverPortIdx>'
of this S-Function.
%closefile fcnAbstract
%assign argEl = GetERTExportedFcnArgEl(System[sysId].EnableFcn)
%assign argTid = GetERTExportedFcnArgTid(System[sysId].EnableFcn)
%assign fcnName = "mdlExportedEnableFcn%<driverPortIdx>"
%assign fcnReturns = "static ssFcnCallErr_T"
%assign fcnParams = "SimStruct *%<tSimStructArg>, int_T %<argEl>, int_T %<argTid>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Exported Enable";...
GeneratedFor "%<LibGetRecordIdentifier(System[sysId])>"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
/* Reserved arguments. */
(void)%<argEl>;
(void)%<argTid>;
/* Enable function for system '%<LibGetRecordIdentifier(System[sysId])>'. */
%();
/* Default return status. */
return(SS_FCNCALL_NO_ERR);
}
%endif
%if !LibSystemFcnIsEmpty(System[sysId],"Disable")
%openfile fcnAbstract
This function is a wrapper around the 'disable' function for system
'%<LibGetRecordIdentifier(System[sysId])>'. This function is explicitly called
by the function-call initiator which drives input port '%<driverPortIdx>'
of this S-Function.
%closefile fcnAbstract
%assign argEl = GetERTExportedFcnArgEl(System[sysId].DisableFcn)
%assign argTid = GetERTExportedFcnArgTid(System[sysId].DisableFcn)
%assign fcnName = "mdlExportedDisableFcn%<driverPortIdx>"
%assign fcnReturns = "static ssFcnCallErr_T"
%assign fcnParams = "SimStruct *%<tSimStructArg>, int_T %<argEl>, int_T %<argTid>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Exported Disable"; ...
GeneratedFor "%<LibGetRecordIdentifier(System[sysId])>"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
/* Reserved arguments. */
(void)%<argEl>;
(void)%<argTid>;
%<DumpERTExportedFcnDataRead(fcallSysId, ROLL_LIMIT)>
/* Disable function for system '%<LibGetRecordIdentifier(System[sysId])>'. */
%();
%<DumpERTExportedFcnDataWrite(fcallSysId, ROLL_LIMIT)>
/* Default return status. */
return(SS_FCNCALL_NO_ERR);
}
%endif
%openfile fcnAbstract
This function is a wrapper around the 'output-update' function for
system '%<LibGetRecordIdentifier(System[sysId])>'. This function is explicitly called
by the function-call initiator which drives input port '%<driverPortIdx>'
of this S-Function.
%closefile fcnAbstract
%assign argEl = GetERTExportedFcnArgEl(LibGetRecordIdentifier(System[sysId]))
%assign argTid = GetERTExportedFcnArgTid(LibGetRecordIdentifier(System[sysId]))
%assign fcnName = "mdlExportedOutputFcn%<driverPortIdx>"
%assign fcnReturns = "static ssFcnCallErr_T"
%assign fcnParams = "SimStruct *%<tSimStructArg>, int_T %<argEl>, int_T %<argTid>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Exported OutputUpdate";...
GeneratedFor "'%<LibGetRecordIdentifier(System[sysId])>"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
/* Reserved arguments. */
(void)%<argEl>;
(void)%<argTid>;
%<DumpERTExportedFcnDataRead(fcallSysId, ROLL_LIMIT)>
%if !LibSystemFcnIsEmpty(System[sysId],"OutputUpdate")
/* Output-update function for system '%<LibGetRecordIdentifier(System[sysId])>'. */
%();
%else
/* (Output-update function for system '%<LibGetRecordIdentifier(System[sysId])>' is empty.) */
%endif
%<DumpERTExportedFcnDataWrite(fcallSysId, ROLL_LIMIT)>
/* Default return status. */
return(SS_FCNCALL_NO_ERR);
}
%endfunction
%function DumpERTExportedFcnDataRead(sysId, ROLL_LIMIT) Output
%openfile declBuffer
%if NumModelInputs > 0 && ...
ISFIELD(System[sysId], "ExternalInputs")
%foreach idx = SIZE(System[sysId].ExternalInputs, 1)
%assign extIdx = System[sysId].ExternalInputs[idx]
%openfile tmpVar
%<GenerateTmpSFunctionInputSignalDef(extIdx)>/
%closefile tmpVar
%<GenerateTmpInputSignalConditioning(tmpVar, ROLL_LIMIT, extIdx)>/
%endforeach
%endif
%assign currBlockFcn = ::BlockFcn
%assign ::BlockFcn = "SFunctionOutputs"
%<SLibGenDataStoreReads("%<tSimStructArg>")>
%assign ::BlockFcn = currBlockFcn
%closefile declBuffer
%if !WHITE_SPACE(declBuffer)
/* Update input variables for system '%<LibGetRecordIdentifier(System[sysId])>'. */
%<declBuffer>
%endif
%endfunction
%function DumpERTExportedFcnDataWrite(sysId, ROLL_LIMIT) Output
%openfile declBuffer
%if NumModelOutputs > 0 && ...
ISFIELD(System[sysId], "ExternalOutputs")
%foreach idx = SIZE(System[sysId].ExternalOutputs, 1)
%assign extIdx = System[sysId].ExternalOutputs[idx]
%openfile tmpVar
%<GenerateTmpSFunctionOutputSignalDef(extIdx)>/
%closefile tmpVar
%<GenerateTmpOutputSignalConditioning(tmpVar, ROLL_LIMIT, extIdx)>/
%endforeach
%endif
%assign currBlockFcn = ::BlockFcn
%assign ::BlockFcn = "SFunctionOutputs"
%<SLibGenDataStoreWrites(tSimStructArg)>
%assign ::BlockFcn = currBlockFcn
%closefile declBuffer
%if !WHITE_SPACE(declBuffer)
/* Update block output for this S-Function. */
%<declBuffer>
%endif
%endfunction
%function FcnCompareDataTypeChecksums() Output
%openfile compareBuffer
%foreach dtIdx = ::CompiledModel.DataTypes.NumDataTypes
%assign dt = ::CompiledModel.DataTypes.DataType[dtIdx]
%if ISFIELD(dt, "Checksum")
%if dt.Checksum[0] > 0 || dt.Checksum[1] > 0 || dt.Checksum[2] > 0 || dt.Checksum[3] > 0
ssCallGetDataTypeChecksum(%<tSimStructArg>, "%<dt.Name>", &checksumVals);
if ((checksumVals != NULL) && (checksumVals[0] != % ||
checksumVals[1] != % ||
checksumVals[2] != % ||
checksumVals[3] != %)) {
ssSetErrorStatus(%<tSimStructArg>, "The definition of the data type "
"'%<dt.Name>' has been updated since this S-Function was "
"generated; regenerate this S-Function.");
return;
}
%endif
%endif
%endforeach
%closefile compareBuffer
%if !WHITE_SPACE(compareBuffer)
/* Validate checksums for user-defined data types used by this S-Function. */
{
const uint32_T *checksumVals;
%<compareBuffer>
}
%endif
%endfunction
%if ExportFunctionsMode == 1
%assign rootSystem = System[NumSystems-1]
%foreach id = rootSystem.NumChildSystems
%assign systemId = rootSystem.ChildSystems[id][0]
%assign system = System[systemId]
%if system.Type == "function-call" && system.Exported == "yes"
%<DumpERTExportedFcns(systemId,ROLL_LIMIT)>
%endif
%endforeach
%endif
%assign fcnName = "mdlInitializeSizes"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%openfile fcnAbstract
This function registers the input and output signal properties of the
generated ERT code.
%closefile fcnAbstract
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Initialize"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
/* Tunable Parameters */
ssSetNumSFcnParams(%<tSimStructArg>, %<numTunablePrms>);
ssFxpSetU32BitRegionCompliant(%<tSimStructArg>, 1);
/* Number of expected parameters */
if (ssGetNumSFcnParams(%<tSimStructArg>) == ssGetSFcnParamsCount(%<tSimStructArg>)) {
#if defined(MDL_CHECK_PARAMETERS)
mdlCheckParameters(%<tSimStructArg>);
#endif /* MDL_CHECK_PARAMETERS */
if (ssGetErrorStatus(%<tSimStructArg>) != %<SLibGetNullDefinitionFromTfl()>) {
return;
}
} else {
return; /* Parameter mismatch will be reported by Simulink */
}
ssSetNumContStates(%<tSimStructArg>, 0);
ssSetNumDiscStates(%<tSimStructArg>, 0);
ssSetRTWGeneratedSFcn(%<tSimStructArg>, 3);
%<SLibRegisterDataStores(tSimStructArg)>
%assign localISTParray = []
%foreach idx = ::CompiledModel.NumSampleTimes
%assign localISTParray = localISTParray + 1
%assign localISTParray[idx]=0
%endforeach
%addtorecord ::CompiledModel IsSampleTimeOnPort localISTParray
%<DumpErtSFcnExternalInputs()>
%<DumpErtSFcnExternalOutputs()>
%assign AllSampleTimesOnPorts = TLC_TRUE
%foreach idx = ::CompiledModel.NumRuntimeExportedRates
%if !::CompiledModel.IsSampleTimeOnPort[idx]
%assign AllSampleTimesOnPorts = TLC_FALSE
%break
%endif
%endforeach
%assign NeedConstantST = TLC_FALSE
%if ExportFunctionsMode != 1 && ExternalOutputs.NumExternalOutputs > 1
%foreach idx = ExternalOutputs.NumExternalOutputs
%assign extOut = ExternalOutputs.ExternalOutput[idx]
%assign sysIdx = extOut.Block[0]
%assign blkIdx = extOut.Block[1]
%assign outportBlock = System[sysIdx].Block[blkIdx]
%if ISEQUAL(outportBlock.TID,"constant")
%assign NeedConstantST = TLC_TRUE
%break
%endif
%endforeach
%endif
%if %<ConfigSet.NoFixptDivByZeroProtection>
%assign ss_option_str = ""
%else
%assign ss_option_str = "SS_OPTION_EXCEPTION_FREE_CODE"
%endif
%if NumRuntimeExportedRates > 1 || NeedConstantST
%if AllSampleTimesOnPorts
/*
* All sample times are available through ports.
* Use port based sample times
*/
ssSetNumSampleTimes(%<tSimStructArg>, PORT_BASED_SAMPLE_TIMES);
%else
/* Using hybrid block and port based sample times */
ssSetNumSampleTimes
(%<tSimStructArg>, %<NumRuntimeExportedRates>);
%if !ISEMPTY(ss_option_str)
%assign ss_option_str = "%<ss_option_str> | "
%endif
%assign ss_option_str = "%<ss_option_str>SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED"
%endif
%if NeedConstantST
%if !ISEMPTY(ss_option_str)
%assign ss_option_str = "%<ss_option_str> | "
%endif
%assign ss_option_str = "%<ss_option_str>SS_OPTION_ALLOW_CONSTANT_PORT_SAMPLE_TIME"
%endif
%else
/* Number of sample-times */
ssSetNumSampleTimes(%<tSimStructArg>, %<NumRuntimeExportedRates>);
%endif
ssSetNumRWork(%<tSimStructArg>, 0);
ssSetNumIWork(%<tSimStructArg>, 0);
ssSetNumPWork(%<tSimStructArg>, 0);
ssSetNumModes(%<tSimStructArg>, 0);
ssSetNumNonsampledZCs(%<tSimStructArg>, 0);
/* ERT S-Function works with model reference normal mode */
ssSetModelReferenceNormalModeSupport(%<tSimStructArg>, MDL_START_AND_MDL_PROCESS_PARAMS_OK);
%if AllSampleTimesInherited == "yes"
/* ERT S-Function works with model sample time inheritance */
ssSetModelReferenceSampleTimeDefaultInheritance(%<tSimStructArg>);
%endif
%if ::CompiledModel.DWorks.NumSFcnWrapperDWorks > 0 || ...
(AllSampleTimesInherited == "yes" && ::CompiledModel.DWorks.NumDWorks > 0)
%if !ISEMPTY(ss_option_str)
%assign ss_option_str = "%<ss_option_str> | "
%endif
%assign ss_option_str = "%<ss_option_str>SS_OPTION_DISALLOW_CONSTANT_SAMPLE_TIME"
%endif
%if !ISEMPTY(ss_option_str)
/* Set SS_OPTIONS */
ssSetOptions(%<tSimStructArg>, %<ss_option_str>);
%endif
%if AllSampleTimesInherited == "yes"
ssSetModelReferenceSampleTimeInheritanceRule(%<tSimStructArg>, USE_DEFAULT_FOR_DISCRETE_INHERITANCE);
%endif
}
%assign fcnName = "mdlInitializeSampleTimes"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%assign fcnAbstract = "This function registers the sample times of the generated ERT code."
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Initialize"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%if AllSampleTimesInherited == "yes" || ExportFunctionsMode == 1
ssSetSampleTime(%<tSimStructArg>, 0, -1);
%else
%foreach idx = NumRuntimeExportedRates
%assign tid = SampleTime[idx].TID
%assign sampleTime = SampleTime[idx].PeriodAndOffset[0]
%assign offset = SampleTime[idx].PeriodAndOffset[1]
ssSetSampleTime(%<tSimStructArg>, %<tid>, %<sampleTime>);
ssSetOffsetTime(%<tSimStructArg>, %<tid>, %<offset>);
%endforeach
%endif
}
%assign genWrapperDWorks = ::CompiledModel.DWorks.NumSFcnWrapperDWorks > 0
%assign fcnName = "mdlSetWorkWidths"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%assign fcnAbstract = "This function registers run-time parameters for tunable parameters."
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Initialize"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
#define MDL_SET_WORK_WIDTHS
#if defined(MDL_SET_WORK_WIDTHS) && defined(MATLAB_MEX_FILE)
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%if numTunablePrms > 0
%<mdlWorkWidthFcnBody>
%endif
%if genWrapperDWorks
%<SLibGenDataStoreChecks("%<tSimStructArg>")>
%endif
%<FcnCompareDataTypeChecksums()>
}
#endif /* MDL_SET_WORK_WIDTHS */
%if !SLibMdlEnableDisablePermitted()
static boolean_T enable_first_entry;
%endif
%assign fcnName = "mdlStart"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%openfile fcnAbstract
This function does sfunction consistent check, initializes internal memory if neccessary, and
calls the initialization function of the generated ERT code.
%closefile fcnAbstract
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Start"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
#define MDL_START /* Change to #undef to remove function */
#if defined(MDL_START)
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%assign currBlockFcn = ::BlockFcn
%assign currSystemFcn = ::SystemFcnsForArgAccess
%assign ::BlockFcn = "SFunctionStart"
%assign ::SystemFcnsForArgAccess = ::BlockFcn
%if NumModelOutputs > 0
%foreach idx = ExternalOutputs.NumExternalOutputs
%<GenerateSFunctionOutputSignalDefinition("OutPort_",idx)>
%endforeach
%endif
%if !GenerateClassInterface
%<FcnErtSfcnDeclareSimStruc()>
%endif
/* check if more than one instance of this S-Function has been used */
if (++%<instanceCounter> > 1) {
ssSetErrorStatus(%<tSimStructArg>,"This S-Function is limited to one copy per model.");
%<instanceCounter> = 0;
return;
}
/* check if parent model's start time is the same as that used to generate code */
if (ssGetTStart(%<tSimStructArg>) != %<::CompiledModel.StartTime>) {
ssSetErrorStatus(%<tSimStructArg>,"The parent model of this S-Function must set the value of the 'Start time' on the Solver page of its Configuration Parameters Dialog to %<::CompiledModel.StartTime> since that was the value used when generating code for the S-Function's original model.");
return;
}
%<SLibGenerateSolverChecks("%<tSimStructArg>")>
%if !SLibMdlEnableDisablePermitted()
enable_first_entry = %;
%endif
#ifdef PIL_S_FUNCTION
pilMarshallInitSFcnSimStruct(%<tSimStructArg>);
pilMarshallInitRootSimStruct(ssGetRootSS(%<tSimStructArg>));
#endif
%<FcnPackModelDataIntoRTM()>
%if ertSfcnNeedZeroInitialization
%<modelZeroMemory>(%<SLibModelFcnArgs("Initialize",TLC_TRUE,"")>);
%endif
%<ERTSfcnGenInitializeConditionCode(origERTInitFcnArg,ROLL_LIMIT)>
%if NumModelOutputs > 0
%foreach idx = ExternalOutputs.NumExternalOutputs
%<GenerateOutputSignalConditioning("OutPort_", ROLL_LIMIT,idx)>
%endforeach
%endif
%assign ::BlockFcn = currBlockFcn
%assign ::SystemFcnsForArgAccess = currSystemFcn
}
#endif /* MDL_START */
#define MDL_INITIALIZE_CONDITIONS
%assign fcnName = "mdlInitializeConditions"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%openfile fcnAbstract
%if SLibMdlEnableDisablePermitted()
This function calls the initialization function of the generated ERT
code.
%else
Nothing runs in this function
%endif
%closefile fcnAbstract
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Initialize"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%if SLibMdlEnableDisablePermitted()
%<ERTSfcnGenInitializeConditionCode(origERTInitFcnArg,ROLL_LIMIT)>
%endif
}
%if ExportFunctionsMode != 1
%assign fcnName = "mdlOutputs"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>, int_T %<::CompiledModel.GlobalScope.tTID>"
%openfile fcnAbstract
This function calls the step function of the generated ERT code
and provides an interface with the simulation data.
%closefile fcnAbstract
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Output"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%assign currBlockFcn = ::BlockFcn
%assign currSystemFcn = ::SystemFcnsForArgAccess
%assign ::BlockFcn = "SFunctionOutputs"
%assign ::SystemFcnsForArgAccess = ::BlockFcn
%if NumModelInputs > 0
%foreach idx = ExternalInputs.NumExternalInputs
%<GenerateSFunctionInputSignalDefinition("InPort_",idx)>
%endforeach
%endif
%if NumModelOutputs > 0
%foreach idx = ExternalOutputs.NumExternalOutputs
%<GenerateSFunctionOutputSignalDefinition("OutPort_",idx)>
%endforeach
%endif
%if !GenerateClassInterface
%<FcnErtSfcnDeclareSimStruc()>
%endif
%if NumModelInputs > 0
%foreach idx = ExternalInputs.NumExternalInputs
%<GenerateInputSignalConditioning("InPort_", ROLL_LIMIT,idx)>
%endforeach
%endif
%<SLibGenDataStoreReads("%<tSimStructArg>")>
%assign localTid = ""
%assign mdlTid01Eq = ISEQUAL(SolverType, "FixedStep") && ...
FixedStepOpts.TID01EQ
%assign mdlAllTidEq = NumRuntimeExportedRates == 1 || ...
(NumRuntimeExportedRates == 2 && mdlTid01Eq)
%assign needTimeConditioningCode = ...
NumRuntimeExportedRates > 1 && !mdlAllTidEq && !SLibSingleTasking()
%openfile codeBody
%if SLibFcnProtoCtrlActive()
%assign fcnData = FcnGetFunctionPrototypeRecord()
%assign arglist = FcnModelStepFcnArgs(fcnData,"ERTSfcnCall")
%assign fcnName = fcnData.FunctionName
%assign haveReturnValue = (fcnData.NumArgSpecData > 0 && ...
fcnData.ArgSpecData[0].Category == "Value" && ...
fcnData.ArgSpecData[0].SLObjectType == "Outport")
%assign returnAssignment = ""
%if haveReturnValue
%assign returnAssignment = "localOut% = "
%endif
%<returnAssignment>%<fcnName>(%<arglist>);
%elseif ::GenerateClassInterface && ...
SLibSingleTasking()
%assign fcnName = classConfObj.FunctionName
%if (!(classConfObj.hasGlobalAccessForInport)) || ...
(!(classConfObj.hasGlobalAccessForOutport))
%assign arglist = FcnModelStepFcnArgs(classConfObj,"ERTSfcnCall")
%assign haveReturnValue = ISFIELD(classConfObj, "hasReturnValue") && ...
classConfObj.hasReturnValue
%assign returnAssignment = ""
%if haveReturnValue
%assign returnAssignment = "localOut% = "
%endif
%<returnAssignment>%<::CompiledModel.GlobalScope.tModelObject>.%<fcnName>(%<arglist>);
%else
%<::CompiledModel.GlobalScope.tModelObject>.%<fcnName>();
%endif
%elseif needTimeConditioningCode
{
%assign localTid = "ertTid"
%<DumpTimeConditioningCode(localTid)>
%if GenerateSampleERTMain && SLibIsPeriodicRateGrouping()
switch(%<localTid>) {
%foreach tid = NumRuntimeExportedRates
case %<tid> :
%assign rootSystem.CurrentTID = tid
%if CombineOutputUpdateFcns == 1
%if !GenerateClassInterface
%<modelStepFcn>%<tid>(%<SLibModelFcnArgs("OutputUpdate",TLC_TRUE,tid)>);
%else
%<::CompiledModel.GlobalScope.tModelObject>.%<classConfObj.FunctionName>%<tid>();
%endif
%else
%<modelStepFcn>%<tid>(%<SLibModelFcnArgs("Output",TLC_TRUE,tid)>);
%<modelUpdtFcn>%<tid>(%<SLibModelFcnArgs("Update",TLC_TRUE,tid)>);
%endif
break;
%endforeach
default :
break;
}
%else
%if CombineOutputUpdateFcns == 1
%<modelStepFcn>(%<SLibModelFcnArgs("OutputUpdate",TLC_TRUE,localTid)>);
%else
%<modelStepFcn>(%<SLibModelFcnArgs("Output",TLC_TRUE,localTid)>);
%if (NumContStates > 0)
%<modelUpdtFcn>(%<SLibModelFcnArgs("UpdateContStates",TLC_TRUE,localTid)>);
%else
%<modelUpdtFcn>(%<SLibModelFcnArgs("RootUpdate",TLC_TRUE,localTid)>);
%endif
%endif
%endif
}
%else
%if NumRuntimeExportedRates > 1
%assert (mdlTid01Eq && mdlAllTidEq) || SLibSingleTasking()
if (ssIsMajorTimeStep(%<tSimStructArg>)) {
%endif
%if CombineOutputUpdateFcns == 1
%<modelStepFcn>(%<SLibModelFcnArgs("OutputUpdate",TLC_TRUE,"")>);
%else
%<modelStepFcn>(%<SLibModelFcnArgs("Output",TLC_TRUE,"")>);
%if (NumContStates > 0)
%<modelUpdtFcn>(%<SLibModelFcnArgs("UpdateContStates",TLC_TRUE,localTid)>);
%else
%<modelUpdtFcn>(%<SLibModelFcnArgs("RootUpdate",TLC_TRUE,localTid)>);
%endif
%endif
%if NumRuntimeExportedRates > 1
}
%endif
%endif
%closefile codeBody
%if NeedConstantST && !needTimeConditioningCode
if (%<::CompiledModel.GlobalScope.tTID> != CONSTANT_TID) {
%<codeBody>
}
%else
%<codeBody>
%endif
%if NumModelOutputs > 0
%foreach idx = ExternalOutputs.NumExternalOutputs
%<GenerateOutputSignalConditioning("OutPort_", ROLL_LIMIT,idx)>
%endforeach
%endif
%<SLibGenDataStoreWrites(tSimStructArg)>
%assign ::BlockFcn = currBlockFcn
%assign ::SystemFcnsForArgAccess = currSystemFcn
}
%endif
%assign fcnName = "mdlTerminate"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%assign fcnAbstract = "This function calls the termination function of the generated ERT code."
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Terminate"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>)
{
%if !GenerateClassInterface
%<FcnErtSfcnDeclareSimStruc()>
%endif
%if GenerateClassInterface && ::CompiledModel.IncludeMdlTerminateFcn
%<::CompiledModel.GlobalScope.tModelObject>.terminate();
%elseif ::CompiledModel.IncludeMdlTerminateFcn
%<modelTermFcn>(%<SLibModelFcnArgs("Terminate",TLC_TRUE,"")>);
%endif
%<instanceCounter> = 0;
}
#define MDL_ENABLE
%assign fcnName = "mdlEnable"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract ""; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Enable"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>) {
%if EnableGenerated == 1
%if !GenerateClassInterface
%<modelEnable>(%<SLibModelFcnArgs("Enable",TLC_TRUE,"")>);
%else
%<::CompiledModel.GlobalScope.tModelObject>.enable();
%endif
%else
%if !SLibMdlEnableDisablePermitted()
if (!enable_first_entry) {
static char msg[256];
if (strlen(ssGetPath(%<tSimStructArg>)) < 128) {
sprintf(msg, "The model is attempting to invoke the enable method of ...
the S-Function block %s for model '%<LibGetModelName()>', yet the code ...
generated for the model does not include the enable method/n", ssGetPath(%<tSimStructArg>));
} else {
sprintf(msg, "The model is attempting to invoke the enable method of ...
the S-Function block for model '%<LibGetModelName()>', yet the code ...
generated for the model does not include the enable method/n");
}
ssSetErrorStatus(%<tSimStructArg>, msg);
}
enable_first_entry = %;
%else
(void) %<tSimStructArg>;
%endif
%endif
}
#define MDL_DISABLE
%assign fcnName = "mdlDisable"
%assign fcnReturns = "static void"
%assign fcnParams = "SimStruct *%<tSimStructArg>"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract ""; ...
Category "sfcn"; GeneratedBy "ertsfcnbody.tlc"; Type "Disable"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnReturns> %<fcnName>(%<fcnParams>) {
%if DisableGenerated == 1
%if !GenerateClassInterface
%<modelDisable>(%<SLibModelFcnArgs("Disable",TLC_TRUE,"")>);
%else
%<::CompiledModel.GlobalScope.tModelObject>.disable();
%endif
%else
%if !SLibMdlEnableDisablePermitted()
static char msg[256];
if (strlen(ssGetPath(%<tSimStructArg>)) < 128) {
sprintf(msg, "The model is attempting to invoke the disable mothod of ...
the S-Function block %s for model '%<LibGetModelName()>', yet the code ...
generated for the model does not include the disable method/n", ssGetPath(%<tSimStructArg>));
} else {
sprintf(msg, "The model is attempting to invoke the disable mothod of ...
the S-Function block for model '%<LibGetModelName()>', yet the code ...
generated for the model does not include the disable method/n");
}
ssSetErrorStatus(%<tSimStructArg>, msg);
%else
(void) %<tSimStructArg>;
%endif
%endif
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#include "fixedpoint.c"
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
%<SetCurrentUtilsIncludesIdx("")>
%closefile ModelSfu
%<SLibAddGeneratedFileToList(sFunctionName + "." + LangFileExt, "interface", "source", "")>
%<SLibAddGeneratedFileToList("rtwtypes_sf.h", "interface", "header", "")>
%endwith