Target Language Compiler | ![]() ![]() |
Block Functions
The functions declared inside each of the block target files are called by the system target files. In these tables, block
refers to a Simulink block name (e.g., gain
for the Gain block) and system
refers to the subsystem in which the block resides. The first table lists the two functions that are used for preprocessing and setup. Neither of these functions outputs any generated code.
The following functions all generate executable code that Real-Time Workshop places appropriately.
Enable(block, system)
Disable(block, system)
Start(block, system)
InitializeConditions(block, system)
Outputs(block, system)
Update(block, system)
Derivatives(block, system)
Terminate(block, system)
In object-oriented programming terms, these functions are polymorphic in nature since each block target file contains the same functions. The Target Language Compiler dynamically determines at run-time which block function to execute depending on the block's type. That is, the system file only specifies that the Outputs
function, for example, is to be executed. The particular Outputs
function is determined by the Target Language Compiler depending on the block's type.
To write a block target file, use these polymorphic block functions combined with the Target Language Compiler library functions. For a complete list of the Target Language Compiler library functions, see TLC Function Library Reference.
BlockInstanceSetup(block, system)
The BlockInstanceSetup
function executes for all the blocks that have this function defined in their target files in a model. For example, if there are 10 From Workspace blocks in a model, then the BlockInstanceSetup
function in fromwks.tlc
executes 10 times, once for each From Workspace block instance. Use BlockInstanceSetup
to generate code for each instance of a given block type.
See the Reference chapter for available utility processing functions to call from inside this block function. See matlabroot
/rtw/c/tlc/blocks/lookup2d.tlc
for an example of the BlockInstanceSetup
function.
block
= Reference to a Simulink block
system
= Reference to a nonvirtual Simulink subsystem
This example uses BlockInstanceSetup
:
%function BlockInstanceSetup(block, system) void %if (block.InMask == "yes") %assign blockName = LibParentMaskBlockName(block) %else %assign blockName = LibGetFormattedBlockPath(block) %endif %if (CodeFormat == "Embedded-C") %if !(ParamSettings.ColZeroTechnique == "NormalInterp" && ... ParamSettings.RowZeroTechnique == "NormalInterp") %selectfile STDOUT Note: Removing repeated zero values from the X and Y axes will produce more efficient code for block: %<blockName>. To locate this block, type open_system('%<blockName>') at the MATLAB command prompt. %selectfile NULL_FILE %endif %endif %endfunction
BlockTypeSetup
executes once per block type before code generation begins. That is, if there are 10 Lookup Table blocks in the model, the BlockTypeSetup
function in look_up.tlc
is only called one time. Use this function to perform general work for all blocks of a given type.
See "TLC Function Library Reference," for a list of relevant functions to call from inside this block function. See look_up.tlc
for an example of the BlockTypeSetup
function.
BlockTypeSetup(block, system) void
block
= Reference to a Simulink blocksystem
= Reference to a nonvirtual Simulink subsystem
As an example, given the S-function foo
requiring a #define
and two function declarations in the header file, you could define the following function:
%function BlockTypeSetup(block, system) void %% Place a #define in the model's header file %openfile buffer #define A2D_CHANNEL 0 %closefile buffer %<LibCacheDefine(buffer)> %% Place function prototypes in the model's header file %openfile buffer void start_a2d(void); void reset_a2d(void); %closefile buffer %<LibCacheFunctionPrototype(buffer)> %endfunction
The remaining block functions execute once for each block in the model.
Nonvirtual subsystem Enable
functions are created whenever a Simulink subsystem contains a block with an Enable
function. Including the Enable
function in a block's target file places the block's specific enable code into this subsystem Enable
function. See sin_wave.tlc
for an example of the Enable
function.
%% Function: Enable ============================================ %% Abstract: %% Subsystem Enable code is only required for the discrete form %% of the Sine Block. Setting the boolean to TRUE causes the %% Output function to re-sync its last values of cos(wt) and %% sin(wt). %% %function Enable(block, system) Output %if LibIsDiscrete(TID) /* %<Type> Block: %<Name> */ %<LibBlockIWork(SystemEnable, "", "", 0)> = (int_T) TRUE; %endif %endfunction
Nonvirtual subsystem Disable
functions are created whenever a Simulink subsystem contains a block with a Disable
function. Including the Disable
function in a block's target file places the block's specific disable code into this subsystem Disable
function. See outport.tlc
in matlabroot
/rtw/c/tlc/blocks
for an example of the Disable
function.
Include a Start
function to place code into the Start
function. The code inside the Start
function executes once and only once. Typically, you include a Start
function to execute code once at the beginning of the simulation (e.g., initialize values in the work vectors; see backlash.tlc
) or code that does not need to be reexecuted when the subsystem in which it resides enables. See constant.tlc
for an example of the Start
function:
%% Function: Start ============================================ %% Abstract: %% Set the output to the constant parameter value if the block %% output is visible in the model's start function scope, i.e., %% it is in the global rtB structure. %% %function Start(block, system) Output %if LibBlockOutputSignalIsInBlockIO(0) /* %<Type> Block: %<Name> */ %assign rollVars = ["Y", "P"] %roll idx = RollRegions, lcv = RollThreshold, block, ... "Roller", rollVars %assign yr = LibBlockOutputSignal(0,"", lcv, ... "%<tRealPart>%<idx>") %assign pr = LibBlockParameter(Value, "", lcv, ... "%<tRealPart>%<idx>") %<yr> = %<pr>; %if LibBlockOutputSignalIsComplex(0) %assign yi = LibBlockOutputSignal(0, "", lcv, ... "%<tImagPart>%<idx>") %assign pi = LibBlockParameter(Value, "", lcv, ... "%<tImagPart>%<idx>") %<yi> = %<pi>; %endif %endroll %endif %endfunction %% Start
InitializeConditions(block, system)
TLC code that is generated from the block's InitializeConditions
function ends up in one of two places. A nonvirtual subsystem contains an Initialize
function when it is configured to reset states on enable. In this case, the TLC code generated by this block function is placed in the subsystem Initialize
function and the start
function will call this subsystem Initialize
function. If, however, the Simulink block resides in the root system or in a nonvirtual subsystem that does not require an Initialize
function, the code generated from this block function is placed directly (inlined) into the start
function.
There is a subtle difference between the block functions Start
and InitializeConditions
. Typically, you include a Start
function to execute code that does not need to re-execute when the subsystem in which it resides enables. You include an InitializeConditions
function to execute code that must reexecute when the subsystem in which it resides enables. See delay.tlc
for an example of the InitializeConditions
function. The following code is an example from ratelim.tlc
:
%% Function: InitializeConditions ============================= %% %% Abstract: %% Invalidate the stored output and input in rwork[1 ... %% 2*blockWidth] by setting the time stamp (stored in %% rwork[0]) to rtInf. %% %function InitializeConditions(block, system) Output /* %<Type> Block: %<Name> */ %<LibBlockRWork(PrevT, "", "", 0)> = %<LibRealNonFinite(inf)>; %endfunction %% InitializeConditions
A block should generally include an Outputs
function. The TLC code generated by a block's Outputs
function is placed in one of two places. The code is placed directly in the model's Outputs
function if the block does not reside in a nonvirtual subsystem and in a subsystem's Outputs
function if the block resides in a nonvirtual subsystem. See absval.tlc
for an example of the Outputs
function:
%% Function: Outputs ========================================== %% Abstract: %% Y[i] = fabs(U[i]) if U[i] is real or %% Y[i] = sqrt(U[i].re^2 + U[i].im^2) if U[i] is complex. %% %function Outputs(block, system) Output /* %<Type> Block: %<Name> */ %% %assign inputIsComplex = LibBlockInputSignalIsComplex(0) %assign RT_SQUARE = "RT_SQUARE" %% %assign rollVars = ["U", "Y"] %if inputIsComplex %roll sigIdx = RollRegions, lcv = RollThreshold, ... block, "Roller", rollVars %% %assign ur = LibBlockInputSignal( 0, "", lcv, ... "%<tRealPart>%<sigIdx>") %assign ui = LibBlockInputSignal( 0, "", lcv, ... "%<tImagPart>%<sigIdx>") %% %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx) %<y> = sqrt( %<RT_SQUARE>( %<ur> ) + %<RT_SQUARE>( %<ui> ) ); %endroll %else %roll sigIdx = RollRegions, lcv = RollThreshold, ... block, "Roller", rollVars %assign u = LibBlockInputSignal (0, "", lcv, sigIdx) %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx) %<y> = fabs(%<u>); %endroll %endif %endfunction
Include an Update
function if the block has code that needs to be updated at each major time step. Code generated from this function is either placed into the model's or the subsystem's Update
function, depending on whether or not the block resides in a nonvirtual subsystem. See delay.tlc
for an example of the Update
function.
%% Function: Update ============================================ %% Abstract: %% X[i] = U[i] %% %function Update(block, system) Output /* %<Type> Block: %<Name> */ %assign stateLoc = (DiscStates[0]) ? "Xd" : "DWork" %assign rollVars = ["U", %<stateLoc>] %roll idx = RollRegions, lcv = RollThreshold, block, ... "Roller", rollVars %assign u = LibBlockInputSignal(0, "", lcv, idx) %assign x = FcnGetState("",lcv,idx, "") %<x> = %<u>; %endroll %endfunction %% Update
FcnGetState
is a function defined locally in delay.tlc
.
Include a Derivatives
function when generating code to compute the block's continuous states. Code generated from this function is either placed into the
model's or the subsystem's Derivatives
function, depending on whether or not the block resides in a nonvirtual subsystem. See integrat.tlc
for an example of the Derivatives
function.
Include a Terminate
function to place any code into MdlTerminate
. User-defined S-function target files can use this function to save data, free memory, reset hardware on the target, and so on. See tofile.tlc
for an example of the Terminate
function.
![]() | Block Target File Methods | Loop Rolling | ![]() |