%if EXISTS("_ASYNCLIB_") == 0
%assign _ASYNCLIB_ = 1
%selectfile NULL_FILE
%function LibGetBlockAttribute(block,attr) void
%if ISFIELD(block,attr)
%return block.%<attr>
%else
%return ""
%endif
%endfunction
%function LibGetFcnCallBlock(sfcnblock, recIdx) void
%with sfcnblock
%if LibIsEqual(SFcnSystemOutputCall[recIdx].BlockToCall, "unconnected")
%return ""
%elseif ISFIELD(sfcnblock,"SFcnSystemOutputCall") && (SIZE(SFcnSystemOutputCall,1) > recIdx)
%assign ssSysIdx = SFcnSystemOutputCall[recIdx].BlockToCall[0]
%assign ssBlkIdx = SFcnSystemOutputCall[recIdx].BlockToCall[1]
%return ::CompiledModel.System[ssSysIdx].Block[ssBlkIdx]
%else
%assign ::ShowErrorStackTrace = TLC_TRUE
%<SLibReportErrorWithIdAndArgs("RTW:tlc:InvalidArg", "LibGetFcnCallBLock")>
%endif
%endwith
%endfunction
%function FcnGetAsyncTidFromSfcnBlk(blk, el)
%foreach idx = LibGetNumAsyncTasks()
%assign tid = idx + NumRuntimeExportedRates
%if ISFIELD(SampleTime[tid], "AsyncSfcnBlkIdx")
%assign asyncSfcnBlkIdx = SampleTime[tid].AsyncSfcnBlkIdx
%assign thisBlkIdx = blk.BlockIdx
%if SampleTime[tid].AsyncSfcnBlkElm == el && ...
asyncSfcnBlkIdx[0] == thisBlkIdx[0] && ...
asyncSfcnBlkIdx[1] == thisBlkIdx[2]
%break
%endif
%endif
%endforeach
%assert tid < NumSampleTimes
%return tid
%endfunction
%function SLibDumpOutputUpdateCodeForAsyncTid(tidVal)
%return SLibDumpOutputUpdateCodeForAsyncTidInSS(GetBaseSystemIdx(),tidVal)
%endfunction
%function SLibDumpOutputUpdateCodeForAsyncTidInSS(ssIdx, tidVal)
%assign baseSystem = ::CompiledModel.System[ssIdx]
%openfile retBuf
%assign prevRSCurrTid = baseSystem.CurrentTID
%assign baseSystem.CurrentTID = tidVal
%if SLibPartitionGroupingSystem(baseSystem)
%assign prevRSCurrPid = baseSystem.CurrentPID
%assign pidVec = SLibGetPidFromTid(tidVal)
%assign baseSystem.CurrentPID = pidVec[0]
%endif
%openfile outputFcnLocalVars
%if MultiInstanceERTCode && !GenerateClassInterface
%<SLibDumpLocalVariablesForBlockFcn(baseSystem, "OutputUpdate")>
%endif
%<LibGetSystemLocalVars(baseSystem, "Output", tidVal)>
%<LibGetSystemLocalVars(baseSystem, "OutputUpdate", tidVal)>
%<SLibGetFcnLocalVars(baseSystem, "Output", tidVal)>
%closefile outputFcnLocalVars
%assign updateFcnLocalVars = SLibGetFcnLocalVars(baseSystem, "Update", tidVal)
%assign needSeperateScope = !WHITE_SPACE(outputFcnLocalVars) && !WHITE_SPACE(updateFcnLocalVars)
%<SLibDumpLocalTidInSystem(baseSystem, "OutputUpdate")>
%if needSeperateScope
{
%<outputFcnLocalVars>
%<LibDumpSystemUserCode(baseSystem,"Output","Header")>/
%<LibDumpSystemUserCode(baseSystem,"Output","Body")>/
%if SLibPartitionGroupingSystem(baseSystem)
%<LibDumpSystemFcn(baseSystem,"Output%<tidVal>%<baseSystem.CurrentPID>")>/
%else
%<LibDumpSystemFcn(baseSystem,"Output%<tidVal>")>/
%endif
%<LibDumpSystemUserCode(baseSystem,"Output","Trailer")>/
}
{
%<updateFcnLocalVars>
%<LibDumpSystemUserCode(baseSystem,"Update","Header")>/
%<LibDumpSystemUserCode(baseSystem,"Update","Body")>/
%if SLibPartitionGroupingSystem(baseSystem)
%<LibDumpSystemFcn(baseSystem,"Update%<tidVal>%<baseSystem.CurrentPID>")>/
%else
%<LibDumpSystemFcn(baseSystem,"Update%<tidVal>")>/
%endif
%<LibDumpSystemUserCode(baseSystem,"Update","Trailer")>/
}
%else
%<outputFcnLocalVars>
%<updateFcnLocalVars>
%<LibDumpSystemUserCode(baseSystem,"Output","Header")>/
%<LibDumpSystemUserCode(baseSystem,"Output","Body")>/
%if SLibPartitionGroupingSystem(baseSystem)
%<LibDumpSystemFcn(baseSystem,"Output%<tidVal>%<baseSystem.CurrentPID>")>/
%else
%<LibDumpSystemFcn(baseSystem,"Output%<tidVal>")>/
%endif
%<LibDumpSystemUserCode(baseSystem,"Output","Trailer")>/
%<LibDumpSystemUserCode(baseSystem,"Update","Header")>/
%<LibDumpSystemUserCode(baseSystem,"Update","Body")>/
%if SLibPartitionGroupingSystem(baseSystem)
%<LibDumpSystemFcn(baseSystem,"Update%<tidVal>%<baseSystem.CurrentPID>")>/
%else
%<LibDumpSystemFcn(baseSystem,"Update%<tidVal>")>/
%endif
%<LibDumpSystemUserCode(baseSystem,"Update","Trailer")>/
%endif
%if EXISTS(buffsRec.ExtModeTrailer%<tidVal>) && ...
!WHITE_SPACE(buffsRec.ExtModeTrailer%<tidVal>)
/* external mode */
%assign tmpBuff = buffsRec.ExtModeTrailer%<tidVal>
%<tmpBuff>/
%endif
%assign baseSystem.CurrentTID = prevRSCurrTid
%if SLibPartitionGroupingSystem(baseSystem)
%assign baseSystem.CurrentPID = prevRSCurrPid
%endif
%closefile retBuf
%if !ISFIELD(SampleTime[tidVal], "DumpedAsyncOutputCode")
%addtorecord SampleTime[tidVal] DumpedAsyncOutputCode TLC_TRUE
%endif
%return retBuf
%endfunction
%function SLibGetAsyncSysTid(ssBlock, recIdx)
%if ssBlock.Type == "SubSystem"
%assign ssTid = ssBlock.TaskToFirstTID
%return ssTid[0]
%else
%assert ssBlock.Type == "ModelReference"
%return ssBlock.InputPortTIDs[SFcnSystemOutputCall[recIdx].FcnPortIdx]
%endif
%endfunction
%function LibSetAsyncCounter(sfcnBlock,callIdx,buf) void
%assign recIdx = sfcnBlock.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock, recIdx)
%assign ssTid = SLibGetAsyncSysTid(ssBlock, recIdx)
%return "%<LibGetClockTick(ssTid)> = %<buf>;"
%endfunction
%function LibSetAsyncCounterHigh(sfcnBlock,callIdx,buf) void
%assign recIdx = sfcnBlock.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock, recIdx)
%assign ssTid = SLibGetAsyncSysTid(ssBlock, recIdx)
%if SLibClockTickIsUnit32Pair(ssTid)
%return "%<LibGetClockTickHigh(ssTid)> = %<buf>;"
%else
%return ""
%endif
%endfunction
%function SLibUpdateFloatTimeForAsyncTask(tid)
%openfile tmpBuf
%if SLibClockTickIsUnit32Pair(tid)
%assign ct = RTMDispatchToAccessFcn("ClockTick%<tid>", "get", ...
"", "", ::tSimStruct)
%assign cth = RTMDispatchToAccessFcn("ClockTickH%<tid>", "get", ...
"", "", ::tSimStruct)
%assign ss = RTMDispatchToAccessFcn("StepSize%<tid>", "get", ...
"", "", ::tSimStruct)
%assign tt = "%<LibGetTaskTime(tid)>"
%if PurelyIntegerCode
%<tt> = %<ct> + %<cth> * 4294967296.0;
%else
%<tt> = %<ct> * %<ss> + %<cth> * %<ss> * 4294967296.0;
%endif
%else
%assign ct = RTMDispatchToAccessFcn("ClockTick%<tid>", "get", ...
"", "", ::tSimStruct)
%assign ss = RTMDispatchToAccessFcn("StepSize%<tid>", "get", ...
"", "", ::tSimStruct)
%assign tt = "%<LibGetTaskTime(tid)>"
%if PurelyIntegerCode
%<tt> = (%<ct>);
%else
%<tt> = (%<ct>) * %<ss>;
%endif
%endif
%closefile tmpBuf
%return tmpBuf
%endfunction
%function LibSetAsyncClockTicks(sfcnBlock, callIdx, buf1, buf2) void
%assign recIdx = sfcnBlock.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock, recIdx)
%assign ssTid = SLibGetAsyncSysTid(ssBlock, recIdx)
%openfile tmpBuf
%if SLibClockTickIsUnit32Pair(ssTid)
%if WHITE_SPACE(buf2)
%assign warnTxt = "Asynchronous task associated with "...
"sfunction %<sfcnBlock.Name> requires 64-bits hardware timer."...
"If target doesn't provide method to access the higher 32-bits "...
"of the hardware timer, higher 32-bits timer is calculated using " ...
"lower 32-bits. Lower 32-bits timer must never counter around pass "...
"it's previous value"
%<LibBlockReportWarning(sfcnBlock,warnTxt)>
if (%<LibGetClockTick(ssTid)> > %<buf1>) {
%<LibGetClockTickHigh(ssTid)>++;
}
%else
%<LibSetAsyncCounterHigh(sfcnBlock, callIdx, buf2)>
%endif
%endif
%<LibSetAsyncCounter(sfcnBlock, callIdx, buf1)>
%if SampleTime[ssTid].NeedFloatTime == "yes"
%<SLibUpdateFloatTimeForAsyncTask(ssTid)>
%endif
%closefile tmpBuf
%return tmpBuf
%endfunction
%function LibNeedAsyncCounter(sfcnBlock,callIdx) void
%assign recIdx = sfcnBlock.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock, recIdx)
%assign ssTid = SLibGetAsyncSysTid(ssBlock, recIdx)
%return (::CompiledModel.SampleTime[ssTid].NeedAbsoluteTime == "yes"? TLC_TRUE:TLC_FALSE)
%endfunction
%function LibManageAsyncCounter(sfcnBlock,callIdx) void
%assign recIdx = sfcnBlock.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock, recIdx)
%assign ssTid = SLibGetAsyncSysTid(ssBlock, recIdx)
%return (LibNeedAsyncCounter(sfcnBlock,callIdx) && ...
(::CompiledModel.SampleTime[ssTid].TimeSource == "Self"))
%endfunction
%function LibGetCallerClockTickCounter(sfcnBlock) void
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock,0)
%assign callerTid = FcnGetAsyncPromotedTID(SLibGetAsyncSysTid(ssBlock, 0))
%assert ::CompiledModel.SampleTime[callerTid].NeedAbsoluteTime == "yes"
%return LibGetClockTick(callerTid)
%endfunction
%function LibGetCallerClockTickCounterHigh(sfcnBlock) void
%assign ssBlock = LibGetFcnCallBlock(sfcnBlock,0)
%assign callerTid = FcnGetAsyncPromotedTID(SLibGetAsyncSysTid(ssBlock,0))
%assert ::CompiledModel.SampleTime[callerTid].NeedAbsoluteTime == "yes"
%if SLibClockTickIsUnit32Pair(callerTid)
%return LibGetClockTickHigh(callerTid)
%else
%return ""
%endif
%endfunction
%function FcnGetAsyncPromotedTID(tid)
%assert(LibAsynchronousTriggeredTID(tid))
%if Accelerator
%return tid
%else
%return SampleTime[tid].AsyncPromotedTID
%endif
%endfunction
%endif
%function SLibAsyncSampleTimeGeneratesTimeManagementCode(tid)
%assert LibAsynchronousTriggeredTID(tid)
%assign retVal = TLC_FALSE
%if ISFIELD(SampleTime[tid],"AsyncSfcnBlkIdx")
%assign asyncSfcnBlkIdx = SampleTime[tid].AsyncSfcnBlkIdx
%assign asyncSfcnBlk = System[asyncSfcnBlkIdx[0]].Block[asyncSfcnBlkIdx[1]]
%with asyncSfcnBlk
%if SLibSfcnHasBranchFcnCall(asyncSfcnBlk)
%assign retVal = TLC_TRUE
%elseif ISFIELD(asyncSfcnBlk,"NumSFcnSysOutputCallDsts") && ...
NumSFcnSysOutputCallDsts == 1 && ...
!ISEQUAL(SFcnSystemOutputCall[0].BlockToCall, "unconnected")
%assign sysIdx = SFcnSystemOutputCall[0].BlockToCall[0]
%assign blkIdx = SFcnSystemOutputCall[0].BlockToCall[1]
%assign fcnCallBlock = System[sysIdx].Block[blkIdx]
%assign retVal = (fcnCallBlock.Type == "ModelReference")
%endif
%endwith
%endif
%return retVal
%endfunction
%function FcnGetTaskTopSfcnBlock(tid)
%assign taskTopSfcnBlock = ""
%if LibAsynchronousTriggeredTID(tid)
%if ISFIELD(SampleTime[tid], "AsyncSfcnBlkIdx")
%assign blkIdx = SampleTime[tid].AsyncSfcnBlkIdx
%assign taskTopSfcnBlock = System[blkIdx[0]].Block[blkIdx[1]]
%endif
%endif
%return taskTopSfcnBlock
%endfunction
%function FcnIsForcedInlinedForAsync(system,activeTid)
%assign sysTid = LibGetSubsystemTID(system, TLC_TRUE)
%return sysTid >=0 && LibAsynchronousTriggeredTID(activeTid) && !ISEQUAL(activeTid, sysTid)
%endfunction
%function FcnAddAsyncFunctionToCodeDescriptor(functionName, taskIndex, priority) void
%if !ISFIELD(::CompiledModel, "CodeDescriptorAsyncFunctions")
%addtorecord ::CompiledModel CodeDescriptorAsyncFunctions {}
%endif
%createrecord entry {functionName "%<functionName>"}
%addtorecord entry taskIndex "%<taskIndex>"
%addtorecord entry priority "%<priority>"
%addtorecord ::CompiledModel.CodeDescriptorAsyncFunctions %<functionName> entry
%endfunction