Используйте различную подсистему, чтобы сгенерировать код, который использует условные выражения препроцессора C

В этом примере показано, как использовать подсистемы варианта Simulink®, чтобы сгенерировать условные выражения препроцессора C, которые управляют, какая дочерняя подсистема различной подсистемы активна в сгенерированном коде, произведенном Simulink® Coder™.

Обзор различных подсистем

Различный блок Subsystem содержит две или больше дочерних подсистемы, где один дочерний элемент активен во время выполнения модели. Активная дочерняя подсистема упоминается как активный вариант. Можно программно переключить активный вариант Различного блока Subsystem путем изменения значений переменных в базовом рабочем пространстве, или вручную переопределяющим различным выбором с помощью Различного диалогового окна блока Subsystem. Активный вариант программно соединен с блоками Inport и Outport Различной Подсистемы Simulink® во время компиляции модели.

Программно управлять различным выбором, Simulink.Variant объект сопоставлен с каждой дочерней подсистемой в Различном диалоговом окне блока Subsystem. Simulink.Variant объекты создаются в базовом рабочем пространстве MATLAB®. Эти объекты имеют свойство под названием Condition, выражение, которое оценивает к булеву значению и используется, чтобы определить активную различную дочернюю подсистему.

По умолчанию сгенерированный код содержит только активный вариант. В качестве альтернативы можно параметрировать выбор активного варианта и сделать его зависящим от значений переменных и объектов в основной рабочей области MATLAB®. Когда вы генерируете код, можно сгенерировать код для всех вариантов и задержать выбор активного варианта, пока не пора скомпилировать тот код.

Определение вариантов для блока Subsystem

Открытие модели rtwdemo_preprocessor_subsys в качестве примера запустит PostLoadFcn, заданный в "Файле: ModelProperties: Коллбэки" диалоговое окно. Это заполнит базовое рабочее пространство с переменными для Различных блоков Subsystem.

open_system('rtwdemo_preprocessor_subsys')

Подсистема варианта LeftController содержит две дочерних подсистемы: Линейный и Нелинейный. Дочерняя подсистема LeftController/Linear выполняется когда Simulink. Различный объект LINEAR оценивает к true, и дочерняя подсистема LeftController/Nonlinear выполняется когда Simulink. Различный объект NONLINEAR оценивает к true.

Simulink. Различные объекты заданы для подсистемы LeftController путем щелчка правой кнопкой по подсистеме LeftController и выбора Subsystem Parameters, который откроется, подсистема LeftController блокируют диалоговое окно.

open_system('rtwdemo_preprocessor_subsys/LeftController');

Подсистема LeftController блокируется, диалоговое окно создает ассоциацию между Линейными и Нелинейными подсистемами с двумя Simulink. Различные объекты, LINEAR и NONLINEAR, это существует в базовом рабочем пространстве. Эти объекты имеют свойство под названием Condition, выражение, которое оценивает к булеву значению и определяет активную различную дочернюю подсистему (Линейный или Нелинейный). Условие также показывают в диалоговом окне блока подсистемы. В этом примере, условиях LINEAR и NONLINEAR 'VSSMODE == 0' и 'VSSMODE == 1', соответственно.

В этом примере Simulink.Variant object s создается в базовом рабочем пространстве.

LINEAR = Simulink.Variant;
LINEAR.Condition = 'VSSMODE==0';
NONLINEAR = Simulink.Variant;
NONLINEAR.Condition = 'VSSMODE==1';

Определение различной контрольной переменной

Различные объекты позволяют вам снова использовать произвольно комплексные условия в модели. Несколько Различных блоков Subsystem могут использовать тот же Simulink. Различные объекты, позволяя вам переключить активацию выбора как набор. Можно переключить набор до симуляции путем изменения значения VSSMODE в среде MATLAB или при компиляции сгенерированного кода, как объяснено в следующем разделе. В этом примере LeftController и RightController ссылаются на те же различные объекты, так, чтобы можно было переключить их одновременно.

Нелинейные подсистемы контроллера реализуют гистерезис, в то время как линейные подсистемы контроллера действуют как простые фильтры lowpass. Откройте подсистему для левого канала. Подсистемы для правильного канала подобны.

