Каждый блок имеет целевой файл, который определяет, какой код должен быть сгенерирован для блока. Код может изменяться в зависимости от точных параметров блока или типов соединений с ним (например, широкий или скалярный вход).
В каждом целевом файле блока функции блока определяют код, который должен быть выведен для блока в модели или подсистеме. start функция, output функция, update функция и так далее.
Функции, объявленные внутри каждого из целевых файлов блоков, вызываются целевыми файлами системы. В этих таблицах block ссылается на имя блока Simulink ® (например ,gain для блока усиления) и system относится к подсистеме, в которой находится блок. В первой таблице перечислены две функции, используемые для предварительной обработки и настройки. Ни одна из этих функций не выводит сгенерированный код.
Следующие функции генерируют исполняемый код, который генератор кода размещает соответствующим образом:
В объектно-ориентированных терминах программирования эти функции носят полиморфный характер, поскольку каждый целевой файл блока содержит одни и те же функции. Компилятор целевого языка динамически определяет во время выполнения, какую функцию блока выполнять в зависимости от типа блока. То есть системный файл указывает только, что Outputs например, должна выполняться функция. Деталь Outputs функция определяется компилятором целевого языка в зависимости от типа блока.
Чтобы записать целевой файл блока, используйте эти полиморфные функции блока в сочетании с функциями библиотеки компилятора целевого языка. Полный список функций библиотеки компилятора целевого языка см. в разделе Справочник библиотеки функций TLC по компилятору целевого языка.
BlockInstanceSetup выполняется для блоков, для которых эта функция определена в целевых файлах модели. Например, если модель включает 10 блоков из рабочей области, то BlockInstanceSetup функция в fromwks.tlc выполняется 10 раз, по одному разу для каждого экземпляра блока из рабочей области. Использовать BlockInstanceSetup для создания кода для каждого экземпляра данного типа блока.
Для получения информации о доступных функциях обработки служебных программ для вызова из этой блочной функции см. Справочник библиотеки функций TLC по компилятору целевого языка. Просмотр файла для примера matlabroot/rtw/c/tlc/blocks/lookup2d.tlcBlockInstanceSetup функция.
BlockInstanceSetup(block, system) void
block = Reference to a Simulink block
system = Reference to a nonvirtual Simulink subsystemВ этом примере используется 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
%endfunctionBlockTypeSetup выполняется один раз для каждого типа блока до начала создания кода. То есть, если в модели существует 10 блоков таблицы подстановки, BlockTypeSetup функция в look_up.tlc вызывается только один раз. Эта функция используется для выполнения общей работы с несколькими блоками данного типа.
Список соответствующих функций для вызова из этой блочной функции см. в справочнике библиотеки функций TLC по компилятору целевого языка. Посмотрите look_up.tlc для примера BlockTypeSetup функция.
BlockTypeSetup(block, system) void
block = Reference to a Simulink block
system = Reference to a nonvirtual Simulink subsystemВ качестве примера, учитывая S-функцию foo, для чего требуется #define и два объявления функций в файле заголовка, можно определить:
%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Остальные функции блока выполняются один раз для каждого блока в модели.
Генератор кода создает Enable функции для невиртуальной подсистемы всякий раз, когда подсистема Simulink содержит блок с Enable функция. Включая Enable функция в целевом файле блока помещает специфический код включения блока в эту подсистему Enable функция. Например:
%% Function: Enable ============================================
%% Abstract:
%% Subsystem Enable code is required only for the discrete form
%% of the Sine Block. Setting the Boolean to TRUE causes the
%% Output function to resync 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Невиртуальная подсистема Disable функции создаются всякий раз, когда подсистема Simulink содержит блок с Disable функция. Включая Disable функция в целевом файле блока помещает специфический код блокировки блока в эту подсистему Disable функция.
Включить Start для размещения кода в Start функция. Код внутри Start функция выполняется один раз и только один раз. Как правило, включается Start функция выполнения кода один раз в начале моделирования (например, инициализация значений в рабочих векторах) или кода, который не нуждается в повторном выполнении, когда подсистема, в которой он находится, включена. Посмотрите constant.tlc для примера Start функция.
%% 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Код TLC, генерируемый блоком InitializeConditions функция появляется в одном из двух мест. Невиртуальная подсистема содержит Initialize функция, если она сконфигурирована для сброса состояний при включении. В этом случае код TLC, генерируемый этой функцией блока, помещается в подсистему Initialize функции и start функция вызывает эту подсистему Initialize функция. Однако если блок Simulink находится в корневой системе или в невиртуальной подсистеме, для которой не требуется Initialize , код, сгенерированный из этой блочной функции, помещается непосредственно (встраивается) в start функция.
Существует незначительное различие между функциями блока Start и InitializeConditions. Как правило, включается Start для выполнения кода, который не нуждается в повторном выполнении, когда подсистема, в которой он находится, включена. Вы включаете InitializeConditions для выполнения кода, который должен выполняться повторно, когда подсистема, в которой он находится, включена. Например:
%% 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
Блок, как правило, должен включать Outputs функция. Код TLC, генерируемый блоком Outputs размещают функцию в одном из двух мест. Код помещается непосредственно в модель Outputs функция, если блок не находится в невиртуальной подсистеме, и в подсистеме Outputs функция, если блок находится в невиртуальной подсистеме. Например:
%% 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
Примечание
Код сброса с пересечением нуля помещается в Outputs функция.
При записи кода TLC для генерации встроенного кода из S-функции и если код TLC содержит Outputs необходимо изменить код TLC, если выполняются все эти условия:
Выходной порт использует или наследует постоянное время выборки. Выходной порт имеет постоянное значение.
S-функция является многоскоростной S-функцией или использует время выборки на основе порта.
В этом случае код TLC должен генерировать код для порта вывода с постоянным значением с помощью функции OutputsForTID вместо функции Outputs. Дополнительные сведения см. в разделе Указание постоянного времени выборки (INF) для порта.
Включить Update функция, если блок имеет код, который должен обновляться на каждом основном временном шаге. Код, генерируемый этой функцией, помещается либо в модели, либо в подсистеме Update в зависимости от того, находится ли блок в невиртуальной подсистеме. Например:
%% Function: Update ============================================
%% Abstract:
%% X[i] = U[i]
%%
%function Update(block, system) Output
/* %<Type> Block: %<Name> */
%assign rollVars = ["U", "Xd"]
%roll idx = RollRegions, lcv = RollThreshold, block, ...
"Roller", rollVars
%assign u = LibBlockInputSignal(0, "", lcv, idx)
%assign x = LibBlockDiscreteState("", lcv, idx)
%<x> = %<u>;
%endroll
%endfunction %% UpdateВключить Derivatives функция при формировании кода для вычисления непрерывных состояний блока. Код, генерируемый этой функцией, помещается либо в модели, либо в подсистеме Derivatives в зависимости от того, находится ли блок в невиртуальной подсистеме. Посмотрите integrat.tlc для примера Derivatives функция.
Включить Terminate функция для размещения кода в MdlTerminate. Пользовательские целевые файлы S-функций могут использовать эту функцию для сохранения данных, свободной памяти, сброса аппаратных средств на цели и т.д. Посмотрите tofile.tlc для примера Terminate функция.