Каждый блок имеет целевой файл, который определяет, какой код должен быть сгенерирован для блока. Код может варьироваться в зависимости от точных параметров блока или типов соединений с ним (например, широкий и скалярный входы).
В каждом целевом файле блока block functions задайте код, который будет выведен для блока в модели или подсистеме start
функция, output
функция, update
функции и так далее.
Функции, объявленные внутри каждого из целевых файлов блоков, вызываются системными целевыми файлами. В этих таблицах block
относится к Simulink® имя блока (например gain
для блока Gain) и system
относится к подсистеме, в которой находится блок. В первой таблице перечислены две функции, которые используются для предварительной обработки и настройки. Ни одна из этих функций не выводит сгенерированный код.
Следующие функции генерируют исполняемый код, который должным образом помещает генератор кода:
В объектно-ориентированных терминах программирования эти функции носят полиморфный характер, потому что каждый целевой файл блока содержит одни и те же функции. Компилятор целевого языка динамически определяет во время выполнения, какую функцию блока выполнять в зависимости от типа блока. То есть системный файл указывает только, что Outputs
функция, для примера, должна выполняться. Деталь Outputs
функция определяется компилятором целевого языка в зависимости от типа блока.
Чтобы записать целевой файл блока, используйте эти функции полиморфных блоков в сочетании с функциями библиотеки Target Language Compiler. Полный список функций библиотеки компилятора целевого языка см. в разделе Ссылки библиотеки функций TLC на компиляторе целевого языка.
BlockInstanceSetup
функция выполняется для блоков, которые имеют эту функцию, определенную в их целевых файлах в модели. Например, если модель включает 10 блоков Из Рабочей области, то BlockInstanceSetup
функция в fromwks.tlc
выполняется 10 раз, один раз для каждого образца блока From Workspace. Использовать BlockInstanceSetup
чтобы сгенерировать код для каждого образца заданного типа блока.
Смотрите Ссылку по библиотеке функций TLC на Target Language Compiler для доступных функций обработки утилит, чтобы вызвать из этой функции блока. Смотрите файл
для примера 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 %endfunction
BlockTypeSetup
выполняется один раз на тип блока перед началом генерации кода. То есть, если в модели существуют блоки 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
функция.
Включите a 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
function, код, сгенерированный из этой блочной функции, помещается непосредственно (inlined) в 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, если блок находится в невиртуальной подсистеме. Для примера:
%% 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 код, чтобы сгенерировать inlined код из S-функции, и если TLC код содержит Outputs
функция, вы должны изменить код TLC, если все эти условия верны:
Порт выхода использует или наследует постоянные шаги расчета. Порт выхода имеет постоянное значение.
S-функция является многократной S-функцией или использует основанные на порте шаги расчета.
В этом случае код TLC должен сгенерировать код для порта выхода с постоянными значениями при помощи функции OutputsForTID
вместо функции Outputs
. Для получения дополнительной информации смотрите Задание Постоянного Шага Расчета (Inf) для Порта.
Включите Update
function, если блок имеет код, который нужно обновить на каждом крупном временном шаге. Код, сгенерированный из этой функции, помещается или в модель, или в подсистему 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
Включите a Derivatives
функция при генерации кода для вычисления непрерывных состояний блока. Код, сгенерированный из этой функции, помещается или в модель, или в подсистему Derivatives
функция, в зависимости от того, находится ли блок в невиртуальной подсистеме. См. integrat.tlc
для примера Derivatives
функция.
Включите a Terminate
функция для размещения кода в MdlTerminate
. Пользовательские целевые файлы S-функции могут использовать эту функцию для сохранения данных, свободной памяти, сброса оборудования на целевой системе и так далее. См. tofile.tlc
для примера Terminate
функция.