Сгенерированный код получает доступ к различной контрольной переменной VSSMODE как пользовательский макрос. В этом примере, rtwdemo_importedmacros.h предоставления VSSMODE. В среде MATLAB вы задаете VSSMODE использование Simulink.Parameter объект. Его значение будет проигнорировано при генерации кода включая условные выражения препроцессора. Однако значение используется в симуляции. Устаревший заголовочный файл задает значение макроса, который будет использоваться при компиляции сгенерированного кода, который в конечном счете активирует один из двух заданных вариантов во встроенном исполняемом файле.

Различные контрольные переменные могут быть заданы как Simulink.Parameter объекты с одним из этих классов памяти:

  • Define или ImportedDefine с заданным заголовочным файлом

  • CompilerFlag

  • SystemConstant (AUTOSAR)

  • Пользовательский пользовательский класс памяти, который задает данные как макрос в заданном заголовочном файле

VSSMODE = Simulink.Parameter;
VSSMODE.Value = 1;
VSSMODE.DataType = 'int32';
VSSMODE.CoderInfo.StorageClass = 'Custom';
VSSMODE.CoderInfo.CustomStorageClass = 'ImportedDefine';
VSSMODE.CoderInfo.CustomAttributes.HeaderFile = 'rtwdemo_importedmacros.h';

Симуляция модели с различными вариантами

Поскольку вы устанавливаете значение VSSMODE к 1, модель использует нелинейные контроллеры в процессе моделирования.

sim('rtwdemo_preprocessor_subsys')
youtnl = yout;

Если вы изменяете значение VSSMODE к 0, модель использует линейные контроллеры в процессе моделирования.

VSSMODE.Value = int32(0);
sim('rtwdemo_preprocessor_subsys')
youtl = yout;

Можно построить и сравнить ответ линейных и нелинейных контроллеров:

figure('Tag','CloseMe');
plot(tout, youtnl.signals(1).values, 'r-', tout, youtl.signals(1).values, 'b-')
title('Response of Left Channel Linear and Nonlinear Controllers');
ylabel('Response');
xlabel('Time (seconds)');
legend('nonlinear','linear')
axis([0 100 -0.8 0.8]);

Используя условные выражения препроцессора C

Эта модель в качестве примера была сконфигурирована, чтобы сгенерировать условные выражения препроцессора C. Чтобы сгенерировать код для модели, во вкладке C Code панели инструментов выбирают Build.

Чтобы активировать генерацию кода условных выражений препроцессора, проверяйте, верны ли следующие условия:

  • Выберите цель Embedded Coder® в Генерации кода> Системный конечный файл в диалоговом окне Configuration Parameters

  • В Различном диалоговом окне параметра блока Subsystem Выберите опцию, чтобы Анализировать весь выбор во время обновления, схематически изображают и генерируют условные выражения препроцессора.

В этом примере сгенерированный код включает ссылки на Simulink. Вариант возражает LINEAR и NONLINEAR, а также определения макросов, соответствующих тем вариантам. Те определения зависят от значения VSSMODE, который предоставляется во внешнем заголовочном файле rtwdemo_importedmacros.h. Активный вариант определяется при помощи условных выражений препроцессора (#if) на макросах (#define) LINEAR и NONLINEAR.

Макросы LINEAR и NONLINEAR заданы в сгенерированном rtwdemo_preprocessor_subsys_types.hЗаголовочный файл:

  #ifndef LINEAR
  #define LINEAR      (VSSMODE == 0)
  #endif
  #ifndef NONLINEAR
  #define NONLINEAR   (VSSMODE == 1)
  #endif

В сгенерированном коде код, связанный с вариантами, охраняют условные выражения препроцессора C. Например, в rtwdemo_preprocessor_subsys.c, вызовы шага и функций инициализации каждого варианта условно скомпилированы:

  /* Outputs for atomic SubSystem: '<Root>/LeftController' */
  #if LINEAR
      /* Output and update for atomic system: '<S1>/Linear' */
  #elif NONLINEAR
      /* Output and update for atomic system: '<S1>/Nonlinear' */
  #endif

Закройте модель, фигуру и переменные рабочей области из примера.

bdclose('rtwdemo_preprocessor_subsys')
close(findobj(0,'Tag','CloseMe'));
clear LINEAR NONLINEAR VSSMODE
clear tout yout youtl youtnl