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

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

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

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

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

Когда вы генерируете код, можно только сгенерировать код для активного варианта. Можно также сгенерировать код для всех вариантов Различного блока Subsystem и задержать выбор активного варианта, пока не пора скомпилировать сгенерированный код.

Определение вариантов для блока 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. Различные объекты создаются в базовом рабочем пространстве.

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

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

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

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

Сгенерированный код получает доступ к различной контрольной переменной 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. Можно сгенерировать код для модели путем выбора Code> C/C ++ Code> Build Model.

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

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

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

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

Отчет генерации кода Simulink® Coder™ содержит разделы в отчете Вариантов Кода, выделенном подсистемам, которым управляли вариантами условные выражения препроцессора.

В этом примере сгенерированный код включает ссылки на 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