%selectfile NULL_FILE
%if EXISTS("_ERT_MODELREF_TIMING_") == 0
%assign _ERT_MODELREF_TIMING_ = 1
%function SLibComputeNumTaskTicks(period, stepSize) void
%assign nTaskTicks = period / stepSize + 0.5
%assign nTaskTicks = CAST("Number",FEVAL("floor", nTaskTicks))
%return nTaskTicks
%endfunction
%function FcnComputeTaskTickLimit(tidIdx) void
%assign stepSize = SLibGetFundamentalStepSize()
%assign period = SampleTime[tidIdx].PeriodAndOffset[0]
%if tidIdx == 0
%assign nTaskTicks = 1
%elseif SLibControllableRateTID(tidIdx)
%assign ctrlRateNumTicks = RTMGet("CtrlRateNumTicksToNextHit")
%assign ctrlRateIdx = SampleTime[tidIdx].CtrlRateInstanceIndex
%assign ctrlRateRatio = SampleTime[tidIdx].CtrlRateBaseRatioToFundmentalStepSize
%assign nTaskTicks = "(%<ctrlRateNumTicks>[%<ctrlRateIdx>]*%<ctrlRateRatio>-1)"
%else
%assign nTaskTicks = SLibComputeNumTaskTicks(period, stepSize)
%endif
%return nTaskTicks
%endfunction
%function FcnComputeTaskTickOffset(tidIdx) void
%assign stepSize = SLibGetFundamentalStepSize()
%assign period = SampleTime[tidIdx].PeriodAndOffset[0]
%assign offset = SampleTime[tidIdx].PeriodAndOffset[1]
%if SLibControllableRateTID(tidIdx) || offset == 0.0
%assign nOffsetTicks = 0
%else
%assign nOffsetTicks = (period - offset)/stepSize + 0.5
%assign nOffsetTicks = CAST("Number",FEVAL("floor", nOffsetTicks))
%endif
%return nOffsetTicks
%endfunction
%function FcnInitializeSampleTimeOffsets()
%assert !IsModelReferenceTarget()
%openfile retBuff
%assign commentAdded = TLC_FALSE
%foreach tidIdx = NumSynchronousSampleTimes
%if SLibControllableRateTID(tidIdx)
%assign ctrlRateNumTicks = RTMGet("CtrlRateNumTicksToNextHit")
%assign ctrlRateIdx = SampleTime[tidIdx].CtrlRateInstanceIndex
%assign nTaskTicks = "%<ctrlRateNumTicks>[%<ctrlRateIdx>]"
%<nTaskTicks> = 1;
%if SampleTime[tidIdx].NeedFloatTime == "yes"
%assert SLibIsERTCodeFormat()
%<LibGetTaskTime(tidIdx)> = 0;
%endif
%else
%assign offset = FcnComputeTaskTickOffset(tidIdx)
%if offset != 0
%if tidIdx == 0
%<LibReportFatalError("Base rate cannot have an offset")>
%else
%if !commentAdded
/* initialize sample time offsets */
%assign addedComment = TLC_TRUE
%endif
%if RTMTaskCountersIsReqFcn()
%assign cTick = RTMGet("TaskCounters")
%assign counter = "%<cTick>.%<SLibERTMultiRateCounterField(tidIdx)>"
%<counter> = %<offset>; %<LibTaskComment(tidIdx)>
%endif
%if SampleTime[tidIdx].NeedFloatTime == "yes"
%assert SLibIsERTCodeFormat()
%<LibGetTaskTime(tidIdx)> = %;
%endif
%endif
%endif
%endif
%endforeach
%if !LibIsDeploymentDiagram() && ...
!IsModelReferenceTarget() && ...
RTMCtrlRateMdlRefTimingIsReqFcn()
%assign ctrlRateTiming = RTMGet("CtrlRateMdlRefTiming")
%<ctrlRateTiming>.firstCtrlRateTID = %<SLibFirstControllableRateTID()>;
%assign numTicksToNextHit = RTMGet("CtrlRateNumTicksToNextHit")
%<ctrlRateTiming>.numTicksToNextHitForCtrlRate = %<numTicksToNextHit>;
%endif
%closefile retBuff
%return retBuff
%endfunction
%function () void
%assign dtIdx = SampleTime[0].TaskCounterDataTypeId
%assign dtype = LibGetDataTypeNameFromId(dtIdx)
%openfile tmpFcnBuf
struct {
%<dtype> TID[%<NumSynchronousSampleTimes>];
%if ::CompiledModel.SuppressMultiTaskScheduler && ...
!::CompiledModel.GenerateSampleERTMain
%<dtype> cLimit[%<NumSynchronousSampleTimes>];
%endif
} /
%closefile tmpFcnBuf
%return tmpFcnBuf
%endfunction
%function () void
%assign haveOffset = 0
%foreach idx = NumSynchronousSampleTimes
%if SampleTime[idx].PeriodAndOffset[1] != 0.0 && ...
!SLibControllableRateTID(idx)
%assign haveOffset = 1
%break
%endif
%endforeach
%openfile txt
/* Compute which subrates run during the next base time step. Subrates
* are an integer multiple of the base rate counter. Therefore, the subtask
* counter is reset when it reaches its limit (zero means run).
%if haveOffset
*
* Sample time offsets are handled by priming the counter with the
* appropriate non-zero value in the model's initialization function.
%endif
*/
%closefile txt
%return txt
%endfunction
%function UpdateRateTransitionFlagsWhenSuppressMultiTaskScheduler(tid)
%assign needUpdateRTFlags = SLibIsERTCodeFormat() && ...
(SuppressMultiTaskScheduler || (UseTargetTaskScheduler() && !SLibSingleTasking()))
%if !needUpdateRTFlags
%return ""
%endif
%openfile retBuf
%foreach idx = NumSynchronousSampleTimes - tid - 1
%assign j = idx + tid + 1
%if !IsModelReferenceTarget() && ...
SLibGetNeedRateInteraction(tid, j)
%assign cTick = RTMGet("TaskCounters")
%assign shMat = RTMGet("PerTaskSampleHits")
%assign limit = FcnComputeTaskTickLimit">FcnComputeTaskTickLimit(j)/FcnComputeTaskTickLimit">FcnComputeTaskTickLimit(tid)
%<SLibAddTIDtoAccessTIDList(...
System[NumSystems-1].Interface.RTMArgDef,::BlockFcn,"",tid)>
%assign period = ::CompiledModel.SampleTime[tid].PeriodAndOffset[0]
%assign offset = ::CompiledModel.SampleTime[tid].PeriodAndOffset[1]
%assign s_period = ::CompiledModel.SampleTime[j].PeriodAndOffset[0]
%assign s_offset = ::CompiledModel.SampleTime[j].PeriodAndOffset[1]
/* Update the flag to indicate when data transfers from
* Sample time: [%<period>s, %<offset>s] to Sample time: [%<s_period>s, %<s_offset>s] */
%if SLibModelHierarchyContainsNoninlinedSfcn() || GenerateGRTWrapper
%<RTMGet("PerTaskSampleHitsPtr")>[%] = ...
(%<shMat>.%<SLibERTMultiRateTimingField(j,tid)> == 0);
%endif
%if HasModelReferenceBlocks()
%<shMat>.b_%<SLibERTMultiRateTimingField(j,tid)> = ...
(%<shMat>.%<SLibERTMultiRateTimingField(j,tid)> == 0);
%endif
(%<shMat>.%<SLibERTMultiRateTimingField(j,tid)>)++;
if ((%<shMat>.%<SLibERTMultiRateTimingField(j,tid)>) > %) {
%<shMat>.%<SLibERTMultiRateTimingField(j,tid)> = 0;
}
%endif
%endforeach
%closefile retBuf
%return retBuf
%endfunction
%function UpdateRateTransitionFlagsHelper(ss, tid, skipMajorTimeCheck)
%openfile tmpBuf
%if SLibIsERTCodeFormat() && ...
(SuppressMultiTaskScheduler || (UseTargetTaskScheduler() && !SLibSingleTasking())) &&...
(IsModelReferenceBaseSys(ss) || ss.SystemIdx == NumSystems-1)
%if FixedStepOpts.TID01EQ
%if ISEQUAL(tid, 0)
%<UpdateRateTransitionFlagsWhenSuppressMultiTaskScheduler(0)>
%<UpdateRateTransitionFlagsWhenSuppressMultiTaskScheduler(1)>
%elseif ISEQUAL(tid, 1)
%else
%<UpdateRateTransitionFlagsWhenSuppressMultiTaskScheduler(tid)>
%endif
%else
%<UpdateRateTransitionFlagsWhenSuppressMultiTaskScheduler(tid)>
%endif
%endif
%closefile tmpBuf
%openfile retBuf
%if !WHITE_SPACE(tmpBuf)
%if !skipMajorTimeCheck && (tid == 0) && (NumContStates > 0)
if (%<RTMIs("MajorTimeStep")>) {
%<tmpBuf>
}
%else
%<tmpBuf>
%endif
%endif
%closefile retBuf
%return retBuf
%endfunction
%function FcnScheduleRateTransitions() Output
%if ::CompiledModel.RequireMultiRateSampleHits
/* To ensure a deterministic data transfer between two rates,
* data is transferred at the priority of a fast task and the frequency
* of the slow task. The following flags indicate when the data transfer
* happens. That is, a rate interaction flag is set true when both rates
* will run, and false otherwise.
*/
%endif
%assign cTick = RTMGet("TaskCounters")
%assign shMat = RTMGet("PerTaskSampleHits")
%foreach i = NumSynchronousSampleTimes
%openfile tmpFcnBuf
%assign str = ""
%assign comma = ""
%assign plural = -1
%foreach j = NumSynchronousSampleTimes
%if SLibGetNeedRateInteraction(i,j)
%<shMat>.%<SLibERTMultiRateTimingField(j,i)> = ...
(%<cTick>.%<SLibERTMultiRateCounterField(j)> == 0);
%assign str = str + "%<comma>%<j>"
%assign comma = ", "
%assign plural = plural + 1
%if SLibModelHierarchyContainsNoninlinedSfcn() || GenerateGRTWrapper
/* update PerTaskSampleHits matrix for non-inline sfcn */
%<RTMGet("PerTaskSampleHitsPtr")>[%] = ...
%<shMat>.%<SLibERTMultiRateTimingField(j,i)>;
%endif
%endif
%endforeach
%closefile tmpFcnBuf
%if !WHITE_SPACE(tmpFcnBuf)
/* tid %<i> shares data with slower tid rate%: %<str> */
%if i == 0
%<tmpFcnBuf>/
%else
if (%<cTick>.%<SLibERTMultiRateCounterField(i)> == 0) {
%<tmpFcnBuf>/
}
%endif
%endif
%endforeach
%endfunction
%function FcnScheduleSubRates() Output
%assign cTick = RTMGet("TaskCounters")
%<FcnResetCTicksComment()>/
%openfile buff
%assign needSampleHit = (SLibModelHierarchyContainsNoninlinedSfcn() || GenerateGRTWrapper) && SLibSingleTasking()
%foreach idx = NumSynchronousSampleTimes - 1
%assign i = idx + 1
%assign counter = "%<cTick>.%<SLibERTMultiRateCounterField(i)>"
%assign limit = FcnComputeTaskTickLimit(i)
%if TYPE(limit) == "Number"
%assign limit = limit - 1
%endif
%if TYPE(limit) != "Number" || limit > 0
(%<counter>)++;
if ((%<counter>) > %<limit>) { %<LibTaskComment(i)>
%<counter> = 0;
}
%if needSampleHit
%assert SLibSingleTasking()
%<RTMGet("SampleHitPtr")>[%<i>] = (%<counter> == 0);
%endif
%endif
%endforeach
%closefile buff
%<buff>
%return !WHITE_SPACE(buff)
%endfunction
%function SLibERTMultiRateTimingField(slowTID,fastTID) void
%if TYPE(%<slowTID>) != "Number" || TYPE(%<fastTID>) != "Number"
%assign errTxt = "tid values must be integers: %<TYPE(slowTID)>, " ...
"%<slowTID>, TYPE(fastTID)>, %<fastTID>"
%<LibReportFatalError(errTxt)>
%endif
%return "TID%<fastTID>_%<slowTID>"
%endfunction
%function SLibERTMultiRateCounterField(tid) void
%return "TID[%<tid>]"
%endfunction
%function SLibGenERTRateInteractionSubStruct() void
%assign dtIdx = SuppressMultiTaskScheduler || ...
(UseTargetTaskScheduler() && !SLibSingleTasking()) ? ...
SampleTime[0].TaskCounterDataTypeId : tSS_BOOLEAN
%assign dtype = LibGetDataTypeNameFromId(dtIdx)
%openfile tmpFcnBuf
%foreach i = NumSynchronousSampleTimes
%foreach j = NumSynchronousSampleTimes
%if SLibGetNeedRateInteraction(i,j)
%<dtype> %<SLibERTMultiRateTimingField(j,i)>;
%if (SuppressMultiTaskScheduler || ...
(UseTargetTaskScheduler() && !SLibSingleTasking())) && ...
HasModelReferenceBlocks()
%<LibGetDataTypeNameFromId(tSS_BOOLEAN)> b_%<SLibERTMultiRateTimingField(j,i)>;
%endif
%endif
%endforeach
%endforeach
%closefile tmpFcnBuf
%if !WHITE_SPACE(tmpFcnBuf)
%openfile retVal
struct {
%<tmpFcnBuf>/
} /
%closefile retVal
%else
%assign retVal = ""
%endif
%return retVal
%endfunction
%function FcnGenerateEventsForThisBaseRateFcn() Output
%assign prototype = ""
%openfile buff
%if !SLibSingleTasking() && !SuppressSetEventsForThisBaseRateFcn && !SLibIsExportFcnDiagram()
%assert(!IsModelReferenceTarget())
%if GenerateGRTWrapper
%assign fcnName = "rt_SimUpdateDiscreteEvents"
%if UsingMalloc
%assign tmpfcnName = "_%<fcnName>"
%assign fcnParams = ["void *pModel,", ...
"int_T rtmNumSampTimes, ", ...
"void *rtmTimingData, ", ...
"int_T *rtmSampleHitPtr, ", ...
"int_T *rtmPerTaskSampleHits"]
%else
%assign tmpfcnName = fcnName
%assign fcnParams = ["int_T rtmNumSampTimes,", ...
"void *rtmTimingData,",...
"int_T *rtmSampleHitPtr,",...
"int_T *rtmPerTaskSampleHits"]
%endif
%assign fcnReturns = "time_T"
%openfile prototype
%<fcnReturns> %<tmpfcnName>(
%foreach idx = SIZE(fcnParams, 1)
%/
%endforeach
)
%closefile prototype
%assign fcnReturns = "%<SLibGetGRTWrapperLinkage()> %<fcnReturns>"
%createrecord fcnRec {Name tmpfcnName; Returns fcnReturns; Params fcnParams; Abstract ""; ...
Category "model"; GeneratedBy "ertmdlreftiming.tlc"; Type "Update"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<SLibGetFcnMemSecPragma(tmpfcnName, "MemSecFuncExecute", "Pre")>/
%<SLibGetGRTWrapperLinkage()> %<prototype>
{
%if UsingMalloc
%<::tSimStructType>* %<::tSimStruct> = (%<tSimStructType>*) pModel;
%endif
%foreach idx = NumSynchronousSampleTimes -1
rtmSampleHitPtr[%] = %<RTMTaskRunsThisBaseStep(idx+1)>;
%if SuppressMultiTaskScheduler
%<RTMUpdateTaskCounter(idx+1)>
%endif
%endforeach
%<SLibUnusedParameter("rtmNumSampTimes")>
%<SLibUnusedParameter("rtmTimingData")>
%<SLibUnusedParameter("rtmPerTaskSampleHits")>
return(-1);
}
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Post")>/
%elseif !InlineSetEventsForThisBaseRateFcn
%assign fcnName = "%<Name>_SetEventsForThisBaseStep"
%openfile fcnAbstract
Set which subrates need to run this base step (base rate always runs).
%if (TargetOS == "BareBoardExample") || (TargetOS == "NativeThreadsExample")
This function must be called prior to calling the model step function
in order to "remember" which rates need to run this base step. The
buffering of events allows for overlapping preemption.
%endif
%closefile fcnAbstract
%assign fcnReturns = "void"
%if MultiInstanceERTCode
%assign fcnParams = "boolean_T *eventFlags, %<::tSimStructType> *const %<::tSimStruct>"
%else
%assign fcnParams = "boolean_T *eventFlags"
%endif
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "model"; GeneratedBy "ertmdlreftiming.tlc"; Type "SetEvent"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Pre")>/
%assign prototype = "%<fcnReturns> %<fcnName>(%<fcnParams>)"
%<prototype>
{
/* Task runs when its counter is zero, computed via rtmStepTask macro */
%assign firstSubrateTID = 1 + FixedStepOpts.TID01EQ
%foreach idx = NumSynchronousSampleTimes - firstSubrateTID
%assign flags_idx = idx + firstSubrateTID
eventFlags[%<flags_idx>] = ((boolean_T)%<RTMTaskRunsThisBaseStep(flags_idx)>);
%if SuppressMultiTaskScheduler
%<RTMUpdateTaskCounter(flags_idx)>
%endif
%endforeach
}
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Post")>/
%endif
%endif
%closefile buff
%if !WHITE_SPACE(prototype)
%openfile prototypeBuf
/* External function called from main */
%if ::GenCPP
#ifdef __cplusplus
extern "C" {
#endif
%endif
%if UsingMalloc && GenerateGRTWrapper
/* Backward compatibility macro */
#ifdef rt_SimUpdateDiscreteEvents
#undef rt_SimUpdateDiscreteEvents
#endif
#ifdef _RTW_COMBINE_MULTIPLE_MODELS
#define rt_SimUpdateDiscreteEvents(x1,x2,x3,x4) rtmiDiscreteEvents(rtmcGetRTWRTModelMethodsInfo(rtmC),(x1),(x2),(x3),(x4))
#else
#define rt_SimUpdateDiscreteEvents(x1,x2,x3,x4) rtmiDiscreteEvents(rtmGetRTWRTModelMethodsInfo(S),(x1),(x2),(x3),(x4))
#endif
%else
%<LibExternInFcnDecls()>%<prototype>;
%endif
%if ::GenCPP
#ifdef __cplusplus
}
#endif
%endif
%closefile prototypeBuf
%<SLibCacheCodeToFile("mdl_extern_fcn_decl", prototypeBuf)>
%endif
%return buff
%endfunction
%function FcnGetMulirateSchedulerName()
%if SLibSingleTasking() || SLibConcurrentTasks()
%return "rate_scheduler"
%else
%return "rate_monotonic_scheduler"
%endif
%endfunction
%function FcnGenSchedulerFcnAbstract()
%openfile abstractBuf
%if SLibSingleTasking()
This function updates active task flag for each subrate.
The function is called at model base rate, hence the
generated code self-manages all its subrates.
%elseif SLibConcurrentTasks()
This function updates active task flag for each subrate.
The function is called in the model base rate function.
It maintains SampleHit information to allow scheduling
of the subrates from the base rate function.
%else
This function updates active task flag for each subrate
and rate transition flags for tasks that exchange data.
The function assumes rate-monotonic multitasking scheduler.
The function must be called at model base rate so that
the generated code self-manages all its subrates and rate
transition flags.
%endif
%closefile abstractBuf
%return abstractBuf
%endfunction
%function FcnGenerateMultirateScheduler() Output
%assign buff = ""
%assign prototypeBuf = ""
%assign fcnName = ""
%if !RootSystemIsSingleRate || SLibModelHasControllableRate()
%openfile buff
%assign nr = NumRuntimeExportedRates
%assign fcnName = FcnGetMulirateSchedulerName()
%assign curBlockFcn = ::BlockFcn
%assign ::BlockFcn = "Rate_Scheduler"
%assign typePrefix = SLibGetModelTypesNamespacePrefix()
%if SLibSingleTasking()
%openfile schedulerCode
%assign ::NeedScheduler = %<FcnScheduleSubRates()>
%closefile schedulerCode
%if ::NeedScheduler
%assign fcnAbstract = FcnGenSchedulerFcnAbstract()
%if IsMultiInstanceERTOrModelReference()
%assign fcnArgs = "%<typePrefix>%<::tSimStructType> *const %<::tSimStruct>"
%<SLibAddTIDtoAccessTIDList(...
System[NumSystems-1].Interface.RTMArgDef,"Update", "",0)>
%else
%assign fcnArgs = "void"
%endif
%if SLibAutosarCompilerAbstractionRequired()
%assign fcnReturns = "static " + SLibAutosarCompilerAbstractionForFcnDeclRtnType("void", "FuncInternal", "")
%else
%assign fcnReturns = "static void"
%endif
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnArgs; Abstract fcnAbstract; ...
Category "model"; GeneratedBy "ertmdlreftiming.tlc"; Type "Schedule"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Pre")>/
%if SLibAutosarCompilerAbstractionRequired()
%assign prototypeBuf = "static " + SLibAutosarCompilerAbstractionForFcnDeclRtnType("void", "FuncInternal", "") + " %<fcnName>(%<fcnArgs>);"
%else
%assign prototypeBuf = "static void %<fcnName>(%<fcnArgs>);"
%endif
%<fcnReturns> %<fcnName>(%<fcnArgs>)
{
%<schedulerCode>
}
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Post")>/
%endif
%else
%assign fcnAbstract = FcnGenSchedulerFcnAbstract()
%if IsMultiInstanceERTOrModelReference()
%assign fcnArgs = "%<typePrefix>%<::tSimStructType> *const %<::tSimStruct>"
%<SLibAddTIDtoAccessTIDList(...
System[NumSystems-1].Interface.RTMArgDef,"Output", "",0)>
%else
%assign fcnArgs = "void"
%endif
%if !SLibConcurrentTasks()
%assign fcnReturns = "static void"
%else
%assign fcnReturns = "void"
%endif
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnArgs; Abstract fcnAbstract; ...
Category "model"; GeneratedBy "ertmdlreftiming.tlc"; Type "Schedule"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Pre")>/
%assign prototypeBuf = "%<fcnReturns> %<fcnName>(%<fcnArgs>);"
%<fcnReturns> %<fcnName>(%<fcnArgs>)
{
%if !SuppressMultiTaskScheduler
%<FcnScheduleRateTransitions()>/
%endif
%assign needScheduler = %<FcnScheduleSubRates()>
}
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncExecute", "Post")>/
%endif
%closefile buff
%endif
%if !SLibConcurrentTasks()
%<SLibCacheCodeToFile("baseMdl_fcn_prototype", prototypeBuf)>
%elseif !SLibSingleTasking()
%assign externPrototypeBuf = "%<LibExternInFcnDecls()> %<prototypeBuf>"
%if SLibIsModelTypesModelClassNamespace()
%<SLibCacheCPPEncapModelData("ExternData", externPrototypeBuf)>
%else
%<SLibCacheCodeToFile("mdl_extern_fcn_decl", externPrototypeBuf)>
%endif
%endif
%assign ::BlockFcn = curBlockFcn
%return buff
%endfunction
%function UseTargetTaskScheduler() void
%return SLibGenerateNativeThreads()
%endfunction
%function FcnCallSingleTaskingRateScheduler(tid)
%assert (SLibSingleTasking())
%openfile buff
%if !RootSystemIsSingleRate && ::NeedScheduler
%if IsMultiInstanceERTOrModelReference()
%<FcnGetMulirateSchedulerName()>(%<GetSimStructExpr(System[GetBaseSystemIdx()], ::tSimStruct)>);
%else
%<FcnGetMulirateSchedulerName()>();
%endif
%endif
%closefile buff
%return buff
%endfunction
%function FcnCallMultiTaskingRateScheduler(tid)
%assert (!SLibSingleTasking())
%openfile buff
%if !RootSystemIsSingleRate && !SuppressMultiTaskScheduler && ...
!UseTargetTaskScheduler()
%if(ISEQUAL(tid, "") || ISEQUAL(tid, 0))
%<FcnGenerateTidGuardOpenCode(0)>
%if IsMultiInstanceERTOrModelReference()
%<FcnGetMulirateSchedulerName()>(%<GetSimStructExpr(System[GetBaseSystemIdx()], ::tSimStruct)>);
%else
%<FcnGetMulirateSchedulerName()>();
%endif
%<FcnGenerateTidGuardCloseCode(0)>
%endif
%endif
%closefile buff
%return buff
%endfunction
%function FcnDumpMultiRateScheduler() void
%if !RootSystemIsSingleRate
%openfile multirateBuffer
%<FcnGenerateEventsForThisBaseRateFcn()>
%if (!SuppressMultiTaskScheduler || SLibConcurrentTasks()) ...
&& !LibIsDeploymentDiagram() && !SLibIsExportFcnDiagram() ...
&& (SLibSingleTasking() || !UseTargetTaskScheduler())
%<FcnGenerateMultirateScheduler()>
%endif
%closefile multirateBuffer
%<SLibCacheCodeToFile("baseMdl_fcn_defn", multirateBuffer)>
%endif
%endfunction
%function ErtOrModelrefGetTimingForTopOfOutputFcn(ss, tid)
%assert (SLibIsERTCodeFormat() && ss.SystemIdx == NumSystems-1) && ...
!IsModelReferenceTarget()
%assign needMajorTimeGuard = ...
(ISEQUAL(tid,0) || ISEQUAL(tid, "")) && NumContStates > 0
%assign retBuf = ""
%openfile buf
%if (ISEQUAL(tid,0) || ISEQUAL(tid, "")) && ...
((NumContStates > 0) || (UsingMalloc && GenerateGRTWrapper))
%<ERTSetSolverStopTime()>
%endif
%if (!SLibSingleTasking())
%<FcnCallMultiTaskingRateScheduler(tid)>
%endif
%<UpdateRateTransitionFlagsHelper(ss, tid, needMajorTimeGuard)>
%closefile buf
%openfile retBuf
%if !WHITE_SPACE(buf)
%if needMajorTimeGuard
if (%<RTMIs("MajorTimeStep")>) {
%endif
%<buf>
%if needMajorTimeGuard
} /* end MajorTimeStep */
%endif
%endif
%if needMajorTimeGuard
/* Update absolute time of base rate at minor time step */
if (%<RTMIs("MinorTimeStep")>) {
%<LibGetTaskTime(0)> = rtsiGetT(%<RTMGetSolverInfo()>);
}
%<FcnUpdateAsyncTimeAtMinorMajorTimeStep()>
%endif
%closefile retBuf
%return retBuf
%endfunction
%function ErtOrModelrefGetTimingForBottomOfUpdateFcn(ss, tid, skipMajorTimeCheck)
%assert (SLibIsERTCodeFormat() && ...
(IsModelReferenceBaseSys(ss) || ss.SystemIdx == NumSystems-1))
%openfile buff
%assign continuousUpdate = ...
(ISEQUAL(tid,0) || ISEQUAL(tid, "")) && (NumContStates > 0)
%assign needMajorTimeGuard = !skipMajorTimeCheck && continuousUpdate
%if needMajorTimeGuard
if (%<RTMIs("MajorTimeStep")>) {
%endif
%if ISEQUAL(tid, 0) || ISEQUAL(tid, "")
%assert (!IsModelReferenceTarget() || ...
WHITE_SPACE(CachedCodeBuffsForRootSys.StopSimBuffer))
%<CachedCodeBuffsForRootSys.StopSimBuffer>/
%endif
%if !IsModelReferenceTarget()
%if continuousUpdate
%assign reuseArgs = SLibModelFcnArgs("ODEUpdateContinuousStates",2,0)
%if !ISEQUAL(reuseArgs,"")
%assign reuseArgs = ", " + reuseArgs
%endif
%if !SLibIsPeriodicRateGrouping() && !SLibSingleTasking()
if (%<LibIsSampleHit(1)>) {
rt_ertODEUpdateContinuousStates(%<RTMGetSolverInfo()>%<reuseArgs>);
}
%elseif !needMajorTimeGuard
if (%<RTMIs("MajorTimeStep")>) {
rt_ertODEUpdateContinuousStates(%<RTMGetSolverInfo()>%<reuseArgs>);
}
%else
rt_ertODEUpdateContinuousStates(%<RTMGetSolverInfo()>%<reuseArgs>);
%endif
%endif
%endif
%assert !LibAsynchronousTriggeredTID(tid)
%assign tmpBuf = SLibIsMultiRateAndPeriodicRateGrouping( System[NumSystems-1] ) ? ...
CachedCodeBuffsForRootSys.UpdateAbsoluteTimeBuffer%<tid> : ...
CachedCodeBuffsForRootSys.UpdateAbsoluteTimeBuffer
%<tmpBuf>
%if SLibSingleTasking() && !SLibIsExportFcnDiagram()
%<FcnCallSingleTaskingRateScheduler(tid)>
%endif
%if needMajorTimeGuard
} /* end MajorTimeStep */
%endif
%closefile buff
%return buff
%endfunction
%function ERTSetSolverStopTime()
%openfile retBuf
%assign needGuard = TLC_FALSE
/* set solver stop time */
%assign ct = RTMDispatchToAccessFcn("ClockTick0", "get", ...
"", "", GetSimStructExpr(System[GetBaseSystemIdx()], ::tSimStruct))
%assign ss = RTMDispatchToAccessFcn("StepSize0", "get", ...
"", "", GetSimStructExpr(System[GetBaseSystemIdx()], ::tSimStruct))
%if SLibClockTickIsUnit32Pair(0)
%assign cth = RTMDispatchToAccessFcn("ClockTickH0", "get", ...
"", "", GetSimStructExpr(System[GetBaseSystemIdx()], ::tSimStruct))
if (!(%<ct>+1)) {
rtsiSetSolverStopTime(%<RTMGetSolverInfo()>, ...
((%<cth> + 1) * %<ss> * 4294967296.0));
} else {
rtsiSetSolverStopTime(%<RTMGetSolverInfo()>, ...
((%<ct> + 1) * %<ss> + %<cth> * %<ss> * 4294967296.0));
}
%else
rtsiSetSolverStopTime(%<RTMGetSolverInfo()>,((%<ct>+1)*%<ss>));
%endif
%closefile retBuf
%return retBuf
%endfunction
%function FcnGenChangeStepSizesFcn()
%openfile retBuf
%assign fcnAbstract = "Change all stepsize using the newBaseRateStepSize"
%with ::CompiledModel
%assign rootSystem = System[NumSystems-1]
%assign reqInsts = LibGetSystemField(rootSystem, "ReqRootPrmHdrDataInsts")
%assign fcnName = "%<Name>_ChangeStepSize"
%assign fcnReturns = "void"
%if reqInsts.SimStructInst
%assign fcnParams = "real_T newBaseRateStepSize, %<::tSimStructType> *const %<::tSimStruct>"
%else
%assign fcnParams = "real_T newBaseRateStepSize"
%endif
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "model"; GeneratedBy "ertmdlreftiming.tlc"; Type "Utility"; ...
GeneratedFor FcnGeneratedFor(rootSystem)}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncInitTerm", "Pre")>/
%<fcnReturns> %<fcnName>(%<fcnParams>) {
real_T ratio = newBaseRateStepSize / %;
%assert SampleTime[0].ClockTickStepSize > 0
/* update non-zore stepsize of periodic
* sample time. Stepsize of asynchronous
* sample time is not changed in this function */
%foreach tid = NumSynchronousSampleTimes
%if SampleTime[tid].NeedFloatTime == "yes" && ...
!PurelyIntegerCode
%<RTMGet">RTMGet("StepSize%<tid>")> = %<RTMGet">RTMGet("StepSize%<tid>")> * ratio;
%endif
%endforeach
%if NumChildSFunctions || GenerateGRTWrapper
%<RTMGet">RTMGet("StepSize")> = %<RTMGet">RTMGet("StepSize")> * ratio;
%endif
}
%<SLibGetFcnMemSecPragma(fcnName, "MemSecFuncInitTerm", "Post")>/
%endwith
%closefile retBuf
%return retBuf
%endfunction
%function FcnCallChangeStepSizesFcn(newBaseRateStepSize)
%openfile retBuf
/* Change all stepsize using the newBaseRateStepSize */
%assert SampleTime[0].ClockTickStepSize > 0
%assign rootSystem = System[NumSystems-1]
%assign reqInsts = LibGetSystemField(rootSystem, "ReqRootPrmHdrDataInsts")
%if reqInsts.SimStructInst
%<Name>_ChangeStepSize(%<newBaseRateStepSize>, %<::tSimStruct>);
%else
%<Name>_ChangeStepSize(%<newBaseRateStepSize>);
%endif
%closefile retBuf
%return retBuf
%endfunction
%endif