Программное обеспечение Embedded Coder® предоставляет возможность диалогового окна Subsystem Parameters, Function with separate data, который позволяет вам генерировать модульный функциональный код для невиртуальных подсистем, включая атомарные подсистемы и условно выполняемые подсистемы.
По умолчанию сгенерированный код для невиртуальной подсистемы не разделяет внутренние данные подсистемы из данных его родительской модели Simulink®. Это может мешать прослеживать и тестировать код, особенно для подсистем одноразового использования. Кроме того, в больших моделях, содержащих невиртуальные подсистемы, структуры данных могут стать большими и потенциально трудными скомпилировать.
Function with separate data позволяет вам генерировать код функции подсистемы, в котором внутренние данные для невиртуальной подсистемы разделяются от своей родительской модели и принадлежат подсистеме. Структура данных подсистемы объявляется независимо от структур данных родительской модели. Подсистема с отдельными данными имеет свою собственную структуру данных блока I/O и DWork
. В результате сгенерированный код для подсистемы легче проследить и протестировать. Разделение данных также имеет тенденцию уменьшать максимальный размер структур глобальных данных в модели, потому что они разделены в несколько структур данных.
Использовать параметр Function with separate data,
Ваша модель должна использовать основанный на ERT системный конечный файл (требует лицензии Embedded Coder).
Ваша подсистема должна быть сконфигурирована, чтобы быть атомарной или условно выполненной. Для получения дополнительной информации смотрите Системы и Подсистемы (Simulink).
Ваша подсистема должна использовать установку Nonreusable function
для Code Generation> Function packaging.
Чтобы сконфигурировать вашу подсистему для генерации модульного функционального кода, вы вызываете диалоговое окно Subsystem Parameters и делаете ряд выборов, чтобы отобразить и включить опцию Function with separate data. Смотрите Конфигурируют Подсистему для Генерации Модульного Функционального Кода и Модульного Функционального Кода для Невиртуальных Подсистем для деталей. Для ограничений, которые применяются, смотрите Невиртуальную Подсистему Модульные Функциональные Ограничения Кода.
Для получения дополнительной информации о генерации кода для атомарных подсистем, смотрите Генерацию Управления разделами Функций для Подсистем (Simulink Coder) и Сгенерируйте Код и Исполняемые файлы для Отдельных Подсистем (Simulink Coder).
Этот раздел обобщает шаги, чтобы сконфигурировать невиртуальную подсистему в модели Simulink для модульной функциональной генерации кода.
Проверьте, что модель Simulink, содержащая подсистему, использует основанный на ERT системный конечный файл (см. параметр System target file на панели Code Generation диалогового окна Configuration Parameters).
В вашей модели Simulink выберите подсистему, для которой вы хотите сгенерировать модульный функциональный код и открыть диалоговое окно Subsystem Parameters (например, щелкните правой кнопкой по подсистеме и выберите Block Parameters (Subsystem)). Диалоговое окно для атомарной подсистемы показывают ниже. (В диалоговом окне для условно выполняемой подсистемы опция диалогового окна отображается серым Treat as atomic unit, и можно пропустить Шаг 3.)
Если опция диалогового окна Subsystem Parameters, Treat as atomic unit доступен для выбора, но не выбранный, подсистема, не является ни атомарной, ни условно выполнена. Выберите опцию Treat as atomic unit, который включает Function packaging на вкладке Code Generation. Выберите вкладку Code Generation.
Для параметра Function packaging выберите значение Nonreusable function
. После того, как вы сделаете этот выбор, опция Function with separate data отображена.
Прежде чем вы сгенерируете невиртуальный код функции подсистемы с выбранной опцией Function with separate data, вы можете хотеть сгенерировать функциональный код с невыбранной опцией и сохранить сгенерированный функциональный .c
и файлы .h
в отдельной директории для более позднего сравнения.
Выберите опцию Function with separate data. После того, как вы сделаете этот выбор, дополнительные параметры конфигурации отображены.
Чтобы управлять именованием подсистемы функционируют и файлы подсистемы в сгенерированном коде, можно изменить параметры подсистемы Function name options и File name options.
Чтобы сохранить ваши установки параметров подсистемы и выйти из диалогового окна, нажмите OK.
Это завершает настройку подсистемы для генерации модульного функционального кода. Можно теперь сгенерировать код для подсистемы и исследовать сгенерированные файлы, включая функциональный .c
и файлы с именем .h
согласно спецификациям параметра подсистемы. Для получения дополнительной информации о генерации кода для невиртуальных подсистем смотрите Генерацию Управления Функций для Подсистем (Simulink Coder). Для примеров сгенерированного кода функции подсистемы см. Модульный Функциональный Код для Невиртуальных Подсистем.
Чтобы проиллюстрировать выбор опции Function with separate data для невиртуальной подсистемы, следующая процедура генерирует код функции атомарной подсистемы с и без выбранной опции и сравнивает результаты.
Откройте MATLAB® и откройте модель rtwdemo_atomic
с помощью команды MATLAB rtwdemo_atomic
.
Исследуйте модель Simulink. Эта модель показывает, как сохранить контур виртуальной подсистемы. Путем выбора опции Параметров Подсистемы Treat as atomic unit вы гарантируете, что код для той подсистемы выполняется как атомарный модуль. Когда система отмечена как атомарная, можно задать, как подсистема представлена в коде с опцией Параметров Подсистемы Code Generation Function Packaging. Можно указать, что подсистема переводится в один из этих типов реализации:
Встроенный:
Встройте код подсистемы на сайтах вызова
Функция:
пустая/пустая функция с вводом-выводом и внутренними данными в структуре глобальных данных
Reusable Function
: повторно используемая функция с данными, переданными в как часть аргументов функции
'auto':
Позвольте генератору кода оптимизировать реализацию на основе контекста
Дважды кликните подсистему SS1 и исследуйте содержимое.
Закройте окно подсистемы, когда вы будете закончены.
Щелкните правой кнопкой по подсистеме SS1, выберите Block Parameters (Subsystem) из контекстного меню и исследуйте настройки. Simulink и генератор кода могут избежать "искусственных" алгебраических циклов, когда подсистема сделана атомарной с опцией подсистемы Minimize algebraic loop occurrences.
Закройте диалоговое окно Block Parameters, когда вы будете закончены.
Измените System target file для режима от grt.tlc
до ert.tlc
. Выберите вкладку Configuration Parameters> Code Generation и задайте ert.tlc
для параметра System target file. Нажмите OK дважды, чтобы подтвердить изменение. Используя ERT цель предоставляет больше возможностей генерации кода для атомарной подсистемы.
Создайте вариант rtwdemo_atomic
, который иллюстрирует функциональный код без разделения данных.
В модели rtwdemo_atomic
щелкните правой кнопкой по подсистеме SS1 и выберите Block Parameters (Subsystem). В диалоговом окне Subsystem Parameters, которое появляется, проверьте это
На вкладке the Main выбран Treat as atomic unit
На вкладке Code Generation User specified
выбран для Function name options
На вкладке Code Generation myfun
задан для Function name
В диалоговом окне Subsystem Parameters, на вкладке Code Generation проверяют это
Nonreusable function
выбран для параметра Function packaging. После этого выбора появляются дополнительные параметры и опции.
Use function name
выбран для параметра File name options. Этот выбор является дополнительным, но упрощает более позднюю задачу сравнения кода, заставляя код функции атомарной подсистемы быть сгенерированным в файлы myfun.c
и myfun.h
.
Не выбирайте опцию Function with separate data. Нажмите Apply, чтобы применить изменения и нажать OK, чтобы выйти из диалогового окна.
Сохраните этот образцовый вариант в персональный рабочий каталог, например, rtwdemo_atomic1
в d:/atomic
.
Создайте вариант rtwdemo_atomic
, который иллюстрирует функциональный код с разделением данных.
В модели rtwdemo_atomic1
(или rtwdemo_atomic
с повторно примененным шагом 3), щелкните правой кнопкой по подсистеме SS1 и выберите Block Parameters (Subsystem). В диалоговом окне Subsystem Parameters проверьте это
На вкладке Main выбран Treat as atomic unit
На вкладке Code Generation Function
выбран для Function packaging
На вкладке Code Generation User specified
выбран для Function name options
На вкладке Code Generation myfun
задан для Function name
На вкладке Code Generation Use function name
задан для File name options
В диалоговом окне Subsystem Parameters, на вкладке Code Generation, выбирают опцию Function with separate data. Нажмите Apply, чтобы применить изменение и нажать OK, чтобы выйти из диалогового окна.
Сохраните этот образцовый вариант, с помощью другого имени, чем первый вариант, к персональному рабочему каталогу, например, rtwdemo_atomic2
в d:/atomic
.
Сгенерируйте код для каждой модели, rtwdemo_atomic1
и rtwdemo_atomic2
.
В директориях сгенерированного кода сравните
/model.c
.h
и myfun.c
/.h
файлы, сгенерированные для этих двух моделей. Для обсуждения сравнения кода см. Различия в Файле H для Невиртуального Разделения Данных о Функции Подсистемы и H различия в файле для невиртуального разделения данных о функции подсистемыC различия в файле для невиртуального разделения данных о функции подсистемы.
В этом примере нет существенных различий в сгенерированных вариантах ert_main.c
,
, model_private.h
или model_types.h
rtwtypes.h
.
Различия между файлами H, сгенерированными для rtwdemo_atomic1
и rtwdemo_atomic2
, помогают проиллюстрировать выбор опции Function with separate data для невиртуальных подсистем.
Выбор Function with separate data заставляет typedef
s для данных о подсистеме быть сгенерированным в файле myfun.h
для rtwdemo_atomic2
:
/* Block signals for system '<Root>/SS1' */ typedef struct { real_T Integrator; /* '<S1>/Integrator' */ } rtB_myfun; /* Block states (auto storage) for system '<Root>/SS1' */ typedef struct { real_T Integrator_DSTATE; /* '<S1>/Integrator' */ } rtDW_myfun;
В отличие от этого, для rtwdemo_atomic1
, typedef
s для данных о подсистеме принадлежит модели и появляется в rtwdemo_atomic1.h
:
/* Block signals (auto storage) */ typedef struct { ... real_T Integrator; /* '<S1>/Integrator' */ } BlockIO_rtwdemo_atomic1; /* Block states (auto storage) for system '<Root>' */ typedef struct { real_T Integrator_DSTATE; /* '<S1>/Integrator' */ } D_Work_rtwdemo_atomic1;
Выбор Function with separate data генерирует следующие внешние объявления в файле myfun.h
для rtwdemo_atomic2
:
/* Extern declarations of internal data for 'system '<Root>/SS1'' */ extern rtB_myfun rtwdemo_atomic2_myfunB; extern rtDW_myfun rtwdemo_atomic2_myfunDW; extern void myfun_initialize(void);
В отличие от этого, сгенерированный код для rtwdemo_atomic1
содержит внешние объявления образцового уровня для BlockIO
подсистемы и данных D_Work
в rtwdemo_atomic1.h
:
/* Block signals (auto storage) */ extern BlockIO_rtwdemo_atomic1 rtwdemo_atomic1_B; /* Block states (auto storage) */ extern D_Work_rtwdemo_atomic1 rtwdemo_atomic1_DWork;
Различия между файлами C, сгенерированными для rtwdemo_atomic1
и rtwdemo_atomic2
, иллюстрируют выбор опции Function with separate data для невиртуальных подсистем.
Выбор причин Function with separate data отдельная подсистема инициализирует функцию, myfun_initialize
, чтобы быть сгенерированным в файле myfun.c
для rtwdemo_atomic2
:
void myfun_initialize(void) { { ((real_T*)&rtwdemo_atomic2_myfunB.Integrator)[0] = 0.0; } rtwdemo_atomic2_myfunDW.Integrator_DSTATE = 0.0; }
Подсистема инициализирует функцию в myfun.c
, вызывается моделью, инициализируют функцию в rtwdemo_atomic2.c
:
/* Model initialize function */ void rtwdemo_atomic2_initialize(void) { ... /* Initialize subsystem data */ myfun_initialize(); }
В отличие от этого, для rtwdemo_atomic1
, данные о подсистеме инициализируются моделью, инициализируют функцию в rtwdemo_atomic1.c
:
/* Model initialize function */ void rtwdemo_atomic1_initialize(void) { ... /* block I/O */ { ... ((real_T*)&rtwdemo_atomic1_B.Integrator)[0] = 0.0; } /* states (dwork) */ rtwdemo_atomic1_DWork.Integrator_DSTATE = 0.0; ... }
Выбор Function with separate data генерирует следующие объявления в файле myfun.c
для rtwdemo_atomic2
:
/* Declare variables for internal data of system '<Root>/SS1' */ rtB_myfun rtwdemo_atomic2_myfunB; rtDW_myfun rtwdemo_atomic2_myfunDW;
В отличие от этого, сгенерированный код для rtwdemo_atomic1
содержит объявления образцового уровня для BlockIO
подсистемы и данных D_Work
в rtwdemo_atomic1.c
:
/* Block signals (auto storage) */ BlockIO_rtwdemo_atomic1 rtwdemo_atomic1_B; /* Block states (auto storage) */ D_Work_rtwdemo_atomic1 rtwdemo_atomic1_DWork;
Выбор Function with separate data генерирует идентификатор, называющий, который отражает ориентацию подсистемы элементов данных. Заметьте ссылки на данные о подсистеме в функциях подсистемы, таких как myfun
и myfun_update
или в функции
моделиmodel_step
. Например, сравните этот код от
myfun
для rtwdemo_atomic2
/* DiscreteIntegrator: '<S1>/Integrator' */ rtwdemo_atomic2_myfunB.Integrator = rtwdemo_atomic2_myfunDW.Integrator_DSTATE;
к соответствующему коду от myfun
для rtwdemo_atomic1
.
/* DiscreteIntegrator: '<S1>/Integrator' */ rtwdemo_atomic1_B.Integrator = rtwdemo_atomic1_DWork.Integrator_DSTATE;
Объединенные подсистемы в модели с именами функций и файлами.
Узнать, как к:
Задайте функцию и имена файлов в сгенерированном коде.
Идентифицируйте части сгенерированного кода, которые требуются для интегрирования.
Сгенерируйте код для атомарных подсистем.
Идентифицируйте данные, которые требуются, чтобы выполнять сгенерированную функцию.
Для получения информации о модели в качестве примера и других примерах в этом ряду, смотрите, Генерируют код С от Алгоритма управления для Встраиваемой системы.
Атомарные и виртуальные подсистемы
Модели в качестве примера в Генерируют код С от Алгоритма управления для Встраиваемой системы и Конфигурируют Интерфейс Данных в виртуальных подсистемах использования Сгенерированного кода. Виртуальные подсистемы визуально организуют блоки, но не влияют на образцовые Атомарные подсистемы функциональности, оценивают все включенные блоки как модуль. С атомарными подсистемами можно указать дополнительную информацию разделения функции. В модели атомарные подсистемы появляются с полужирной границей.
Просмотрите изменения в архитектуре модели
Откройте модель в качестве примера, rtwdemo_PCG_Eval_P3
.
Сохраните копию модели к вашей текущей папке.
Этот пример показывает, как заменить виртуальные подсистемы на подсистемы вызова функции. Function-Call подсистемы:
Атомарные подсистемы
Позвольте вам управлять порядком выполнения подсистемы
Выполнитесь, когда вызов функции будет сигнализировать о триггерах
Путем управления порядком выполнения подсистем можно совпадать с моделью существующей системе, которая имеет определенный порядок выполнения.
Фигура идентифицирует подсистемы вызова функции (1) PI_ctrl_1
, PI_ctrl_2
и Pos_Command_Arbitration
.
Эта версия модели содержит новую подсистему Execution_Order_Control
(2), который содержит график Stateflow®, который моделирует функциональность вызова планировщика. Подсистема управляет порядком выполнения подсистем вызова функции через сигналы вызова функции (3). Позже в этом примере, вы исследуете, как изменение порядка выполнения может изменить результаты симуляции.
Эта версия модели содержит новые блоки Преобразования Сигнала (4) при выходных параметрах контроллеров PI. С этими дополнительными блоками на месте, генератор кода может сгенерировать одну повторно используемую функцию для контроллеров PI.
Местоположение функции управления и размещение файла в сгенерированном коде
В Генерируют код С от Алгоритма управления для Встраиваемой системы и Конфигурируют Интерфейс Данных в Сгенерированном коде, генератор кода создает одну функцию model_step
, которая содержит код алгоритма управления. Однако много приложений требуют большего уровня управления размещением файла функций. Путем изменения параметров атомарных подсистем можно задать несколько функций в одной модели.
Данные показывают параметры подсистемы для PI_ctrl_1
.
Обработайте как атомарный модуль
Включает другие подменю. Для атомарных подсистем этот параметр автоматически выбран и отключен.
'SampleTime'
Задает шаг расчета для выполнения. Не доступный для подсистем вызова функций.
Функция упаковочные опции
Автоматический - Определяет, как подсистема появляется в сгенерированном коде. Это значение является значением по умолчанию.
Встроенный - Места код подсистемы встраивают с остальной частью типового кодекса.
Функция - Генерирует код для подсистемы как функция.
Допускающая повторное использование функция - Генерирует допускающую повторное использование (повторно используемую) функцию от подсистемы. Функция передает все входные и выходные данные через формальные параметры. Функция непосредственно не получает доступ к глобальным переменным.
Опции имени функции
Выбор Function или Reusable function для Функциональной упаковки включает опции имени функции.
Автоматический - Определяет функцию.
Используйте имя подсистемы - Основы функция на имени подсистемы.
Пользователь задал - Применяет заданное имя файла.
Опции имени файла
Выбор Function или Reusable function для Функциональной упаковки включает опции имени файла.
Автоматический - Места, которые функциональное определение в модуле сгенерировало для родительской системы, или, если образцовый корень является родительским элементом в model.c
.
Используйте имя подсистемы - Генерирует отдельный файл. Имя файла является именем блока библиотеки или подсистемы.
Используйте имя функции - Генерирует отдельный файл. Имя файла является именем, которое вы задаете с опциями Имени функции.
Пользователь задал - Применяет заданное, уникальное имя файла.
Функция с отдельными данными
Enabled, когда вы упаковка функции множества, чтобы Функционировать. Когда выбрано, генератор кода разделяет внутренние данные подсистемы (например, сигналы) от данных родительской модели. Подсистема владеет этими отдельными данными.
Сгенерируйте повторно используемый код
Embedded Coder® поддерживает повторно используемый код. Повторно используемый код является допускающей повторное использование стандартной программой программирования, которую несколько программ могут использовать одновременно. Повторно используемый код используется в операционных системах и другом системном программном обеспечении, которое использует многопоточность, чтобы обработать параллельные события. Повторно используемый код не поддерживает данные состояния, таким образом, нет никаких персистентных переменных в функции. Программы вызова поддерживают переменные состояния и должны передать данные состояния в функцию. Многий пользователь или процессы могут совместно использовать одну копию повторно используемой функции.
Чтобы сгенерировать повторно используемый код, необходимо сначала задать подсистему как допускающую повторное использование путем конфигурирования упаковки Функции параметра подсистемы.
В некоторых случаях настройка модели предотвращает повторно используемый код. Таблица приводит распространенные проблемы.
Cause Solution
Subsystem output feeds global signal Add a Signal Conversion block between the data subsystem and the global signal.
Generated function receives data Select Configuration Parameters > (formal parameters) through pointers Model Referencing > Pass fixed-size scalar root inputs by value for code generation.
Subsystem uses global signal data Use a port to pass the global data in and out in internal algorithm of the subsystem.
Используйте маску, чтобы передать значения параметров в подсистему библиотеки
Чтобы задать алгоритмические данные о параметре (такие как усиление или коэффициент) вне осциллографа допускающего повторное использование блока библиотеки или подсистемы, можно применить маску к блоку или подсистеме и создать параметр маски. Можно затем задать различное значение параметров для каждого экземпляра блока или подсистемы. Каждый параметр маски появляется в сгенерированном коде как формальный параметр повторно используемой функции.
В этой версии модели подсистемы маскируются PI_ctrl_1
и PI_ctrl_2
. В каждой маске значения P
и усилений I
установлены объектами данных, такими как I_Gain_2
и P_Gain_2
.
Сгенерируйте код для атомарной подсистемы
В Генерируют код С от Алгоритма управления для Встраиваемой системы и Конфигурируют Интерфейс Данных в Сгенерированном коде, вы генерируете код на корневом уровне модели. Также можно создать определенную подсистему.
Чтобы инициировать сборку подсистемы, используйте контекстное меню. Можно выбрать из этих опций:
Подсистема сборки: Обрабатывает подсистему как отдельный режим и создает полный набор источника C файлы и заголовочные файлы. Эта опция не поддерживает подсистемы вызова функций.
Сгенерируйте S-функцию: Генерирует код С для подсистемы и создает обертку S-функции. Можно затем моделировать код в исходной модели. Эта опция не поддерживает подсистемы вызова функций.
Экспорты функций: Генерирует код С без кода планирования, который идет с опцией Подсистемы Сборки. Используйте эту опцию, чтобы создать подсистемы, которые используют триггеры, такие как подсистемы вызова функций.
Исследуйте сгенерированный код
Этот пример сравнивает файлы, которые сгенерированы для полной системной сборки с файлами, которые сгенерированы для экспортируемых функций. Вы также исследуете, как данные маскированные появляются в коде.
Запустите скрипт сборки для этих трех опций. Затем исследуйте сгенерированные файлы путем нажатия на гиперссылки.
rtwdemo_PCG_Eval_P3.c
Полная сборка: Да, Ступенчатая функция
PI_ctrl_1: нет
Pos_Command_Arbitration: нет
PI_ctrl_1.c
Полная сборка: нет
PI_ctrl_1: Да, Триггерная функция
Pos_Command_Arbitration: нет
Pos_Command_Arbitration.c
Полная сборка: нет
PI_ctrl_1: нет
Pos_Command_Arbitration: да, Init и функция
PI_Ctrl_Reusable.c
ert_main.c
eval_data.c
(1) eval_data.c
имеет различное содержимое в сборках полного и экспорта функций. Полная сборка включает все параметры, которые использует модель. Экспорт функций содержит только переменные, которые использует подсистема.
Данные маскированные в сгенерированном коде
В файле rtwdemo_PCG_Eval_P3.c
сайты вызова повторно используемой функции используют объекты данных P_Gain
, I_Gain
, P_Gain_2
и I_Gain_2
в качестве аргументов.
Эффект порядка выполнения на результатах симуляции
По умолчанию Simulink® выполняет подсистемы в этом порядке:
PI_ctrl_1
PI_ctrl_2
Pos_Command_Arbitration
В данном примере можно задать один из двух альтернативных порядков выполнения. Можно затем использовать тестовую обвязку, чтобы наблюдать эффект порядка выполнения на результатах симуляции. Execution_Order_Control
подсистемы имеет две настройки, которые управляют порядком выполнения. Чтобы выбрать настройку, используйте контекстное меню подсистемы.
Измените порядок выполнения и наблюдайте результаты.
Результаты симуляции (положение дросселя в зависимости от времени) отличаются немного в зависимости от порядка выполнения. Вы видите различие наиболее ясно, когда запрос дросселя изменяется.
Для следующего примера в этом ряду смотрите Вызов Внешний код С из Типового кодекса и Сгенерированного кода.
Невиртуальная опция подсистемы Function with separate data имеет следующие ограничения:
Опция Function with separate data доступна только в основанных на ERT моделях Simulink (требует лицензии Embedded Coder).
Невиртуальная подсистема, к которой применяется опция, не может иметь нескольких шагов расчета или времена непрерывной выборки; то есть, подсистема должна быть односкоростной с дискретным шагом расчета.
Невиртуальная подсистема не может содержать непрерывные состояния.
Невиртуальная подсистема не может позывные выходной функции.
Невиртуальная подсистема не может содержать невстроенные S-функции.
Сгенерированные файлы для невиртуальной подсистемы сошлются на заголовочные файлы всей модели, такие как
и model.h
.model_private.h
Опция Function with separate data несовместима с опцией Classic call interface, расположенной на Code Generation> панель Interface диалогового окна Configuration Parameters. Выбор обоих генерирует ошибку.
Опция Function with separate data несовместима с установкой Code interface packaging с Reusable function
(Code Generation> панель Interface). Выбор обоих генерирует ошибку.
Когда вы выбираете Function with separate data для подсистемы, модель, которая содержит подсистему, не может содержать Блок памяти Хранилища данных с выбранным Share across model instances. Смотрите Память Хранилища данных.