Сгенерируйте повторно используемый код от подсистем

Можно уменьшать объем кода, который генератор кода производит для идентичных атомарных подсистем путем конфигурирования подсистем как допускающих повторное использование функций, которые передают данные в качестве аргументов (например, rtB_* для ввода и вывода блока, rtDW_* для непрерывных состояний и rtP_* для параметров). По умолчанию генератор кода производит код подсистемы, который связывается с другим кодом путем совместного использования доступа к структурам глобальных данных, которые находятся в общей памяти. Передающими данными в качестве аргументов код может быть повторно используем. Каждый экземпляр кода обеспечивает свои собственные уникальные данные.

Чтобы сконфигурировать подсистемы для возможности многократного использования и повторной входимости, сконфигурируйте маску и параметры блоков идентичных подсистем тот же путь. Генератор кода выполняет контрольную сумму, чтобы определить, идентичны ли подсистемы и является ли код допускающим повторное использование. Если код является допускающим повторное использование, генератор кода производит один экземпляр допускающего повторное использование, повторно используемого функционального кода.

Сконфигурировать параметры блоков подсистемы:

  1. Если подсистема является виртуальной, выберите Обработку параметров блоков как атомарный модуль, чтобы включить функции упаковочные параметры.

  2. Установите Функцию параметров блоков, группирующую на Reusable function. Генератор кода производит отдельную функцию с аргументами для каждой подсистемы. Выбор Reusable function также включает дополнительные параметры, которые можно использовать, чтобы управлять именами функции и файлом, который генератор кода производит для кода подсистемы.

  3. Выберите значение для опций Имени функции параметров блоков. Чтобы сгенерировать допускающий повторное использование, повторно используемый код, задайте ту же установку для идентичных подсистем.

    • Чтобы позволить генератору кода определить имя функции, выберите Auto.

    • Чтобы использовать имя подсистемы или, для библиотечного блока, имени библиотечного блока, выбирают Use subsystem name.

    • Чтобы отобразить Имя функции параметров блоков и ввести уникальное, допустимое имя функции C/C++, выберите User specified.

    Если несколько экземпляров идентичной подсистемы существуют в иерархии модели - ссылки, выберите Auto.

    Если вы используете Embedded Coder®, можно использовать управления форматом идентификатора. Смотрите Управление форматом Идентификатора.

  4. Установите опции Имени файла. Чтобы сгенерировать допускающий повторное использование, повторно используемый код, задайте ту же установку для идентичных подсистем.

    • Чтобы позволить генератору кода определить именование файла выбирают Auto.

    • Чтобы использовать имя подсистемы или, для библиотечного блока, имя библиотечного блока выбирает Use subsystem name.

    • Чтобы использовать имя функции, как задано параметрами блоков Function name options выбирают Use function name.

    • Отобразить Имя файла параметров блоков (никакое расширение) и ввести имя файла, исключая расширение (например, .c или .cpp) выберите User specified.

    Другие факторы:

    • Если несколько экземпляров идентичной подсистемы существуют в иерархии модели - ссылки, выберите Auto.

    • Если генератор кода не генерирует отдельный файл для подсистемы, функциональный код помещается в файл, сгенерированный от родительской системы подсистемы. Если родительский элемент является самой моделью, генератор кода помещает функциональный код в modelC или model.cpp.

    • Если ваш сгенерированный код находится под системой контроля версий, задайте значение кроме Auto. Эта спецификация препятствует тому, чтобы сгенерированное имя файла изменилось, когда вы изменяете и восстанавливаете модель.

    • Если вы выбираете Use subsystem name, генератор кода искажает имя файла подсистемы, если модель содержит блоки Model, или если цель модели-ссылки генерируется для модели. В этих ситуациях генератор кода использует имя файла modelsubsystem.c.

Если подсистема A имеет параметр маски b и K и подсистема B имеет параметры маски c и K, повторное использование кода не возможно. Генератор кода производит отдельные функции для подсистем A и B. Если вы устанавливаете параметры блоков для подсистем A и B по-другому, повторное использование кода не возможно.

Функциональное повторное использование в сгенерированном коде

