Генератор кода производит код из модели Simulink®, содержащей один или несколько Variant Subsystem, Variant Source и блоки Variant Sink. Чтобы изучить, как создать модель, содержащую различные блоки, смотрите, Создают Простую Различную Модель (Simulink). Чтобы изучить, как создать пользовательскую проверку Model Advisor, которая оценивает сгенерированный код от активных и неактивных различных путей в модели вариантной системы, смотрите, Создают Собственную проверку, чтобы Оценить Активные и Неактивные Различные Пути из Модели (Simulink Check).
Во время генерации кода может быть выведено предупреждение, связанное с 'Функцией генерации кода, группирующей' для блока Variant. В диалоговом окне параметров блоков блока Variant нажмите Code Generation и затем выберите Reusable function
от Function packaging выпадающий список, чтобы решить эту проблему.
Код сгенерирован для различных вариантов, активного варианта и варианта по умолчанию. Чтобы сгенерировать код для вариантов, установите следующие условия в Различной Подсистеме, Различном Источнике или блоке Variant Sink:
Выберите Expression
как Variant Control mode от диалогового окна параметров блоков.
Выберите опцию Analyze all choices during update diagram and generate preprocessor conditionals.
Код, сгенерированный для Различных блоков Subsystem, окружается условными выражениями препроцессора C #if
, #else
, #elif
, и #endif
. Код, сгенерированный для Различного Источника и Различных блоков Приемника, окружается условными выражениями препроцессора C #if
и #endif
. Поэтому активный вариант выбран во время компиляции, и условные выражения препроцессора определяют который разделы кода выполниться.
Чтобы создать различные модели и сгенерировать директивы препроцессору в сгенерированном коде, см. Модели Варианта Использования в качестве примера, чтобы Сгенерировать Код Который Использование C Условные выражения Препроцессора.
Чтобы создать различные подсистемы и сгенерировать директивы препроцессору в сгенерированном коде, смотрите Подсистему Варианта Использования в качестве примера, Чтобы Сгенерировать Код Который Использование C Условные выражения Препроцессора.
Чтобы создать модели с различными источниками и приемниками и сгенерировать директивы препроцессору в сгенерированном коде, смотрите, что пример Представляет Различные Блоки Источника и Приемника в Сгенерированном коде.
Чтобы сгенерировать условные выражения препроцессора, типы блоков, которые можно поместить в дочерних подсистемах Различного блока Subsystem, ограничиваются. Связи не позволены в Различной схеме блока Subsystem. Однако во время процесса генерации кода, одного VariantMerge
блок помещается во вход каждого блока Outport в рамках Различной схемы блока Subsystem. Все дочерние подсистемы соединяются с каждым VariantMerge
блоки.
В фигуре ниже, процесс генерации кода устанавливает следующие связи и добавляет VariantMerge
блоки к sldemo_variant_subsystems модели.
Когда по сравнению с типовым блоком Merge VariantMerge
блок может иметь только один параметр, который является количеством Входных параметров. VariantMerge
блок используется в генерации кода в различных подсистемах внутренне и не доступен внешне, чтобы использоваться в моделях. Количество входных параметров для VariantMerge
определен и соединен как показано в фигуре ниже.
Дочерние подсистемы Различного блока Subsystem должны быть атомарными подсистемами. Выберите параметр Treat as atomic unit в диалоговом окне параметров блока Subsystem, чтобы сделать подсистемы атомарными. VariantMerge
блоки вставляются в выходном порту подсистем, если больше чем одна дочерняя подсистема присутствует. Если исходный блок VariantMerge
вход блока является невиртуальным, сообщение об ошибке будет отображено во время генерации кода. Необходимо сделать исходный блок непрерывным путем вставки блоков Преобразования Сигнала в вариантах. Сигналы, которые вводят Различный блок Subsystem, должны иметь те же свойства сигнала (например, размерности сигнала, порт width и класс памяти). VariantMerge
блок не поддерживает различные свойства сигнала, потому что входные порты и выходные порты совместно используют ту же память. Можно использовать символьные размерности, чтобы сгенерировать код для различной подсистемы с дочерними подсистемами различных размерностей выходного сигнала.
Следующие компоненты условно не скомпилированы, даже если только код для различных подсистем или модели, которые условно скомпилированы ссылка их.
rtModel
поля структуры данных
#include
из служебных файлов
Глобальные постоянные поля структуры параметра, на которые ссылаются несколько подсистем, активированных различными вариантами
Параметры, которые сконфигурированы, чтобы использовать импортированный, экспортируемый или класс памяти генерации пользовательского кода, и ссылаются несколькими подсистемами, которые активируются различными вариантами
Параметры, которые сконфигурированы, чтобы использовать импортированный, экспортируемый или класс памяти генерации пользовательского кода, и используются различными блоками модели
Для моделирования шаблонов, в которых блок Root Inport соединяется с блоком Variant с одним вариантом, Simulink вставляет скрытую комбинацию блока блока Ground, блока Signal Conversion и блока Variant Merge. Если вариант оценивает ко лжи, эта комбинация блока производит выход 0.0
.
Например, модель Varianttoground
содержит Различный Исходный блок с одним вариантом. Когда Различное Управление SYSCONST_A==6
оценивает к истине, входу к Subsystem
синусоида. Когда SYSCONST_A==6
оценивает ко лжи, входу к Subsystem
0.0
.
varianttoground.c
файл содержит этот код:
* Sin: '<Root>/Sine Wave' incorporates: * SignalConversion generated from: '<Root>/Subsystem' */ #if SYSCONST_A == 6 Varianttoground_B.VM_Conditional_Signal_Subsystem_0 = sin (Varianttoground_M->Timing.t[0]); #else /* SignalConversion generated from: '<Root>/Subsystem' */ Varianttoground_B.VM_Conditional_Signal_Subsystem_0 = 0.0; #endif /* End of Sin: '<Root>/Sine Wave' */
Комментарии в сгенерированном коде указывают на присутствие скрытого блока преобразования сигнала. В связанных гиперссылками комментариях можно проследить до исходного блока в модели, которая инициировала вставку скрытого блока. Код не содержит комментарий для блока Variant Merge, потому что этот блок не имеет сопоставленного сгенерированного кода. Блок Variant Merge используется внутренне и не находится в Библиотеке Simulink.
Когда модель имеет различные блоки, глобальные сигналы и состояния охраняют в сгенерированном коде с их соответствующим различным условием.
Рассмотрите модель, содержащую блок Variant Source. Блок Variant Source имеет условия V==1
и V==2
.
В сгенерированном коде глобальные сигналы и состояния охраняют в объявлении, инициализации модели и определении данных как показано ниже.
Защита сигналов:
Объявление:
/* Exported block signals */ #if V == 1 || V == 2 real_T myOutput; /* '<Root>/Gain3' */ #endif
Инициализация модели:
/* exported global signals */ #if V == 1 || V == 2 myOutput = 0.0; #endif
Определение данных:
* Exported Global Signals * * Note: Exported global signals are block signals with an exported global * storage class designation. Code generation will declare the memory for * these signals and export their symbols. * */ #if V == 1 || V == 2 extern real_T myOutput; /* '<Root>/Gain3' */ #endif
Защита состояний:
/* Block states (default storage) */ DW_mStorageClass_T mStorageClass_DW; /* External inputs (root inport signals with default storage) */ ExtU_mStorageClass_T mStorageClass_U; /* Real-time model */ RT_MODEL_mStorageClass_T mStorageClass_M_; RT_MODEL_mStorageClass_T *const mStorageClass_M = &mStorageClass_M_; /* Model step function */ void step(void) { #if V == 1 || V == 2 real_T rtb_VariantMerge_For_Variant_So; #endif
/* states (dwork) */ (void) memset((void *)&mStorageClass_DW, 0, sizeof(DW_mStorageClass_T)); /* external inputs */ (void)memset(&mStorageClass_U, 0, sizeof(ExtU_mStorageClass_T)); /* InitializeConditions for Delay: '<Root>/Delay' */ #if V == 1 mStorageClass_DW.Delay_DSTATE[0] = mStorageClass_P.Delay_InitialCondition; mStorageClass_DW.Delay_DSTATE[1] = mStorageClass_P.Delay_InitialCondition; #endif
Когда вы генерируете код для модели, содержащей различные блоки, параметры охраняют в сгенерированном коде.
Считайте модель с блоком Constant присоединенной к Различному Исходному блоку.
В сгенерированном коде параметр блока Constant охраняют в заголовочном файле как показано ниже.
/* Exported data definition */ /* Const memory section */ /* Definition for custom storage class: Const */ #if V == 2 const int32_T Parameter2 = 1; #endif
Когда модель имеет блоки Model Reference, которые являются условным выражением, должным встраивать варианты, заголовочный файл и экземпляры, относящиеся к блокам Model Reference, охраняют.
Рассмотрите эту модель с двумя блоками Моделей - ссылок, которые являются условным выражением, должным встраивать варианты.
Когда вы генерируете код для этой модели, заголовочный файл и экземпляры, относящиеся к блокам Model Reference, охраняют как показано в коде ниже.
#include "mWithTwoModelBlocks_Top_types.h" #include "multiword_types.h" #if (A == 1) //Guarding #define mWithTwoModelBlocks_Ref2_MDLREF_HIDE_CHILD_ #include "mWithTwoModelBlocks_Ref2.h" #endif #if (B == 1) //Guarding #include "mWithTwoModelBlocks_Ref1.h" #endif