Прежде чем исследовать определенные части генерации кода компилятора целевого языка (TLC), рассмотрите, как компилятор целевого языка генерирует код для простой модели. На следующем рисунке показано, что блокирует размещение кода в Mdl процедуры. Это показывает MdlOutputs.

static void simple_output(int_T tid)
{
/* Sin Block: '<Root>/Sine Wave' */
simple_B.SineWave_d = simple_P.SineWave_Amp *
sin(simple_P.SineWave_Freq * simple_M->Timing.t[0] +
simple_P.SineWave_Phase) + simple_P.SineWave_Bias;
/* Gain: '<Root>/Gain' */
simple_B.Gain_d = simple_B.SineWave_d * simple_P.Gain_Gain;
/* Outport: '<Root>/Out1' */
simple_Y.Out1 = simple_B.Gain_d;
}Блоки имеют входы, выходы, параметры, состояния, а также другие общие свойства. Например, входы и выходы блоков обычно записываются в структуру блочного ввода-вывода (генерируемую идентификаторами типа , где model_B - имя модели). Входы блоков также могут поступать из внешней структуры ввода (modelили структура состояния при подключении к порту состояния интегратора (model_U) или заземление (model_XrtGround) если не подключен или заземлен. Блочные выходы также могут поступать во внешнюю структуру вывода, (). На следующей схеме показаны общие сопоставления блочных данных.model_Y

Это обсуждение должно дать вам общее представление о том, как выглядит объект блока. Теперь можно просмотреть отдельные части процесса создания кода, относящиеся к компилятору целевого языка.
Генератор кода вызывает компилятор целевого языка после компиляции модели в частичное представление модели () подходит для генерации кода. Для создания кода компилятор целевого языка использует свою библиотеку функций для преобразования двух классов целевых файлов:model.rtw
Системные целевые файлы
Блокировать целевые файлы
Системные целевые файлы используются для определения общей структуры создаваемого кода с учетом конкретных целевых сред. Целевые файлы блоков используются для реализации функциональных возможностей блоков Simulink ®, включая пользовательские S-функциональные блоки.
Можно создать целевые файлы блоков для C MEX, Fortran и S-функций языка MATLAB ®, чтобы полностью встроить функциональные возможности блоков в тело сгенерированного кода. S-функции C MEX могут быть неинлинированными, оберточными или полностью встроенными. S-функции Fortran должны быть встроены или полностью встроены.
Всякий раз, когда компилятор целевого языка обнаруживает запись для блока S-функции в он должен решить, нужно ли генерировать вызов S-функции или встроить ее.model.rtw
Потому что они не могут использовать SimStructs, S-функции языка Fortran и MATLAB должны быть встроены. Это вложение может быть либо в виде целевого файла с полным блоком, либо в виде целевого файла с однострочным блоком, который ссылается на замещающий исходный файл C MEX S-функции.
Компилятор целевого языка выбирает S-функцию C MEX для встраивания, если она явная mdlRTW() существует в S-функциональном коде или если целевой файл для текущего целевого языка для текущего блока находится в пути поиска TLC-файла. Если S-функция C MEX имеет явное mdlRTW() , должен быть соответствующий целевой файл или результат условия ошибки.
Целевой файл для S-функции должен иметь то же корневое имя, что и S-функция, и иметь расширение .tlc. Например, целевой файл для S-функции C MEX с именем sfix_bitop имеет имя файла sfix_bitop.tlc.
В этом примере рассматривается S-функция C MEX с именем sfix_bitop. Опции генерации кода задаются так, чтобы разрешить повторное использование сигнальной памяти для сигнальных линий, которые не были установлены как настраиваемые сигналы.

Код, генерируемый для блока битового оператора, повторно использует временную переменную, которая устанавливается для вывода блока суммы для сохранения памяти. Это приводит к одной очень эффективной строке кода, как видно здесь.
/* Bitwise Logic Block: <Root>/Bitwise Logical Operator */ /* [input] OR 'F00F' */ rtb_temp2 |= 0xF00F;
Для этого встроенного блока не требуется инициализация или код установки.
Если бы этот блок не был встроен, исходный код для самой S-функции с ее различными опциями был бы добавлен в базу сгенерированного кода, память была бы выделена в сгенерированном коде для блока SimStruct и будут генерироваться вызовы методов S-функции для инициализации, запуска и завершения кода S-функции. Для выполнения команды mdlOutputs функции S-функции, код будет генерироваться следующим образом:
/* Level2 S-Function Block: <Root>/Bitwise Logical Operator (sfix_bitop) */
{
SimStruct *rts = ssGetSFunction(rtS, 0);
sfcnOutputs(rts, tid);
}Все mdlOutputs вызывается и запускается так же, как во время моделирования. Но это не все. Существует также код регистрации, инициализации и окончания для неинлинной S-функции. Вызовы инициализации и завершения аналогичны приведенному выше фрагменту. Затем код регистрации для S-функции только с одним входом и одним выходом составляет 72 строки кода C, сгенерированного как часть файла. .model_reg.h
/*Level2 S-Function Block: <Root>/Bitwise Logical Operator (sfix_bitop) */
{
extern void untitled_sf(SimStruct *rts);
SimStruct *rts = ssGetSFunction(rtS, 0);
/* timing info */
static time_T sfcnPeriod[1];
static time_T sfcnOffset[1];
static int_T sfcnTsMap[1];
{
int_T i;
for(i = 0; i < 1; i++) {
sfcnPeriod[i] = sfcnOffset[i] = 0.0;
}
}
ssSetSampleTimePtr(rts, &sfcnPeriod[0]);
ssSetOffsetTimePtr(rts, &sfcnOffset[0]);
ssSetSampleTimeTaskIDPtr(rts, sfcnTsMap);
ssSetMdlInfoPtr(rts, ssGetMdlInfoPtr(rtS));
/* inputs */
{
static struct _ssPortInputs inputPortInfo[1];
_ssSetNumInputPorts(rts, 1);
ssSetPortInfoForInputs(rts, &inputPortInfo[0]);
/* port 0 */
{
static real_T const *sfcnUPtrs[1];
sfcnUPtrs[0] = &rtU.In1;
ssSetInputPortSignalPtrs(rts, 0, (InputPtrsType)&sfcnUPtrs[0]);
_ssSetInputPortNumDimensions(rts, 0, 1);
ssSetInputPortWidth(rts, 0, 1);
}
}
.
.
.Это продолжается до тех пор, пока размеры и методы S-функций не будут объявлены, распределены и инициализированы. Количество генерируемого кода регистрации по существу пропорционально количеству и размеру входных портов и выходных портов.
Неинлинная S-функция обычно оказывает значительное влияние на размер генерируемого кода, тогда как встроенная S-функция может быть близка к рукописному размеру и производительности генерируемого кода.