%implements "S-Function" "C"
%function FcnChildSFunctionIndex(block) void
%if !ISFIELD(block, "SFunctionIdx")
%addtorecord block SFunctionIdx NumChildSFunctions
%assign ::CompiledModel.ChildSFunctionList = ...
::CompiledModel.ChildSFunctionList + block
%assign ::CompiledModel.NumChildSFunctions = ...
::CompiledModel.NumChildSFunctions + 1
%endif
%return block.SFunctionIdx
%endfunction
%function FcnCopyStatesFromWorkVector(s, xc, xd) Output
(void) %<LibGenMemFcnCall("memcpy", xc, "sfcnX", ...
"ssGetNumContStates(%<s>)*sizeof(real_T)")>;
(void) %<LibGenMemFcnCall("memcpy", xd, "sfcnX+ssGetNumContStates(%<s>)", ...
"ssGetNumDiscStates(%<s>)*sizeof(real_T)")>;
%endfunction
%function FcnGetAndCheckSFunctionType(block)
%with block
%assign funcName = ParamSettings.FunctionName
%if ParamSettings.Inlined == "yes"
%assign fileExists = LibBlockSFunctionFileExists(funcName)
%if !fileExists
%assign errTxt = "Unable to locate inlined TLC file: %<funcName>.tlc"
%<LibBlockReportFatalError(block, errTxt)>
%endif
%if ::Accelerator && (funcName == "stateflow")
%assign SFunctionType = "OTHER"
%else
%assign SFunctionType = "TLC"
%endif
%elseif ParamSettings.Inlined == "skip"
%assign SFunctionType = "OTHER"
%elseif ParamSettings.FunctionType == "C-MEX"
%assign SFunctionType = "C-MEX"
%if SLibIsERTCodeFormat() && TYPE(TID) == "Vector" && ...
::CompiledModel.FixedStepOpts.SolverMode == "SingleTasking"
%if IsModelReferenceTarget()
%assign target = "Model reference "
%else
%assign target = "Embedded-C code format "
%endif
%endif
%else
%if ::Accelerator
%assign SFunctionType = "OTHER"
%else
%assign funcType = ParamSettings.FunctionType
%assign blockName = LibGetFormattedBlockPath(block)
%assign errTxt = "%<funcType> S-functions " ...
"without a corresponding TLC file are not supported. " ...
"You can inline your S-function (%<funcName>) by creating " ...
"a TLC file for it. You can also remap your S-function to C by " ...
"creating a corresponding C Mex source file "...
"and a %<funcName>.tlc file in the same " ...
"directory as the %<funcType> S-function which contains (on the " ...
"first line):/n" ...
" /%/% CallAsCMexLevel1/n" ...
"or/n" ...
" /%/% CallAsCMexLevel2/n"
%<LibBlockReportFatalError(block, errTxt)>
%endif
%endif
%endwith
%return SFunctionType
%endfunction
%function FcnCacheRTWGeneratedChildSfcnInfo(block, system) void
%if !ISFIELD(::CompiledModel, "RTWGeneratedChildSfcnExportFiles")
%addtorecord ::CompiledModel RTWGeneratedChildSfcnExportFiles ""
%addtorecord ::CompiledModel RTWGeneratedChildSfcn {}
%endif
%assign sfcnName = ParamSettings.FunctionName
%if !ISFIELD(::CompiledModel.RTWGeneratedChildSfcn, sfcnName)
%addtorecord ::CompiledModel.RTWGeneratedChildSfcn %<sfcnName> 1
%assign currExpFiles = ::CompiledModel.RTWGeneratedChildSfcnExportFiles
%openfile buffer
#undef S_FUNCTION_NAME
#if !defined(RTW_GENERATED_SFCN_TUNABLE_PRMS_%<sfcnName>)
#define RTW_GENERATED_SFCN_TUNABLE_PRMS_%<sfcnName>
#endif
%assign raccelUseMexFile = ...
::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
%if !::Accelerator && !raccelUseMexFile
#include "%<sfcnName>.h"
%endif
%<currExpFiles>
%closefile buffer
%assign ::CompiledModel.RTWGeneratedChildSfcnExportFiles = buffer
%assign buildDir = FEVAL("rtwprivate", "rtwattic", "getBuildDir")
%assign errmsgFromCB = FEVAL("RTW.copySfcnModulesToBuildDir","%<sfcnName>", buildDir)
%if !ISEMPTY(errmsgFromCB)
%openfile errTxt
%<errmsgFromCB>
%closefile errTxt
%<SLibReportErrorWithIdAndArgs("RTW:tlc:GenericMsg", errTxt)>
%endif
%endif
%endfunction
%function FcnGenerateCallForModelRefSimTarget(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID) Output
%assign simTargetWillUseMexFile = ...
IsModelReferenceSimTarget() && ParamSettings.WillBeDynamicallyLoaded == "yes"
%if !ISEMPTY(tid)
%assign methodCall = methodName + "(" + simStruct + ", %<tid>" + ");"
%else
%assign methodCall = methodName + "(" + simStruct + ");"
%endif
%openfile returnBuffer
%if simTargetWillUseMexFile
{
static const char* blockSIDForSFcnLoader = "%<blockSID>";
sfcnLoader_setCurrentSFcnBlockSID(blockSIDForSFcnLoader);
%if ParamSettings.ExpectsSeparateComplexMxArrays == "yes"
%if !ISEMPTY(tid)
void (*sfcnMethodPtr)(SimStruct*, int) = %<actualFcnCall>;
%<SLibWriteSFunctionGuards("if")>
simTarget_sfcnSeperateComplexCaller_withTID(%<simStruct>, sfcnMethodPtr, %<tid>);
%<SLibWriteSFunctionGuards("else")>
sfcnLoader_separateComplexHandler_withTID(%<simStruct>, sfcnMethodPtr, %<tid>);
%<SLibWriteSFunctionGuards("endif")>
%else
void (*sfcnMethodPtr)(SimStruct*) = %<actualFcnCall>;
%<SLibWriteSFunctionGuards("if")>
simTarget_sfcnSeperateComplexCaller(%<simStruct>, sfcnMethodPtr);
%<SLibWriteSFunctionGuards("else")>
sfcnLoader_separateComplexHandler(%<simStruct>, sfcnMethodPtr);
%<SLibWriteSFunctionGuards("endif")>
%endif
%else
%<methodCall>
%endif
}
%else
%<methodCall>
%endif
%closefile returnBuffer
%return returnBuffer
%endfunction
%function FcnGenerateCallForRapidAccelerator(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID) Output
%assign raccelUseMexFile = ...
::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
%openfile returnBuffer
%if raccelUseMexFile
%if !ISEMPTY(tid)
%if ISEQUAL(CompiledModel.SolverType, "FixedStep")
%assign adjustedTID = "(%<tid> <= 1) && gbl_raccel_tid01eq ? 0 : %<tid>"
%else
%assign adjustedTID = "%<tid>"
%endif
%assign methodCall = methodName + "(" + simStruct + ", %<adjustedTID>" + ");"
%else
%assign methodCall = methodName + "(" + simStruct + ");"
%endif
{
static const char* blockSIDForSFcnLoader = "%<blockSID>";
sfcnLoader_setCurrentSFcnBlockSID(blockSIDForSFcnLoader);
%if ParamSettings.ExpectsSeparateComplexMxArrays == "no"
int_T origSampleHit = ssGetSampleHitPtr(%<simStruct>)[0];
_ssSetSampleHit(%<simStruct>, 0, 1);
%<methodCall>
%if !ISEMPTY(tid) && ISEQUAL(CompiledModel.SolverType, "FixedStep")
_ssSetSampleHit(%<simStruct>, 0, origSampleHit);
%endif
%else
%if !ISEMPTY(tid)
void (*sfcnMethodPtr)(SimStruct*, int) = %<actualFcnCall>;
sfcnLoader_separateComplexHandler_withTID(%<simStruct>, sfcnMethodPtr, %<adjustedTID>);
%else
void (*sfcnMethodPtr)(SimStruct*) = %<actualFcnCall>;
sfcnLoader_separateComplexHandler(%<simStruct>, sfcnMethodPtr);
%endif
%endif
}
%else
%assign commaTID = ISEMPTY(tid) ? "" : ", %<tid>"
%assign methodCall = methodName + "(" + simStruct + commaTID + ");"
%<methodCall>
%endif
%closefile returnBuffer
%return returnBuffer
%endfunction
%function FcnGenerateCallForTargetThatCanUseSFcnMexFile(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID) Output
%if ::isRAccel
%<FcnGenerateCallForRapidAccelerator(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID)>
%elseif IsModelReferenceSimTarget()
%<FcnGenerateCallForModelRefSimTarget(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID)>
%endif
%endfunction
%function BlockInstanceSetup(block, system) void
%assign funcName = ParamSettings.FunctionName
%assign str = ""
%if LibSFunctionLevel() == "RTWLevel2"
%<FcnCacheRTWGeneratedChildSfcnInfo(block, system)>
%endif
%if LibSFunctionLevel() == "RTWLevel2"
%assign str = "RTW Generated "
%endif
%assign TypeLevel = "%<str>Level%<ParamSettings.FunctionLevel> %<Type>"
%assign block = block + TypeLevel
%assign sFunctionType = FcnGetAndCheckSFunctionType(block)
%addtorecord block SFunctionType sFunctionType
%if sFunctionType == "TLC"
%if SLibSfcnHasBranchFcnCall(block)
%foreach callIdx = block.NumSFcnSysOutputCalls
%assign nCalledFC = block.SFcnSystemOutputCallMappingInfo[callIdx].NumOfCalledFC
%if nCalledFC > 1
%assign recIdx = block.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
%foreach fcIdx = nCalledFC
%assign blockToCall = block.SFcnSystemOutputCall[recIdx].BlockToCall
%assert !ISEQUAL(blockToCall, "unconnected")
%assign sysIdx = blockToCall[0]
%assign blkIdx = blockToCall[1]
%assign calledBlock = ::CompiledModel.System[sysIdx].Block[blkIdx]
%if calledBlock.Type == "SubSystem"
%with calledBlock
%assign sysIdx = LibBlockParamSetting("Subsystem", "SystemIdx")
%assign calledSys = System[sysIdx]
%endwith
%if !ISFIELD(calledSys, "IsBranchedSys")
%addtorecord calledSys IsBranchedSys TLC_TRUE
%endif
%endif
%assign recIdx = recIdx + 1
%endforeach
%endif
%endforeach
%endif
%if SLibIsMainCodeGenPhase()
%assign origModuleIdx = ::CurrentModuleIdx
%assign ::CurrentModuleIdx = system.CGIRModuleIdx
%<GENERATE_TYPE(block, "BlockInstanceSetup", funcName, system)>
%assign ::CurrentModuleIdx = origModuleIdx
%else
%<GENERATE_TYPE(block, "BlockInstanceSetup", funcName, system)>
%endif
%elseif sFunctionType == "C-MEX" || (sFunctionType == "OTHER" && ...
::Accelerator)
%assign ps = ParamSettings
%if ps.FunctionLevel == 1
%assign InitializeSizesEmpty = 0
%assign InitializeSampleTimesEmpty = 0
%assign InitializeConditionsEmpty = 0
%assign StartEmpty = 0
%assign SetupRuntimeResourcesEmpty = 1
%assign OutputsEmpty = 0
%assign UpdateEmpty = 0
%assign DerivativesEmpty = 0
%assign ProjectionEmpty = 0
%assign ForcingFunctionEmpty = 0
%assign MassMatrixEmpty = 0
%assign ZeroCrossingsEmpty = 1
%assign EnableEmpty = 0
%assign DisableEmpty = 0
%assign TerminateEmpty = 0
%assign CleanupRuntimeResourcesEmpty = 1
%else
%assign InitializeSizesEmpty = 1
%assign InitializeSampleTimesEmpty = 1
%assign InitializeConditionsEmpty = 1
%assign SetupRuntimeResourcesEmpty = 1
%assign StartEmpty = 1
%assign OutputsEmpty = 1
%assign UpdateEmpty = 1
%assign DerivativesEmpty = 1
%assign ProjectionEmpty = 1
%assign ForcingFunctionEmpty = 1
%assign MassMatrixEmpty = 1
%assign ZeroCrossingsEmpty = 1
%assign EnableEmpty = 1
%assign DisableEmpty = 1
%assign TerminateEmpty = 1
%assign CleanupRuntimeResourcesEmpty = 1
%endif
%assign ps = ps + InitializeSizesEmpty
%assign ps = ps + InitializeSampleTimesEmpty
%assign ps = ps + InitializeConditionsEmpty
%assign ps = ps + SetupRuntimeResourcesEmpty
%assign ps = ps + StartEmpty
%assign ps = ps + OutputsEmpty
%assign ps = ps + UpdateEmpty
%assign ps = ps + DerivativesEmpty
%assign ps = ps + ProjectionEmpty
%assign ps = ps + ForcingFunctionEmpty
%assign ps = ps + MassMatrixEmpty
%assign ps = ps + ZeroCrossingsEmpty
%assign ps = ps + EnableEmpty
%assign ps = ps + DisableEmpty
%assign ps = ps + TerminateEmpty
%assign ps = ps + CleanupRuntimeResourcesEmpty
%if ps.FunctionLevel == 1
%assign numDiscStates = DiscStates[0]
%assign numContStates = ContStates[0]
%assign nStates = numDiscStates + numContStates
%assign statesDiscontiguous = (numDiscStates > 0) && (numContStates > 0)
%else
%foreach idx = SIZE(ps.SFcnmdlRoutines, 1)
%switch ps.SFcnmdlRoutines[idx]
%case "mdlInitializeSizes"
%assign ps.InitializeSizesEmpty = 0
%break
%case "mdlInitializeSampleTimes"
%assign ps.InitializeSampleTimesEmpty = 0
%break
%case "mdlInitializeConditions"
%assign ps.InitializeConditionsEmpty = 0
%break
%case "mdlSetupRuntimeResources"
%assign ps.SetupRuntimeResourcesEmpty = 0
%break
%case "mdlStart"
%assign ps.StartEmpty = 0
%break
%case "mdlOutputs"
%assign ps.OutputsEmpty = 0
%break
%case "mdlUpdate"
%assign ps.UpdateEmpty = 0
%break
%case "mdlDerivatives"
%assign ps.DerivativesEmpty = 0
%break
%case "mdlProjection"
%assign ps.ProjectionEmpty = 0
%break
%case "mdlForcingFunction"
%assign ps.ForcingFunctionEmpty = 0
%break
%case "mdlMassMatrix"
%assign ps.MassMatrixEmpty = 0
%break
%case "mdlZeroCrossings"
%assign ps.ZeroCrossingsEmpty = 0
%break
%case "mdlTerminate"
%assign ps.TerminateEmpty = 0
%break
%case "mdlCleanupRuntimeResources"
%assign ps.CleanupRuntimeResourcesEmpty = 0
%break
%case "mdlEnable"
%assign ps.EnableEmpty = 0
%break
%case "mdlDisable"
%assign ps.DisableEmpty = 0
%break
%case "mdlRTW"
%assign raccelUseMexFile = ...
::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
%if (LibSFunctionLevel() == "RTWLevel2") || ::Accelerator || IsModelReferenceSimTarget() || raccelUseMexFile
%break
%endif
%assign errTxt = "This S-function block must have a " ...
"corresponding TLC file since it has an mdlRTW() function."
%<LibBlockReportError(block, errTxt)>
%endswitch
%endforeach
%assign statesDiscontiguous = 0
%endif
%addtorecord block StatesDiscontiguous statesDiscontiguous
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%foreach paramIdx = Parameters[0]
%assign param = Parameter[paramIdx]
%assign param_array = SLibGetAllASTParamsForBlockParam(param)
%foreach mdlParamIdx = SIZE(param_array, 1)
%assign mdlParam = ModelParameters.Parameter[param_array[mdlParamIdx]]
%if (LibGetDataTypeIdAliasedThruToFromId(LibGetRecordDataTypeId(mdlParam)) != tSS_DOUBLE || ...
LibGetRecordIsComplex(mdlParam)) && !::Accelerator && !IsModelReferenceTarget()
%assign errTxt = "This non-inlined C-MEX Block " ...
"has non-double and(or) complex parameters. The Real-Time " ...
"Workshop does not support C-MEX S-Functions " ...
"with non-double or complex parameters without a "...
"corresponding TLC file."
%<LibBlockReportFatalError(block, errTxt)>
%endif
%assign prmSize = SLibGetSizeOfValueFromParamRec(mdlParam)
%if prmSize[0] > 1
%<LibAddIdentifier(mdlParam, "MatlabMatrix", 1)>
%endif
%assign mdlParam.WasAccessedAsVariable = 1
%endforeach
%endforeach
%endif
%endfunction
%function BlockTypeSetup(block, system) void
%assign funcName = ParamSettings.FunctionName
%assign sFunctionType = FcnGetAndCheckSFunctionType(block)
%switch sFunctionType
%case "TLC"
%if SLibIsMainCodeGenPhase()
%assign origModuleIdx = ::CurrentModuleIdx
%assign ::CurrentModuleIdx = system.CGIRModuleIdx
%<GENERATE_TYPE(block, "BlockTypeSetup", funcName, system)>
%assign ::CurrentModuleIdx = origModuleIdx
%else
%<GENERATE_TYPE(block, "BlockTypeSetup", funcName, system)>
%endif
%break
%case "C-MEX"
%assign raccelUseMexFile = ...
::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
%if LibSFunctionLevel() == "RTWLevel2" && !raccelUseMexFile
%assign sfcnInc1 = "%<funcName>cn_rtw/%<funcName>.h"
%assign sfcnInc2 = "%<funcName>cn_rtw/%<funcName>_private.h"
%openfile tmpBuf1
#if !defined(RTW_GNERATED_SFCN_NOT_PRIVATE_%<funcName>)
#define RTW_GNERATED_SFCN_NOT_PRIVATE_%<funcName>
#endif
%closefile tmpBuf1
%openfile tmpBuf2
#if !defined(MATLAB_MEX_FILE)
#undef S_FUNCTION_NAME
#include "%<sfcnInc1>"
#include "%<sfcnInc2>"
#endif
%closefile tmpBuf2
%openfile tmpBuf
%<tmpBuf1>
%<tmpBuf2>
%closefile tmpBuf
%<LibCacheIncludes(tmpBuf)>/
%<SLibCacheCodeToFile("mdl_data_typedef", tmpBuf2)>
%endif
%endswitch
%endfunction
%function BlockInitialValues(block, system, vectType) void
%assign ans = ""
%assign funcName = ParamSettings.FunctionName
%if SFunctionType == "TLC"
%assign ans = GENERATE_TYPE(block, "BlockInitialValues", ...
funcName, system, vectType)
%endif
%return ans
%endfunction
%function SfunctionSampleHitGuard()
%assign sampleHitGuard = ""
%assign orOperator = ""
%assign noGuardNeeded = TLC_FALSE
%assign multTIDs = TLC_FALSE
%if LibTriggeredTID(TID) || ISEQUAL(TID, "constant") || ...
LibAsynchronousTriggeredTID(TID) || ...
SLibIsPeriodicRateGrouping() || SIZE(TID,1) == 1
%assign noGuardNeeded = TLC_TRUE
%else
%assert(TYPE(TID) == "Vector")
%foreach idx = SIZE(ParamSettings.SampleTimesToSet, 0)
%assign tidIdx = ParamSettings.SampleTimesToSet[idx][1]
%if tidIdx == -2
%continue
%endif
%if SLibModelWideEventTID(tidIdx)
%continue
%endif
%assign tidString = LibIsSampleHit(tidIdx)
%if tidString == "1"
%assign noGuardNeeded = TLC_TRUE
%endif
%assign multTIDs = !ISEMPTY(sampleHitGuard)
%assign sampleHitGuard = sampleHitGuard + "%<orOperator>%<tidString>"
%assign orOperator = " || "
%endforeach
%if !multTIDs
%assign noGuardNeeded = TLC_TRUE
%endif
%endif
%return (noGuardNeeded) ? "" : sampleHitGuard
%endfunction
%function BlockInstanceData(block, system) Output
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "BlockInstanceData", funcName, system)>/
%break
%endswitch
%endfunction
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,sigIdx,retType) void
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%return GENERATE_TYPE(block, "BlockOutputSignal", funcName, ...
system,portIdx,ucv,lcv,sigIdx,retType)
%endswitch
%endfunction
%function SetupRuntimeResources(block, system) Output
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "SetupRuntimeResources", funcName, system)>
%break
%case "C-MEX"
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.SetupRuntimeResourcesEmpty
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnSetupRuntimeResources"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlSetupRuntimeResources(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
}
%endif
%endswitch
%endfunction
%function Start(block, system) Output
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "Start", funcName, system)>
%break
%case "C-MEX"
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.StartEmpty
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnStart"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlStart(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
}
%endif
%endswitch
%endfunction
%function InitializeConditions(block, system) Output
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if !ParamSettings.InitializeConditionsEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, ...
"SS_CALL_MDL_INITIALIZE_CONDITIONS")>
%endif
%endif
%break
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "InitializeConditions", funcName, system)>
%break
%case "C-MEX"
%if !ParamSettings.InitializeConditionsEmpty
%if ::Accelerator
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, ...
"SS_CALL_MDL_INITIALIZE_CONDITIONS")>
%else
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%switch ParamSettings.FunctionLevel
%case 1
real_T *sfcnX = ssGetContStates(%<s>);
sfcnInitializeConditionsLevel1(sfcnX, %<s>);
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%assign numContStates = ContStates[0]
%assign numDiscStates = DiscStates[0]
%assign numBlkStates = numContStates + numDiscStates
%if numContStates > 0 && numDiscStates > 0
%assign Xc = "&%<LibBlockContinuousState("", "", 0)>"
%assign Xd = "&%<LibBlockDiscreteState("", "", 0)>"
%<FcnCopyStatesFromWorkVector(s, Xc, Xd)>/
%endif
%break
%case 2
%assign methodName = "sfcnInitializeConditions"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
s + "->modelMethods.sFcn.mdlInitializeConditions.level2"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName,"", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%endfunction
%function FcnGetTIDForSfcn(block, system)
%assign tid = block.TID
%if ISEQUAL(tid, "constant")
%assign tid = 0
%elseif SLibIsMultiRateAndPeriodicRateGrouping(system)
%assign tid = system.CurrentTID
%elseif SLibIsERTCodeFormat()
%if TYPE(tid) == "Vector"
%assign isZeroTid = TLC_FALSE
%if ISEQUAL(SolverType, "FixedStep") && FixedStepOpts.TID01EQ
%assign isZeroTid = TLC_TRUE
%foreach idx = SIZE(tid,1)
%if !ISEQUAL(tid[idx], 0) && ...
!ISEQUAL(tid[idx], 1)
%assign isZeroTid = TLC_FALSE
%break
%endif
%endforeach
%endif
%assign tid = isZeroTid ? 0 : LibTID()
%else
%assign tid = SLibGetNumericTID(block)
%endif
%else
%assign tid = LibTID()
%endif
%if IsModelReferenceTarget()
%assign tidMap = FcnGetMdlRefGlobalTIDMap("")
%assign indx = "%<tidMap>[%<tid>]"
%return indx
%else
%return tid
%endif
%endfunction
%function Update(block, system) Output
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if !ParamSettings.UpdateEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_UPDATE")>
%endif
%endif
%break
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "Update", funcName, system)>
%break
%case "C-MEX"
%if ::Accelerator
%if !ParamSettings.UpdateEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_UPDATE")>
%endif
%else
%assign numDiscStates = DiscStates[0]
%if ParamSettings.FunctionLevel == 1
%assign directFeedthrough = ParamSettings.DirectFeedthrough
%else
%assign directFeedthrough = "no"
%foreach ipIdx = NumDataInputPorts
%if ParamSettings.DirectFeedthrough[ipIdx] == "yes"
%assign directFeedthrough = "yes"
%break
%endif
%endforeach
%endif
%assign callUpdate = 0
%assign ps = ParamSettings
%if ps.FunctionLevel == 1
%if numDiscStates > 0 || directFeedthrough == "no"
%assign callUpdate = 1
%endif
%elseif ps.FunctionLevel == 2
%if !ps.UpdateEmpty
%assign callUpdate = 1
%endif
%endif
%if callUpdate
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
%assign tid = FcnGetTIDForSfcn(block,system)
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%switch ps.FunctionLevel
%case 1
%if CodeFormat == "S-Function"
real_T *sfcnU = _ssGetU(%<s>);
%else
real_T *sfcnU = ssGetU(%<s>);
%endif
real_T *sfcnX = ssGetContStates(%<s>);
sfcnUpdateLevel1(sfcnX, sfcnU, %<s>, %<tid>);
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%assign numContStates = ContStates[0]
%assign numBlkStates = numContStates + numDiscStates
%if numContStates > 0 && numDiscStates > 0
%assign Xc = "&%<LibBlockContinuousState("", "", 0)>"
%assign Xd = "&%<LibBlockDiscreteState("", "", 0)>"
%<FcnCopyStatesFromWorkVector(s, Xc, Xd)>/
%endif
%break
%case 2
%assign stGuard = SfunctionSampleHitGuard()
%assign needGuard = (stGuard != "") && (IsModelReferenceSimTarget() || ::isRAccel || ::Accelerator)
%if needGuard
if (%<stGuard>) {
%endif
%assign methodName = "sfcnUpdate"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlUpdate(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, tid, actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + "," + STRING(tid) + ");"
%<methodCall>
%endif
%if needGuard
}
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%endfunction
%function Derivatives(block, system) Output
%if CodeFormat == "S-Function" || IsModelReferenceTarget()
%assign underScore = "_"
%else
%assign underScore = ""
%endif
%assign numContStates = ContStates[0]
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if numContStates > 0 && !ParamSettings.DerivativesEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_DERIVATIVES")>
%endif
%endif
%break
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "Derivatives", funcName, system)>
%break
%case "C-MEX"
%if (numContStates > 0 && !ParamSettings.DerivativesEmpty) || (ParamSettings.CallSimulinkStateWithContStates == "yes")
%if ::Accelerator
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_DERIVATIVES")>
%else
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
%assign optStartIndex = SLibGet1DArrayIndexer(numContStates,"","",0)
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%if IsModelReferenceTarget()
real_T *sfcndX_fx = (real_T *) ...
&%<LibBlockContinuousStateDerivative("", "", 0)>;
%else
%assign cs = ::CompiledModel.ContStates.ContState[ContStates[1]]
real_T *sfcndX_fx = (real_T *) &((%<::tXdotType> *) ...
%<RTMGet("dX")>)->%<cs.Identifier>%<optStartIndex>;
%endif
%switch ParamSettings.FunctionLevel
%case 1
real_T *sfcnU = %<underScore>ssGetU(%<s>);
real_T *sfcnX = ssGetContStates(%<s>);
%<underScore>ssSetdX(%<s>, sfcndX_fx);
sfcnDerivativesLevel1(sfcndX_fx, sfcnX, sfcnU, %<s>, 0);
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%case 2
%<underScore>ssSetdX(%<s>, sfcndX_fx);
%assign methodName = "sfcnDerivatives"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlDerivatives(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%endfunction
%function Projection(block, system) Output
%assign numContStates = ContStates[0]
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if numContStates > 0 && !ParamSettings.ProjectionEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_PROJECTION")>
%endif
%endif
%break
%case "TLC"
%if ParamSettings.HasMdlProjection == "yes"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "Projection", funcName, system)>
%endif
%break
%case "C-MEX"
%if numContStates > 0 && !ParamSettings.ProjectionEmpty || (ParamSettings.CallSimulinkStateWithContStates == "yes")
%if ::Accelerator
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_PROJECTION")>
%else
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
%assign optStartIndex = SLibGet1DArrayIndexer(numContStates,"","",0)
%switch ParamSettings.FunctionLevel
%case 2
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnProjection"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlProjection(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%endfunction
%function ForcingFunction(block, system) Output
%if ParamSettings.IsLinearlyImplicit == "no"
%<Derivatives(block,system)>
%return
%endif
%if CodeFormat == "S-Function" || IsModelReferenceTarget()
%assign underScore = "_"
%else
%assign underScore = ""
%endif
%assign numContStates = ContStates[0]
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if numContStates > 0 && !ParamSettings.ForcingFunctionEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_FORCINGFUNCTION")>
%endif
%endif
%break
%case "TLC"
%if ParamSettings.IsLinearlyImplicit == "yes"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "ForcingFunction", funcName, system)>
%endif
%break
%case "C-MEX"
%if numContStates > 0 && !ParamSettings.ForcingFunctionEmpty || (ParamSettings.CallSimulinkStateWithContStates == "yes")
%if ::Accelerator
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_FORCINGFUNCTION")>
%else
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
%assign optStartIndex = SLibGet1DArrayIndexer(numContStates,"","",0)
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%if IsModelReferenceTarget()
real_T *sfcndX_fx = (real_T *) ...
&%<LibBlockContinuousStateDerivative("", "", 0)>;
%else
%assign cs = ::CompiledModel.ContStates.ContState[ContStates[1]]
real_T *sfcndX_fx = (real_T *) &((%<::tXdotType> *) ...
%<RTMGet("dX")>)->%<cs.Identifier>%<optStartIndex>;
%endif
%switch ParamSettings.FunctionLevel
%case 2
%<underScore>ssSetdX(%<s>, sfcndX_fx);
%assign methodName = "sfcnForcingFunction"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlForcingFunction(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%endfunction
%function MassMatrix(block, system) Output
%assign numContStates = ContStates[0]
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if numContStates > 0 && !ParamSettings.MassMatrixEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_MASSMATRIX")>
%endif
%endif
%break
%case "TLC"
%if ParamSettings.IsLinearlyImplicit == "yes"
%assign funcName = ParamSettings.FunctionName
%if SLibPartitionGroupingSystem(system)
%assign savedPID = ::GlobalCurrentPID
%assign ::GlobalCurrentPID = SLibGetPIDFromBlock(block, 0 /% tid %/)
%endif
%<GENERATE_TYPE(block, "MassMatrix", funcName, system)>
%if SLibPartitionGroupingSystem(system)
%assign ::GlobalCurrentPID = savedPID
%endif
%endif
%break
%case "C-MEX"
%if numContStates > 0 && !ParamSettings.MassMatrixEmpty || (ParamSettings.CallSimulinkStateWithContStates == "yes")
%if ::Accelerator
%assert ParamSettings.Inlined != "yes"
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_MASSMATRIX")>
%else
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%switch ParamSettings.FunctionLevel
%case 2
ssSetMassMatrixPr(%<s>,%<SLibBlockMassMatrixPr()>);
%assign methodName = "sfcnMassMatrix"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlMassMatrix(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%endfunction
%function InvokeFcnCallForTracking(sfcnBlock, callType) void
%foreach callIdx = sfcnBlock.NumSFcnSysOutputCallDsts
%with sfcnBlock.SFcnSystemOutputCall[callIdx]
%if ISEQUAL(BlockToCall, "unconnected")
%continue
%endif
%assign sysIdx = BlockToCall[0]
%assign blkIdx = BlockToCall[1]
%assign ssBlock = ::CompiledModel.System[sysIdx].Block[blkIdx]
%assign isSubsystem = (ssBlock.Type == "SubSystem")
%if isSubsystem
%assign dstSysIdx = ssBlock.SubsystemParamSettings.SystemIdx
%if !FcnSubsystemIsAsycnTopSS(::CompiledModel.System[dstSysIdx])
%assign unused = ...
LibExecuteFcn%<callType>(ssBlock, FcnPortElement, ...
ParamSettings.SampleTimesToSet[0][1])
%endif
%endif
%endwith
%endforeach
%endfunction
%function InvokeOutputsFcnCallForTracking(sfcnBlock) void
%<InvokeFcnCallForTracking(sfcnBlock, "Call")>
%if sfcnBlock.ParamSettings.ExplicitFCSSCtrl == "yes"
%<InvokeFcnCallForTracking(sfcnBlock, "Enable")>
%<InvokeFcnCallForTracking(sfcnBlock, "Disable")>
%endif
%endfunction
%function Outputs(block, system) void
%openfile tmpBuf
%switch SFunctionType
%case "OTHER"
%if ::Accelerator
%if !ParamSettings.OutputsEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_OUTPUTS")>
%<InvokeOutputsFcnCallForTracking(block)>
%endif
%endif
%break
%case "TLC"
%if !ISFIELD(block, "GenCodeForTopAsyncSS") && ...
ISFIELD(block, "NumSFcnSysOutputCallDsts")
%foreach callIdx = NumSFcnSysOutputCallDsts
%if "%" == "unconnected"
%continue
%endif
%if FcnBlkIsAsyncTopSfcn(block)
%addtorecord block GenCodeForTopAsyncSS TLC_FALSE
%break
%endif
%endforeach
%endif
%assign genCode = TLC_FALSE
%if !ISFIELD(block, "GenCodeForTopAsyncSS")
%assign genCode = TLC_TRUE
%elseif ISFIELD(block, "AsyncCallerGenCode") && ...
AsyncCallerGenCode == TLC_TRUE
%assign genCode = TLC_TRUE
%elseif block.GenCodeForTopAsyncSS
%assign genCode = TLC_TRUE
%endif
%if genCode
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "Outputs", funcName, system)> /
%endif
%break
%case "C-MEX"
%with block
%if SLibIsERTCodeFormat() && !IsModelReferenceSimTarget()
%assert TYPE(TID) == "Vector" || ...
TYPE(TID) == "Number" || ...
ISEQUAL(TID, "triggered") || ...
ISEQUAL(TID, "constant")
%if TYPE(TID) == "Vector"
%if !FcnBlkIsAsyncTopSfcn(block)
%assign numTids = SIZE(TID,1)
%assign ::CompiledModel.RequireMultiRateSampleHits = (numTids > 1)
%foreach i = numTids
%assign tid = TID[i]
%foreach j = numTids - i - 1
%assign sti = TID[j+i+1]
%<SLibSetNeedRateInteraction(sti,tid)>
%endforeach
%<SLibSetNeedFloatAbsoluteTime(tid)>
%endforeach
%endif
%elseif TYPE(TID) == "Number"
%<SLibSetNeedFloatAbsoluteTime(TID)>
%elseif ISEQUAL(TID, "triggered")
%assert TYPE(TriggerTID) == "Vector" && TriggerTID[0] >= 0
%<SLibSetNeedFloatAbsoluteTime(TriggerTID[0])>
%endif
%endif
%endwith
%if !ParamSettings.OutputsEmpty
%<InvokeOutputsFcnCallForTracking(block)>
%if ::Accelerator
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_OUTPUTS")>
%else
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
%if ISFIELD(block, "SampleTimeIdx") && ...
!ISEQUAL(SampleTimeIdx, TID)
%assert TYPE(TID) == "Number" && TYPE(SampleTimeIdx) == "Number"
if( %<LibIsSpecialSampleHit(SampleTimeIdx, TID)> ) {
%else
{
%endif
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
%assign tid = FcnGetTIDForSfcn(block,system)
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%switch ParamSettings.FunctionLevel
%case 1
%if CodeFormat == "S-Function"
real_T *sfcnU = _ssGetU(%<s>);
%else
real_T *sfcnU = ssGetU(%<s>);
%endif
real_T *sfcnX = ssGetContStates(%<s>);
%assign sfcnY = SLibGetNullDefinitionFromTfl()
%if NumDataOutputPorts > 0
%assign idnum = IDNUM(DataOutputPort[0].SignalSrc[0])
%if idnum[0] != "F"
%assign sfcnY = "sfcnY"
real_T *sfcnY = &(%<LibBlockOutputSignal(0,"","",0)>);
%endif
%endif
%assign numContStates = ContStates[0]
%assign numDiscStates = DiscStates[0]
%assign numBlkStates = numContStates + numDiscStates
%if numContStates > 0 && numDiscStates > 0
%assign Xc = "&%<LibBlockContinuousState("", "", 0)>"
%assign Xd = "&%<LibBlockDiscreteState("", "", 0)>"
(void) %<LibGenMemFcnCall("memcpy", "sfcnX", Xc, ...
"ssGetNumContStates(%<s>)*sizeof(real_T)")>;
if (ssIsMajorTimeStep(%<s>) ) {
(void) %<LibGenMemFcnCall("memcpy", ...
"sfcnX+ssGetNumContStates(%<s>)", Xd, ...
"ssGetNumDiscStates(%<s>)*sizeof(real_T)")>;
}
sfcnOutputsLevel1(%<sfcnY>, sfcnX, sfcnU, %<s>, %<tid>);
%if CodeFormat == "S-Function" || IsModelReferenceTarget()
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%endif
if( ssIsMajorTimeStep(%<s>) ) {
%<FcnCopyStatesFromWorkVector(s, Xc, Xd)>/
}
%else
sfcnOutputsLevel1(%<sfcnY>, sfcnX, sfcnU, %<s>, %<tid>);
%if CodeFormat == "S-Function" || IsModelReferenceTarget()
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%endif
%endif
%break
%case 2
%if ParamSettings.HasVariableSampleTime == "yes"
real_T tNext;
if( %<LibIsSampleHit(block.VarTsTID)> ) {
if (ssGetTNextWasAdjusted(%<s>, %<block.VarTsTID>)) {
ssSetTNext(%<s>, ssGetT(%<s>));
}
%assign methodName = "sfcnGetTimeOfNextVarHit"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
s + "->modelMethods.sFcn.mdlGetTimeOfNextVarHit"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
tNext = ssGetTNext(%<s>);
%<LibSetVarNextHitTime(block,"tNext")>;
}
%endif
%foreach opIdx = NumDataOutputPorts
%if !LibBlockOutputSignalIsInBlockIO(opIdx)
%assign idnum = IDNUM(DataOutputPort[0].SignalSrc[0])
%if idnum[0] != "F"
%assign yAddr = LibBlockOutputSignalAddr(opIdx, "", "", 0)
%if CodeFormat == "S-Function" || IsModelReferenceTarget()
_ssSetOutputPortSignal(%<s>, %<opIdx>, %<yAddr>);
%else
ssSetOutputPortSignal(%<s>, %<opIdx>, %<yAddr>);
%endif
%endif
%endif
%endforeach
%assign stGuard = SfunctionSampleHitGuard()
%assign needGuard = (stGuard != "") && (IsModelReferenceSimTarget() || ::isRAccel || ::Accelerator)
%if needGuard
if (%<stGuard>) {
%endif
%assign methodName = "sfcnOutputs"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
s + "->modelMethods.sFcn.mdlOutputs.level2"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, tid, actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + "," + STRING(tid) + ");"
%<methodCall>
%endif
%if needGuard
}
%endif
%if CodeFormat == "S-Function" || IsModelReferenceTarget()
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
%endif
%break
%endswitch
}
%endif
%endif
%break
%endswitch
%closefile tmpBuf
%return tmpBuf
%endfunction
%function SetDims(block, system, oIdx, rIdx) void
%openfile tmpBuf
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "SetDims", funcName, system, oIdx, rIdx)> /
%break
%case "C-MEX"
%if ::Accelerator
%<SLibCallSFcnSetDimsInSimulink(system, block, oIdx, rIdx)>
%endif
%break
%endswitch
%closefile tmpBuf
%return tmpBuf
%endfunction
%function FinalizeAllDims(block, system) void
%openfile tmpBuf
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "FinalizeAllDims", funcName, system)> /
%break
%endswitch
%closefile tmpBuf
%return tmpBuf
%endfunction
%function Enable(block, system) Output
%openfile buffer
%switch SFunctionType
%case "TLC"
%if ParamSettings.HasVariableSampleTime == "yes"
%<SLibResetNextVHTDueToEnable(block)>
%endif
%if LibSFunctionLevel() == "RTWLevel2"
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.EnableEmpty
%<LibBlockReportError(block, "Inlined Enable function not supported.")>
%endif
%else
%assign funcName = ParamSettings.FunctionName
%if !ISFIELD(block, "GenCodeForTopAsyncSS") && ...
FcnBlkIsAsyncTopSfcn(block) && ...
(IsModelReferenceTarget() || SLibIsExportFcnDiagram())
%addtorecord block GenCodeForTopAsyncSS TLC_FALSE
%endif
%<GENERATE_TYPE(block, "Enable", funcName, system)>
%endif
%break
%case "C-MEX"
%if ParamSettings.HasVariableSampleTime == "yes"
%<SLibResetNextVHTDueToEnable(block)>
%endif
%if ::Accelerator
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system,block,"SS_CALL_RTW_GENERATED_ENABLE")>
%else
%if LibSFunctionLevel() == "RTWLevel2"
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.EnableEmpty
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
sfcnRTWGeneratedEnable(%<s>);
}
%endif
%else
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.EnableEmpty
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnEnable"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlEnable(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
}
%endif
%endif
%endif
%if ParamSettings.ExplicitFCSSCtrl == "yes"
%<InvokeFcnCallForTracking(block, "Enable")>
%endif
%endswitch
%closefile buffer
%if !ISEMPTY(buffer) && !WHITE_SPACE(buffer)
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
%<buffer>
%endif
%endfunction
%function Disable(block, system) Output
%openfile buffer
%if ParamSettings.HasVariableSampleTime == "yes"
%<LibSetVarNextHitTime(block,LibRealNonFinite("-inf"))>;
%endif
%switch SFunctionType
%case "TLC"
%if LibSFunctionLevel() == "RTWLevel2"
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.DisableEmpty
%<LibBlockReportError(block, "Inlined Disable function not supported.")>
%endif
%else
%assign funcName = ParamSettings.FunctionName
%if !ISFIELD(block, "GenCodeForTopAsyncSS") && ...
FcnBlkIsAsyncTopSfcn(block) && ...
(IsModelReferenceTarget() || SLibIsExportFcnDiagram())
%addtorecord block GenCodeForTopAsyncSS TLC_FALSE
%endif
%<GENERATE_TYPE(block, "Disable", funcName, system)>
%endif
%break
%case "C-MEX"
%if ::Accelerator
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system,block,"SS_CALL_RTW_GENERATED_DISABLE")>
%else
%if LibSFunctionLevel() == "RTWLevel2"
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.DisableEmpty
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
sfcnRTWGeneratedDisable(%<s>);
}
%endif
%else
%if ParamSettings.FunctionLevel == 2 && !ParamSettings.DisableEmpty
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
{
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnDisable"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
"ssGetmdlDisable(%<s>)"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
}
%endif
%endif
%endif
%if ParamSettings.ExplicitFCSSCtrl == "yes"
%<InvokeFcnCallForTracking(block, "Disable")>
%endif
%endswitch
%closefile buffer
%if !ISEMPTY(buffer) && !WHITE_SPACE(buffer)
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
%<buffer>
%endif
%endfunction
%function ZeroCrossings(block, system) Output
%if ParamSettings.FunctionLevel == 2
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "ZeroCrossings", funcName, system)>
%break
%case "C-MEX"
%if ::Accelerator
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
/* Call into Simulink for MEX-version of S-function */
%<SLibCallBlockInSimulink(system,block,"SS_CALL_MDL_ZERO_CROSSINGS")>
%else
%if !ParamSettings.ZeroCrossingsEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign s = ::tChildSimStruct
SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
ssSetNonsampledZCs(%<s>, &(%<LibBlockZCSignalValue("", "", 0, 0)>));
%assign methodName = "sfcnZeroCrossings"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
s + "->modelMethods.sFcn.mdlZeroCrossings"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + s + ");"
%<methodCall>
%endif
if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
}
%endif
%endif
%break
%endswitch
%endif
%endfunction
%function Terminate(block, system) Output
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "Terminate", funcName, system)>
%break
%case "C-MEX"
%if !ParamSettings.TerminateEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign simStruct = ::tChildSimStruct
SimStruct *%<simStruct> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnTerminate"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
simStruct + "->modelMethods.sFcn.mdlTerminate"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
simStruct, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + simStruct + ");"
%<methodCall>
%endif
}
%endif
%break
%endswitch
%endfunction
%function CleanupRuntimeResources(block, system) Output
%switch SFunctionType
%case "TLC"
%assign funcName = ParamSettings.FunctionName
%<GENERATE_TYPE(block, "CleanupRuntimeResources", funcName, system)>
%break
%case "C-MEX"
%if !ParamSettings.CleanupRuntimeResourcesEmpty
/* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
{
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign simStruct = ::tChildSimStruct
SimStruct *%<simStruct> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%assign methodName = "sfcnCleanupRuntimeResources"
%if ::isRAccel || IsModelReferenceSimTarget()
%assign actualFcnCall = ...
simStruct + "->states.modelMethods2->modelMethods4->mdlCleanupRuntimeResources"
%assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
simStruct, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
%<raccelCall>
%else
%assign methodCall = methodName + "(" + simStruct + ");"
%<methodCall>
%endif
}
%endif
%assign numArgs = Parameters[0] / 2
%if numArgs > 0
%if IsModelReferenceSimTarget()
%assign underScore = "_"
%<SLibWriteSFunctionGuards("if")>
%assign childSFunctionIdx = FcnChildSFunctionIndex(block)
%assign simStruct = ::tChildSimStruct
SimStruct *%<simStruct> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
%foreach argIdx = numArgs
{
mxArray *param = %<underScore>ssGetSFcnParam(%<simStruct>, %<argIdx>);
if (!mxIsEmpty(param))
{
mxDestroyArray(param);
%<underScore>ssSetSFcnParam(%<simStruct>, %<argIdx>, NULL);
}
}
%endforeach
%<SLibWriteSFunctionGuards("endif")>
%endif
%endif
%break
%endswitch
%endfunction