| Target Language Compiler | ![]() |
Using BlockOutput[i].SigSrc
SigSrc enables us to generate a reference to the block I/O "slot" for this record. The block I/O is a hierarchical structure definition.
Consider a model that has two references (sysA1,sysA2) to a nonvirtual subsystem named sysA. Within sysA, there are three references (sysB1,sysB2,sysB3) to sysB. Within sysB, there are five references (sysC1,sysC2,sysC3,sysC4,sysC5) to sysC. The total number of system instances:
A model similar to this example is located at matlabroot/toolbox/rtw/rtwdemos/tlctutorial/biohstruct/biohstruct_a2b3c5_ex.mdl. Some examples based on this model:
rtB.sysA2.sysB1.sysC5.id where sysA2 is the 2nd instance of a system with struct rtB_sysA in the root, sysB1 is the 1st instance of rtB_sysB, in nonvirtual subsystem sysA2, and sysC5 is the 5th instance of rtB_sysC in nonvirtual subsystem sysB1.
p->sysB1.sysC5.id where pointer, p was previously set to &rtB.sysA2.
&p->sysB1.sysC5 to get at a structure address where, p was previously set to &rtB.sysA2.
&p->sysB1.sysC5.id[1] to get at the 2nd element of an output vector in sysC5.
A simple TLC function that lets us generate these references is shown below. This function is located in matlabroot/toolbox/rtw/rtwdemos/tlctutorial/biohstruct/biohstruct.tlc.
%function GetBlockIoHStructAccess(blockIoIdx, stopAtSystemIdx, ... accessPrefix, accessBlockIoStructOnly) %assign bo = CompiledModel.BlockOutputs.BlockOutput[blockIoIdx] %% bo.SigSrc = [systemIdx, callSiteIdx, blockIdx, outputPortIdx] %assign sysIdx = bo.SigSrc[0] %assign callSiteIdx = bo.SigSrc[1] %assign ans = accessBlockIoStructOnly ? "": bo.Identifier %foreach idx = CompiledModel.NumSystems %if sysIdx == stopAtSystemIdx %return accessPrefix + ans %else %% CallSites = Mx4 matrix where each row contains: %% [callerSysIdx, callersCallSiteIdx, ... %% graphicalSysIdx, ssBlkIdxInGraphicalSys] %assign callSiteRow = CompiledModel.System[sysIdx].CallSites[callSiteIdx] %% %% Locate the subsystem Block record to get at the call-site info %% %assign graphicalSysIdx = callSiteRow[2] %assign ssBlkIdxInGraphicalSys = callSiteRow[3] %assign graphicalSys = CompiledModel.System[graphicalSysIdx] %assign ssBlk = graphicalSys.Block[ssBlkIdxInGraphicalSys] %% %% Update the hierarchical strcture access. %% %assign ans = ssBlk.CallSiteInfo.StructId + "." + ans %% %% Walk up the call stack by moving sysIdx and callSiteIdx for %% next iteration %% %assign sysIdx = callSiteRow[0] %assign callSiteIdx = callSiteRow[1] %endif %endforeach %endfunction %% SLibGetBlockIOHStructAccess
This function lets us generate an observer reference to a particular slot in the block I/O (similar to ex1) by passing the desired BlockOutput record index, stopAtSystemIdx == the root system index, accessPrefix == "rtB->", and accessBlockIoStructOnly==0.
This function lets us generate internal references to the Block I/O structure (similar to ex2) where we are in a System record and need a portion of the fully qualified signal access. This is achieved by passing the desired BlockOutput record index, stopAtSystemIdx == DeclSystemIdx (a field within the system record), accessPrefix == "p->", and accessBlockIoStructOnly==0.
This function lets us generate references similar to ex3 by calling by passing the first BlockOutput record index corresponding to the start of the desired structure, stopAtSystemIdx == DeclSystemIdx, accessPrefix = "&p->", and accessBlockIoStructOnly==1.
This function lets us generate references similar to ex4 by passing the BlockOutput record index corresponding stopAtSystemIdx == DeclSystemIdx, accessPrefix == "&p->", and accessBlockIoStructOnly==0. The string "[1]" must then be appended to the return value of GetBlockIoHStructAccess. This example occurs when processing the canonical inputs to a system.
CallSites and their Interaction with SigSrc's.
We will now explore the CallSites matrix in a little more detail. Consider the model, which is located at: matlabroot/toolbox/rtw/rtwdemos/tlctutorial/biohstruct/biohstruct_fcncall_ex.mdl. The overall model is configured as shown below.
The model contains three function call subsystems, A, B, and C:
From Model.rtw System Record, the System[i].CallSites field contains
[[callerSysIdx, callersCallSiteIdx, graphicalSysIdx, ssBlkIdxInGraphicalSys]; ...]
and from Model.rtw Block I/O Information BlockOuptuts.BlockOutput[i].SigSrc field contains:
[systemIdx, callSiteIdx, blockIdx, outputPortIdx]
Looking at the model.rtw for this example, we see:
... BlockOutputs { ... BlockOutput { << Accessed via BlockOutput[6] Identifier Gain2 SigSrc [0, 0, 3, 0] } ... } ... System { Type "function-call" Name "<Root>/C" ... CallSites Matrix(1,4) [[1, 0, 3, 6];] ... } System { Type "function-call" Name "<Root>/B" ... CallSites Matrix(1,4) [[2, 0, 3, 4];] ... } System { Type "function-call" Name "<Root>/A" ... CallSites Matrix(1,4) [[3, -1, 3, 2];] } System { Type root Name "<Root>" ... } ...
Consider a call to GetBlockIoHStructAccess(6, 4, "rtB.", 0) this will use the SigSrc record above to get at sysIdx = 0 to access System with Name "<Root>/C" and callSiteIdx = 0. Then we enter the %foreach loop where we we access the System[sysIdx].CallSites[callSiteIdx] row. Notice that in System `C' the callSysIdx (1 = System B) is not equal to the graphicalSysIdx (3 = System Root). This is because C is called by B, but resides in the Root System. This process continues and the function produces:
Looking at the CallSites matrix, we see that the first two elements (callerSysIdx, callersCallSiteIdx) are used to construct the order in which the identifier path is created. The second two elements (graphicalSysIdx, ssBlkIdxInGraphicalSys) are used to obtain the specific name for each section of the identifier path.
| Signal Connections | Data Type Work (DWork) Information | ![]() |