В этом примере показано, как сконфигурировать атомарную подсистему для генерации повторно используемого кода. Чтобы указать, что код, сгенерированный для подсистемы, выполняется, как, атомарный модуль, на диалоговом окне Block Parameters, выбирает Treat как атомарный модульный параметр. Тот параметр включает Функции Упаковочный параметр на вкладке Code Generation. Функция Упаковочный параметр имеет эти четыре настройки:

  • Inline: Встройте код подсистемы

  • Nonreusable function: Функция с вводом-выводом, переданным как глобальные данные

  • Reusable function: Функция с вводом-выводом, переданным как аргументы функции

  • Auto: Позвольте Simulink Coder оптимизировать на основе контекста

Reusable function и Auto настройки разрешают генератору кода снова использовать код подсистемы. Reusable function и Nonreusable function настройки включают опции Имени функции, Имя функции и параметры опций Имени файла.

Если у вас есть лицензия Embedded Coder, можно сконфигурировать подсистему одноразового использования, чтобы принять аргументы.

Модель в качестве примера

rtwdemo_ssreuse модель содержит две идентичных подсистемы, SS1 и SS2. Для этих подсистем Функция упаковочный параметр устанавливается на Reusable function, и параметром Имени функции является myfun. Подсистемы параметрируются замаскированные подсистемы. Чтобы видеть содержимое подсистем маскированных, щелкните правой кнопкой по блокам подсистемы и выберите Mask> Look Under Mask.

model = 'rtwdemo_ssreuse';
open_system(model);

Сгенерируйте и смотрите код

Создайте временную папку для сборки и инспекционного процесса. Откройте приложение Embedded Coder или Simulink Coder. Затем сгенерируйте и смотрите код.

currentDir=pwd;
[~,cgDir]=rtwdemodir();
slbuild(model)
### Starting build procedure for: rtwdemo_ssreuse
### Successful completion of build procedure for: rtwdemo_ssreuse

Build Summary

Top model targets built:

Model            Action                       Rebuild Reason                                    
================================================================================================
rtwdemo_ssreuse  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 7.9372s
cfile=fullfile(cgDir, 'rtwdemo_ssreuse_grt_rtw', 'rtwdemo_ssreuse.c');
rtwdemodbtype(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_ssreuse_step(void)
{
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */

  /* Inport: '<Root>/In1' incorporates:
   *  Inport: '<Root>/In2'
   */
  myfun(rtwdemo_ssreuse_U.In1, rtwdemo_ssreuse_U.In2, rtwdemo_ssreuse_P.T1Data,
        rtwdemo_ssreuse_P.T1Break, &rtwdemo_ssreuse_B.SS1);

  /* End of Outputs for SubSystem: '<Root>/SS1' */

  /* Outport: '<Root>/Out1' */
  rtwdemo_ssreuse_Y.Out1 = rtwdemo_ssreuse_B.SS1.LookupTable;

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */

  /* Inport: '<Root>/In1' incorporates:
   *  Inport: '<Root>/In2'
   */
  myfun(rtwdemo_ssreuse_U.In1, rtwdemo_ssreuse_U.In2, rtwdemo_ssreuse_P.T2Data,
        rtwdemo_ssreuse_P.T2Break, &rtwdemo_ssreuse_B.SS2);

  /* End of Outputs for SubSystem: '<Root>/SS2' */

  /* Outport: '<Root>/Out2' */
  rtwdemo_ssreuse_Y.Out2 = rtwdemo_ssreuse_B.SS2.LookupTable;
}

В ступенчатой функции модели существует два вызова допускающей повторное использование функции, myfun. Параметры маски, T1Break, T1Data, T2Break, и T2Data, аргументы функции.

Измените Функцию Упаковочный параметр в Inline.

set_param('rtwdemo_ssreuse/SS1','RTWSystemCode','Inline')
set_param('rtwdemo_ssreuse/SS2','RTWSystemCode','Inline')

Сгенерируйте и смотрите код.

slbuild(model)
### Starting build procedure for: rtwdemo_ssreuse
### Successful completion of build procedure for: rtwdemo_ssreuse

Build Summary

Top model targets built:

Model            Action                       Rebuild Reason                   
===============================================================================
rtwdemo_ssreuse  Code generated and compiled  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 6.3775s
cfile=fullfile(cgDir, 'rtwdemo_ssreuse_grt_rtw', 'rtwdemo_ssreuse.c');
rtwdemodbtype(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_ssreuse_step(void)
{
  real_T Out1_tmp;

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */
  /* Sum: '<S1>/Sum' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   *  Sum: '<S2>/Sum'
   */
  Out1_tmp = rtwdemo_ssreuse_U.In1 + rtwdemo_ssreuse_U.In2;

  /* End of Outputs for SubSystem: '<Root>/SS2' */

  /* Outport: '<Root>/Out1' incorporates:
   *  Lookup_n-D: '<S1>/Lookup Table'
   *  Sum: '<S1>/Sum'
   */
  rtwdemo_ssreuse_Y.Out1 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P.T1Break,
    rtwdemo_ssreuse_P.T1Data, 10U);

  /* End of Outputs for SubSystem: '<Root>/SS1' */

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */
  /* Outport: '<Root>/Out2' incorporates:
   *  Lookup_n-D: '<S2>/Lookup Table'
   */
  rtwdemo_ssreuse_Y.Out2 = look1_binlx(Out1_tmp, rtwdemo_ssreuse_P.T2Break,
    rtwdemo_ssreuse_P.T2Data, 10U);

  /* End of Outputs for SubSystem: '<Root>/SS2' */
}

В ступенчатой функции модели встраивается код подсистемы.

Измените Функцию Упаковочный параметр в Nonreusable function. Для SS2 , измените параметр Имени функции в myfun2.

set_param('rtwdemo_ssreuse/SS1','RTWSystemCode','Nonreusable function')
set_param('rtwdemo_ssreuse/SS2','RTWSystemCode','Nonreusable function')
set_param('rtwdemo_ssreuse/SS2','RTWFcnName','myfun2')

Сгенерируйте и смотрите код.

slbuild(model)
### Starting build procedure for: rtwdemo_ssreuse
### Successful completion of build procedure for: rtwdemo_ssreuse

Build Summary

Top model targets built:

Model            Action                       Rebuild Reason                   
===============================================================================
rtwdemo_ssreuse  Code generated and compiled  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 6.3979s
cfile=fullfile(cgDir, 'rtwdemo_ssreuse_grt_rtw', 'rtwdemo_ssreuse.c');
rtwdemodbtype(cfile, '/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_ssreuse_step(void)
{
  /* Outputs for Atomic SubSystem: '<Root>/SS1' */
  myfun();

  /* End of Outputs for SubSystem: '<Root>/SS1' */

  /* Outputs for Atomic SubSystem: '<Root>/SS2' */
  myfun2();

  /* End of Outputs for SubSystem: '<Root>/SS2' */
}

Ступенчатая функция модели содержит вызовы функций myfun и myfun2. Эти функции имеют пустой пустотой интерфейс.

Измените Функцию Упаковочный параметр в Auto.

set_param('rtwdemo_ssreuse/SS1','RTWSystemCode','Auto')
set_param('rtwdemo_ssreuse/SS2','RTWSystemCode','Auto')

Для auto установка, Simulink Coder выбирает оптимальный формат. Для этой модели оптимальный формат является допускающей повторное использование функцией.

Закройте модель и вымойтесь.

bdclose(model)
rtwdemoclean;
cd(currentDir)

Ограничения

  • Генератор кода использует контрольную сумму, чтобы определить, являются ли подсистемы идентичными и допускающими повторное использование. Код подсистемы не снова используется если:

    • В блоках и объектах данных, вы используете символы, чтобы задать размерности.

    • Порт имеет различные шаги расчета, типы данных, сложность, состояние системы координат или размерности через подсистемы.

    • Выход подсистемы отмечен как глобальный сигнал.

    • Подсистемы содержат идентичные блоки с различными именами или установками параметров.

    • Выход подсистемы соединяется с блоком Merge, и выход блока Merge сконфигурирован с пользовательским классом памяти, который реализован в коде С как неадресуемая память (например, BitField).

    • Вход подсистемы является нескалярным и сконфигурирован с пользовательским классом памяти, который реализован в коде С как неадресуемая память.

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

    • Подсистема вызова функций использует параметры маски, когда вы устанавливаете поведение параметра Значения по умолчанию параметра конфигурации модели на Tunable. Чтобы снова использовать подсистему вызова функций маскированную, поместите его в новой атомарной подсистеме без маски. Затем переместите блок Trigger из подсистемы маскированной в атомарную подсистему.

    • Блок в подсистеме использует partially tunable expression. Некоторые частично настраиваемые выражения отключают повторное использование кода.

      Частично настраиваемые выражения являются выражениями, которые содержат одну или несколько настраиваемых переменных и выражение, которое не является настраиваемым. Например, предположите, что вы создаете настраиваемую переменную K со значением 15.23 и настраиваемая переменная P со значением [5;7;9]. Выражение K+P' частично настраиваемое выражение потому что выражение P' не является настраиваемым. Для получения дополнительной информации о настраиваемых ограничениях выражения, смотрите Настраиваемые Ограничения Выражения.

  • Для подсистем, которые содержат Блоки s-function, которые являются допускающими повторное использование, блоки должны удовлетворить требования, перечисленные в S-функциях для Повторного использования кода.

  • Если вы выбираете Reusable function, и генератор кода решает, что вы не можете снова использовать код для подсистемы, это генерирует отдельную функцию, которая не снова используется. Отчет генерации кода может показать, что отдельная функция является допускающей повторное использование, даже если только одна подсистема использует его. Если вы предпочитаете, чтобы генератор кода встроил код подсистемы в таких случаях (а не развернутый как функции), упаковка функции множества к Auto.

  • Если допускающая повторное использование подсистема использует разделяемое локальное хранилище данных, и вы конфигурируете отображение значения по умолчанию для элементов данных модели, оставляете отображение класса памяти по умолчанию для категории набор Shared local data stores к Default.

  • Использование этих блоков в подсистеме может препятствовать тому, чтобы код подсистемы был снова использован:

    • Определите объем блоков (с включенной регистрацией данных)

    • Блоки s-function, которым не удается соответствовать определенным критериям (см. S-функции для Повторного использования кода),

    • С блоками Файла (с включенной регистрацией данных)

    • С блоками Рабочей области (с включенной регистрацией данных)

  • Для допускающих повторное использование подсистем библиотеки (подсистемы, совместно использованные через образцы модели), генератор кода использует контрольную сумму, чтобы определить, идентичны ли подсистемы. Генератор кода помещает допускающий повторное использование код подсистемы библиотеки в разделяемую сервисную папку, и повторно используемый код независим от сгенерированного кода топ-модели или образца модели. Например, допускающий повторное использование код подсистемы библиотеки не включает modelH или model_types.h.

    Повторно используемый код, который генератор кода помещает в разделяемую сервисную папку и зависит от типового кодекса, не компилирует. Если генератор кода решает, что допускающий повторное использование код подсистемы библиотеки зависит от типового кодекса, допускающий повторное использование код подсистемы не помещается в разделяемую сервисную папку. Генератор кода производит код, который зависит от типового кодекса когда допускающая повторное использование подсистема библиотеки:

    • Содержит блок, который использует связанную со временем функциональность, такую как блок Step, или непрерывное время или многоскоростные блоки.

    • Содержит один или несколько блоков Model.

    • Содержит подсистему, которая не встраивается или допускающая повторное использование подсистема библиотеки.

    • Содержит сигнал или параметр с классом памяти, который помещает объявление данных в файл под model_ert_rtw (Например, ExportedGlobal класс памяти помещает данные в model.c)

    • Содержит пользовательский класс памяти как Перечисление, Simulink. Сигнал, Simulink. Параметр, и так далее где Data Scope не установлен в Exported. Генератор кода может поместить определение типа в model_types.h.

    • Различная подсистема, которая генерирует условные выражения препроцессора. Генератор кода помещает директивы препроцессору, которые задают различные объекты в model_types.h

  • Вы не можете снова использовать подсистему, если существует несколько экземпляров той же подсистемы в модели, и одна подсистема питается блоком Constant, но другая подсистема не. Чтобы работать вокруг этого ограничения, вставьте блок Signal Conversion перед подсистемами.

  • Две допускающих повторное использование подсистемы, которые имеют различные контрольные суммы, не могут совместно использовать ту же функцию в сгенерированном коде. Когда вы задаете то же имя функции для обеих подсистем в Block Parameters (Subsystem)> Code Generation> Function name:

    • Если подсистемы соединяются библиотекой, генератор кода искажает имя функции, чтобы сгенерировать уникальные имена функций. Генератор кода использует правила именования подсистемы, чтобы сгенерировать имена функций.

    • Если подсистемы не соединяются библиотекой, генератор кода выдает ошибку.

Предыдущие ограничения также запрашивают основанную на библиотеке генерацию кода. Для получения дополнительной информации смотрите Основанную на библиотеке Генерацию кода для Допускающих повторное использование Подсистем Библиотеки.

Похожие темы