%selectfile NULL_FILE
%if EXISTS("_ERT_MODELREF_ABS_TIME_") == 0
%assign _ERT_MODELREF_ABS_TIME_ = 1
%function (tid)
%assign tsRec = SampleTime[tid]
%openfile retBuf
%if tsRec.NeedFloatTime == "yes"
/* The "clockTick%<tid>" counts the number of times the code of this task has
* been executed. The absolute time is the multiplication of "clockTick%<tid>"
* and "Timing.stepSize%<tid>". Size of "clockTick%<tid>" ensures timer will not
* overflow during the application lifespan selected.
%if SLibClockTickIsUnit32Pair(tid)
* Timer of this task consists of two 32 bit unsigned integers.
* The two integers represent the low bits Timing.clockTick%<tid> and the high bits
* Timing.clockTickH%<tid>. When the low bit overflows to 0, the high bits increment.
%endif
*/
%else
/* The "clockTick%<tid>" counts the number of times the code of this task has
* been executed. The resolution of this integer timer is %<tsRec.ClockTickStepSize>, which is the step size
* of the task. Size of "clockTick%<tid>" ensures timer will not overflow during the
* application lifespan selected.
%if SLibClockTickIsUnit32Pair(tid)
* Timer of this task consists of two 32 bit unsigned integers.
* The two integers represent the low bits Timing.clockTick%<tid> and the high bits
* Timing.clockTickH%<tid>. When the low bit overflows to 0, the high bits increment.
%endif
*/
%endif
%closefile retBuf
%return retBuf
%endfunction
%function RTMUpdateAbsoluteTimeForTID(tid) void
%openfile tmpBuf
%<SLibGenAbsTimeComment(tid)>
%if SampleTime[tid].NeedFloatTime == "yes"
%<RTMUpdateRealAbsoluteTimeForTID(tid)>
%else
%<RTMUpdateIntegerAbsoluteTimeForTID(tid)>
%endif
%closefile tmpBuf
%return tmpBuf
%endfunction
%function FcnUpdateAbsoluteTimeNonRateGrouping(ssIdx) void
%assign absTimeDumped = TLC_FALSE
%openfile tmpBuf
%if SLibNeedAbsoluteTimeForTID(0)
%if !LibIsContinuous(0) || !IsModelReferenceForASimstructBasedTarget()
/* Update absolute time for base rate */
%if !SLibSingleTasking()
%assign guard = LibIsSampleHit(0)
%if guard != "1"
if (%<guard>) {
%endif
%endif
%<RTMUpdateAbsoluteTimeForTID(0)>
%if !SLibSingleTasking() && guard != "1"
}
%endif
%assign absTimeDumped = TLC_TRUE
%endif
%endif
%foreach tidIdx = NumRuntimeExportedRates -1
%assign subRateIdx = tidIdx + 1
%if SLibNeedAbsoluteTimeForTID(subRateIdx)
%if !SLibSingleTasking()
%assign tidGuard = LibIsSampleHit(subRateIdx)
%else
%if SLibControllableRateTID(subRateIdx)
%assign baseTID = ::CompiledModel.SampleTime[subRateIdx].CtrlRateBaseTID
%assign tidGuard = ((baseTID == 1 && FixedStepOpts.TID01EQ) || baseTID == 0) ? ...
"1" : LibIsSpecialSampleHit(baseTID, 0)
%else
%assign tidGuard = (subRateIdx == 1 && FixedStepOpts.TID01EQ) ? ...
"1" : LibIsSpecialSampleHit(subRateIdx, 0)
%endif
%endif
%if tidGuard == "1"
{
%else
if (%<tidGuard>) {
%endif
%assign period = ::CompiledModel.SampleTime[subRateIdx].PeriodAndOffset[0]
%assign offset = ::CompiledModel.SampleTime[subRateIdx].PeriodAndOffset[1]
/* Update absolute timer for sample time: [%<period>s, %<offset>s] */
%<RTMUpdateAbsoluteTimeForTID(subRateIdx)>
}
%assign absTimeDumped = TLC_TRUE
%endif
%endforeach
%closefile tmpBuf
%if absTimeDumped
%assign arg = ::CompiledModel.System[ssIdx].Interface.RTMArgDef
%<SLibAccessArgHelper(arg,"","")>
%endif
%return tmpBuf
%endfunction
%function FcnUpdateAbsoluteTimeRateGrouping(ssIdx, subRateIdx) void
%assign tmpBuf = ""
%if SLibNeedAbsoluteTimeForTID(subRateIdx)
%openfile tmpBuf
%assert(SampleTime[subRateIdx].NeedAbsoluteTime == "yes")
%if !LibIsContinuous(subRateIdx) || ...
!IsModelReferenceForASimstructBasedTarget()
/* Update absolute time */
%<RTMUpdateAbsoluteTimeForTID(subRateIdx)>
%endif
%closefile tmpBuf
%assign arg = ::CompiledModel.System[ssIdx].Interface.RTMArgDef
%<SLibAddTIDtoAccessTIDList(arg, ::BlockFcn, "",subRateIdx)>
%endif
%return tmpBuf
%endfunction
%function FcnUpdateAsyncTimeAtMinorMajorTimeStep()
%assert(!IsModelReferenceTarget())
%openfile tmpBuf
%foreach idx = LibGetNumAsyncTasks()
%assign tid = idx + NumRuntimeExportedRates
%if !RTMAbsTimeNeedTransProtection(tid)
%continue
%endif
%assert !SLibConcurrentTasks()
%if RTMContTDbBufIsReqFcn(%<tid>)
/* Base rate updates double buffers of absolute time at
minor and major time step for asynchronous task %<tid>.
Double buffers are used to ensure data integrity when
asynchronous task reads absolute time.
*/
switch(%<SLibGetDbBufReadBuf(tid)>) {
case 0: %<SLibGetDbBufWriteBuf(tid)> =1; break;
case 1: %<SLibGetDbBufWriteBuf(tid)> =0; break;
default: %<SLibGetDbBufWriteBuf(tid)> = ...
!%<SLibGetDbBufLastBufWr(tid)>; break;
}
%<SLibGetDbBufContTForTID(tid)>[%<SLibGetDbBufWriteBuf(tid)>] = ...
%<LibGetT()>;
%<SLibGetDbBufLastBufWr(tid)> = %<SLibGetDbBufWriteBuf(tid)>;
%<SLibGetDbBufWriteBuf(tid)> = 0xFF;
%elseif RTMContTH2LIsReqFcn(tid)
/* Base rate updates double-buffer of absolute time
at minor and major time step for asynchronous task %<tid>.
Double buffers are used to ensure data integrity
when asynchronous task reads absolute time.
-- rtmH2LBufBeingRead is the index of the buffer being read
by the asynchronous task %<tid>
-- rtmH2LLastBufWr is the index of the buffer that is
written last.
*/
if (%<SLibGetH2LBufBeingRead(tid)> != 0) {
%<SLibGetH2LDbBufContTForTID(tid)>[0] = %<LibGetT()>;
%<SLibGetH2LLastBufWr(tid)> = 0;
} else {
%<SLibGetH2LDbBufContTForTID(tid)>[1] = %<LibGetT()>;
%<SLibGetH2LLastBufWr(tid)> = 1;
}
%endif
%endforeach
%if RTMContTL2HIsReqFcn()
{
/* Base rate updates double buffers of absolute time at
minor and major time step for asynchronous task %<tid>.
Double buffers are used to ensure data integrity when
asynchronous task reads absolute time.
-- rtmL2HLastBufWr is the index of the buffer that is
written last.
*/
boolean_T bufIdx = !%<SLibGetL2HLastBufWr()>;
%<SLibGetL2HDbBufContT()>[bufIdx] = %<LibGetT()>;
%<SLibGetL2HLastBufWr()> = bufIdx;
}
%endif
%closefile tmpBuf
%return tmpBuf
%endfunction
%function FcnUpdateAsyncTaskTimers() void
%assert(!IsModelReferenceTarget())
%openfile tmpBuf
%foreach tid = NumSampleTimes
%if !RTMAbsTimeNeedTransProtection(tid)
%continue
%endif
%if SLibConcurrentTasks()
%<SLibCGIRMutexOp(1,SLibGetTimerSemID(tid))>
%<LibGetClockTickBufForTID">SLibGetClockTickBufForTID(tid)> = %<LibGetClockTick(0)>;
%if SLibClockTickIsUnit32Pair(tid)
%<SLibGetClockTickHBufForTID(tid)> = %<LibGetClockTickHigh(0)>;
%endif
%<SLibCGIRMutexOp(2,SLibGetTimerSemID(tid))>
%continue
%endif
%if RTMClockTick0DbBufIsReqFcn(tid)
switch(%<SLibGetDbBufReadBuf(tid)>) {
case 0: %<SLibGetDbBufWriteBuf(tid)> =1; break;
case 1: %<SLibGetDbBufWriteBuf(tid)> =0; break;
default: %<SLibGetDbBufWriteBuf(tid)> = ...
!%<SLibGetDbBufLastBufWr(tid)>; break;
}
%<SLibGetDbBufClockTickForTID(tid)>[%<SLibGetDbBufWriteBuf(tid)>] = ...
%<LibGetClockTick(0)>;
%if SLibClockTickIsUnit32Pair(tid)
%<SLibGetDbBufClockTickHForTID(tid)>[%<SLibGetDbBufWriteBuf(tid)>] = ...
%<LibGetClockTickHigh(0)>;
%endif
%<SLibGetDbBufLastBufWr(tid)> = %<SLibGetDbBufWriteBuf(tid)>;
%<SLibGetDbBufWriteBuf(tid)> = 0xFF;
%elseif RTMClockTick0H2LIsReqFcn(tid)
/* Base rate updates double buffers of absolute time for
asynchronous task %<tid>. Double buffers are used to
ensure data integrity when asynchronous task reads
absolute time.
-- rtmH2LBufBeingRead is the index of the buffer being
read by the asynchronous task %<tid>
-- rtmH2LLastBufWr is the index of the buffer that is
written last.
*/
if (%<SLibGetH2LBufBeingRead(tid)> != 0) {
%<SLibGetH2LDbBufClockTickForTID(tid)>[0] = %<LibGetClockTick(0)>;
%if LongClockTickForTIDIsReqFcn(0)
%<SLibGetH2LDbBufClockTickHForTID(tid)>[0] = %<LibGetClockTickHigh(0)>;
%endif
%<SLibGetH2LLastBufWr(tid)> = 0;
} else {
%<SLibGetH2LDbBufClockTickForTID(tid)>[1] = %<LibGetClockTick(0)>;
%if LongClockTickForTIDIsReqFcn(0)
%<SLibGetH2LDbBufClockTickHForTID(tid)>[1] = %<LibGetClockTickHigh(0)>;
%endif
%<SLibGetH2LLastBufWr(tid)> = 1;
}
%endif
%endforeach
%if RTMClockTick0L2HIsReqFcn()
{
/* Base rate updates double buffers of absolute time for
asynchronous task. Double buffers are used to ensure
data integrity when asynchronous task reads absolute
time.
-- rtmL2HLastBufWr is the buffer index that is written last.
*/
boolean_T bufIdx = !%<SLibGetL2HLastBufWr()>;
%<SLibGetL2HDbBufClockTick()>[bufIdx] = %<LibGetClockTick(0)>;
%if LongClockTickForTIDIsReqFcn(0)
%<SLibGetL2HDbBufClockTickH()>[bufIdx] = %<LibGetClockTickHigh(0)>;
%endif
%<SLibGetL2HLastBufWr()> = bufIdx;
}
%endif
%closefile tmpBuf
%return tmpBuf
%endfunction
%function SLibErtGenUpdateAbsoluteTimeCode(ssIdx, buffsRec, isPeriodicRateGrouping) void
%assign ::initBlockFcn = ::BlockFcn
%assign ::BlockFcn = "Update"
%if isPeriodicRateGrouping
%foreach subRateIdx = NumRuntimeExportedRates
%openfile tmpBuf
%assign System[ssIdx].CurrentTID = subRateIdx
%<FcnUpdateAbsoluteTimeRateGrouping(ssIdx, subRateIdx)>
%if subRateIdx == 0 && !IsModelReferenceTarget()
%<FcnUpdateAsyncTaskTimers()>
%endif
%closefile tmpBuf
%addtorecord buffsRec UpdateAbsoluteTimeBuffer%<subRateIdx> tmpBuf
%endforeach
%assign System[ssIdx].CurrentTID = -1
%if FixedStepOpts.TID01EQ
%assign tmpBuf0 = buffsRec.UpdateAbsoluteTimeBuffer0
%assign tmpBuf1 = buffsRec.UpdateAbsoluteTimeBuffer1
%assign buffsRec.UpdateAbsoluteTimeBuffer0 = tmpBuf0 + tmpBuf1
%assign buffsRec.UpdateAbsoluteTimeBuffer1 = ""
%endif
%else
%openfile updateTimeBuffer
%<FcnUpdateAbsoluteTimeNonRateGrouping(ssIdx)>
%if !IsModelReferenceTarget()
%<FcnUpdateAsyncTaskTimers()>
%endif
%closefile updateTimeBuffer
%addtorecord buffsRec UpdateAbsoluteTimeBuffer updateTimeBuffer
%endif
%assign ::BlockFcn = initBlockFcn
%endfunction
%endif