Чтобы упростить интегрирование кода С++, сгенерированного Simulink® приложения, компоненты и подсистемы с внешними кодами C or C++, сконфигурируйте пользовательский интерфейс класса C++. Когда вы генерируете код С++ из модели, модель появляется как класс, элементы данных появляются как члены класса, а функции модели появляются как методы класса в сгенерированном коде. Конфигурирование интерфейса класса C++ позволяет вам настроить следующие аспекты сгенерированного кода С++:
Информация о классе - Имя класса и пространство имен
Информация о члене класса - Доступ и видимость члена класса
Информация о методе класса - Имена и аргументы метода класса
Настроенный интерфейс класса C++ позволяет сгенерированным классам соответствовать определенным стандартам кода или требованиям к интерфейсам, так что сгенерированный код может компилироваться и интегрироваться в большие архитектуры с минимальной индивидуальной настройкой после постгенерации.
Интерактивный рабочий процесс обеспечивает быстрое интуитивно понятное и полное строение пользовательского интерфейса класса C++ с помощью инструментов, доступных непосредственно с вкладки C++ Code. На вкладке можно кликнуть Code Interface и получить доступ к диалоговому окну строения Class Name & Namespace и редактору Code Mappings (с Property Inspector), чтобы сконфигурировать интерфейс.
Для интерактивной настройки пользовательского интерфейса C++:
Откройте окружение для настройки пользовательского интерфейса класса C++:
Откройте Embedded Coder® В галерее Apps нажмите Embedded Coder.
Установите язык на C++. На вкладке C++ Code нажмите Output и выберите Embedded C++ Code.
Установите параметры конфигурации модели. Чтобы открыть диалоговое окно Параметры конфигурации, на вкладке C++ Code, нажмите Settings и выберите C/C++ Code generation settings. Эти параметры конфигурируют поведение генерации кода всей модели. Чтобы сконфигурировать параметры, характерные для генерации пользовательского интерфейса класса C++, можно задать эти параметры (расположенные на панели Interface):
Параметр конфигурации | Описание |
---|---|
Code interface packaging | Выбор языка выхода для сгенерированного кода. Для получения дополнительной информации см. раздел «Упаковка интерфейса кода». |
Multi-instance code error diagnostic | Задает уровень серьезности для диагностики, отображаемой, когда модель нарушает требования к генерации кода мультиобразцов. Для получения дополнительной информации см. Раздел Диагностика ошибок кода мультиобразцов. |
Remove error status field in real-time model data structure | Определяет, следует ли опускать поле состояния ошибки из сгенерированной структуры данных модели реального времени |
Include model types in model class | Задает включение определений типов модели в пространство имен классов модели. Для получения дополнительной информации смотрите Включить типы модели в класс модели. |
Параметры интерфейса, которые связаны, но реже используются, появляются под Advanced parameters.
Параметр конфигурации | Описание |
---|---|
Terminate function required | Определяет, нужно ли генерировать |
Combine signal/state structures | Определяет, объединять ли глобальные блочные сигналы и данные о глобальном состоянии в одну структуру данных в сгенерированном коде. Для получения дополнительной информации смотрите Объединить структуры сигнала/состояния. |
Generate destructor | Определяет, нужно ли генерировать деструктор для класса модели C++. Для получения дополнительной информации см. Раздел «Генерация деструктора». |
Use dynamic memory allocation for model block instantiation | Задает выделение памяти для иерархий модели. Для получения дополнительной информации смотрите Использовать динамическое выделение памяти для создания экземпляров блоков модели. |
Сконфигурируйте имя класса и пространство имен. Когда вы генерируете код С++ из модели, эта модель появляется как класс в сгенерированном коде. Чтобы упростить интегрирование и соответствовать требованиям кода и интерфейса, можно настроить сгенерированное имя класса. Вы также можете масштабировать сгенерированный код и предотвращать столкновения символов в проекте, задавая пространство имен для сгенерированного класса. В смоделированных системах, созданных как иерархия модели, можно задать разное пространство имен для каждой модели в иерархии.
Сгенерированный интерфейс класса C++, объявленный в файле заголовка модели, включает настраиваемое имя и пространство имен:
// File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { // public data and function members public: // private data and function members private: }; }
Чтобы сконфигурировать имя класса и пространство имен для пользовательского интерфейса класса C++:
На вкладке C++ Code нажмите Code Interface и выберите Class Name & Namespace.
Чтобы сконфигурировать имя класса, измените поле C++ Class Name.
Чтобы сконфигурировать пространство имен класса, измените поле C++ Class Namespace.
Нажмите OK. Валидация выполняется в интерактивном режиме с предупреждениями о полях, которые предупреждают вас, если вы вводите недопустимое имя или пространство имен.
Настройте видимость и доступ членов класса. Когда вы генерируете код С++ из модели, элементы данных Simulink появляются как члены класса в сгенерированном коде. Чтобы настроить инкапсуляцию данных класса в соответствии со стандартами кода, безопасности или требованиями эффективности, можно настроить видимость и доступ сгенерированных членов класса. Элементы данных Simulink могут быть сгруппированы в следующие категории элементов моделирования:
Категория элемента модели | Описание |
---|---|
Inports | Входные порты данных корневого уровня модели, такие как блоки Inport и In Bus Element. Для получения дополнительной информации смотрите Inport. |
Вспомогательные порты | Выходные порты данных корневого уровня модели, такие как блоки Outport и Out Bus Element. Для получения дополнительной информации смотрите Outport. |
Аргументы параметра модели | Переменные рабочей области, которые появляются как представители данных класса образца (нестатические). |
Параметры модели | Переменные рабочей области, которые являются общими для образцов класса модели, которые генерируются как представители данных статического класса. |
Сигналы, состояния и внутренние данные | Элементы данных, которые являются внутренними для модели, такие как выходные сигналы блоков, дискретные состояния блока, хранилища данных и сигналы пересечения нулем. |
Для каждой категории элемента модели можно сконфигурировать видимость данных, чтобы управлять модификатором доступа (спецификатором доступа) сгенерированных членов класса. Каждая опция и ее влияние на сгенерированный интерфейс класса C++, объявленный в заголовочном файле модели, описывается следующим образом:
Опции видимости данных | Описание |
---|---|
общественность | Если вы конфигурируете элементы данных как
File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: // example inport ExtU rtU; // example outport ExtY rtY; // example block signals and states DW rtDW; private: … }; } |
защищенный | Если вы конфигурируете элементы данных как File: rtwdemo_cpp_workflow.h // Class declaration for model example_model namespace CustomizedNamespace { class customized_ModelClass { public: protected: // example inport ExtU rtU; // example outport ExtY rtY; // example block signals and states DW rtDW; private: … }; } |
частный | Если вы конфигурируете элементы как File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: private: // example inport ExtU rtU; // example outport ExtY rtY; // example block signals and states DW rtDW; }; } |
Отдельные аргументы (только аргументы параметра модели) | Если вы конфигурируете элементы данных как File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: // model step function void step1(real_T rty_engineState, const real_T modelParameterArgument); private: … }; } |
После установки видимости данных категории элемента модели можно сконфигурировать метод доступа к модели, чтобы определить, как генерируются методы get и set для элементов данных. Это строение управляет тем, как код приложения может просматривать и изменять данные члена класса. Каждая опция и ее влияние на сгенерированный интерфейс класса C++, объявленный в заголовочном файле модели, описывается следующим образом:
Опции метода доступа к представителю | Описание |
---|---|
Метод | Если вы конфигурируете входные порты как File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: // example inport void setInport(real_T localArgInput); // example outport real_T getOutport() const; // example of model parameter arguments configured with // ‘DataAccess’ ‘Direct' real_T const & getInstP() const; // example of model parameter arguments configured with // ‘DataAccess’ ‘Pointer’ // real_T const * getInstP() const; // example Block parameters get and set methods const rtwdemo_cppclass_workflowModelClass::rtwdemo_cppclass_workflow_P & getBlockParameters() const; void setBlockParameters(const rtwdemo_cppclass_workflow_P *prtwdemo_cppclass_workflowrtrtP); // example Block states get and set methods const rtwdemo_cppclass_workflowModelClass::rtwdemo_cppclass_workflow_DW & getDWork() const; void setDWork(const rtwdemo_cppclass_workflow_DW *prtwdemo_cppclass_workflowrtDW); private: … }; } |
Встроенный метод | Если вы конфигурируете входные порты как File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: // example inport set method void setkeyState(real_T localArgInput) { rtU.keyState = localArgInput; } // example outport get method const real_T* getengineState() const { return rtY.engineState; } // example Block parameters get and set method const rtwdemo_cppclass_workflowModelClass::rtwdemo_cppclass_workflow_P & getBlockParameters() const { return rtwdemo_cppclass_workflowrtrtP; } void setBlockParameters(const rtwdemo_cppclass_workflow_P *prtwdemo_cppclass_workflowrtrtP) { rtwdemo_cppclass_workflowrtrtP = *prtwdemo_cppclass_workflowrtrtP; } // example Block states get and set methods const rtwdemo_cppclass_workflowModelClass::rtwdemo_cppclass_workflow_DW & getDWork() const { return rtwdemo_cppclass_workflowrtDW; } void setDWork(const rtwdemo_cppclass_workflow_DW *prtwdemo_cppclass_workflowrtDW) { rtwdemo_cppclass_workflowrtDW = *prtwdemo_cppclass_workflowrtDW; } private: … }; } |
Структурный метод | Если вы конфигурируете входные порты следующим File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { // public data and function members public: // example inport void setExternalInputs(const ExtU_demoMethodScheduledModel_T * pExtU_demoMethodScheduledModel_T); // example outport const myNamespace::myModelClass::ExtY_demoMethodScheduledModel_T & getExternalOutputs() const; // Other model element categories may not be configured as ‘Structure-based method’ private: … }; } |
Метод, основанный на встроенной структуре | Если вы конфигурируете входные порты следующим File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: // example inport void setExternalInputs(const ExtU_demoMethodScheduledModel_T * pExtU_demoMethodScheduledModel_T) { demoMethodScheduledModelWithR_U = *pExtU_demoMethodScheduledModel_T; } // example outport const myNamespace::myModelClass::ExtY_demoMethodScheduledModel_T & getExternalOutputs() const { return demoMethodScheduledModelWithR_Y; } // Other model element categories may not be configured as ‘Inlined structure-based method’ private: … }; } |
Ничего | Если вы конфигурируете доступ к категории элемента модели следующим File: rtwdemo_cpp_workflow.h // External inputs (root inport signals with default storage) struct ExtU { real_T keyState; // '<Root>/keyState' }; // External outputs (root outports fed by signals with default storage) struct ExtY { real_T engineState[3]; // '<Root>/engineState' real_T cycleTime; // '<Root>/cycleTime' }; namespace CustomizedNamespace { class customized_ModelClass { public: // External inputs ExtU rtU; // External outputs ExtY rtY; private: … }; } |
Для каждой категории элемента модели описаны допустимые комбинации видимости данных и метода доступа представителей:
Категория элемента модели | Видимость данных | Метод доступа к представителю |
---|---|---|
Inports | частный | Метод Встроенный метод Структурный метод Метод, основанный на встроенной структуре |
общественность | Ничего Метод Встроенный метод Структурный метод Метод, основанный на встроенной структуре | |
Вспомогательные порты | частный | Метод Встроенный метод Структурный метод Метод, основанный на встроенной структуре |
общественность | Ничего Метод Встроенный метод Структурный метод Метод, основанный на встроенной структуре | |
Аргументы параметра модели | Отдельные аргументы | Ничего |
частный | Метод Встроенный метод | |
Параметры модели | частный | Ничего Метод Встроенный метод |
общественность | Ничего Метод Встроенный метод | |
Сигналы, состояния и внутренние данные | частный | Ничего Метод Встроенный метод |
общественность | Ничего Метод Встроенный метод |
Чтобы сконфигурировать члены класса настраиваемого интерфейса класса C++:
Откройте редактор Отображения. На вкладке C++ Code нажмите Code Interface и выберите Code Mappings.
Откройте панель Data. В редакторе Отображения перейдите на вкладку Data.
Настройте видимость. Чтобы сконфигурировать видимость категории элементов данных Simulink в сгенерированном коде, из столбца Data Visibility выберите спецификатор доступа из заданных опций. Опции варьируются в зависимости от Model Element Category.
Сконфигурируйте доступ. Чтобы сконфигурировать доступ к категории элементов данных Simulink в сгенерированном коде, из столбца Member Access Method выберите, как сгенерировать get и задать методы из заданных опций. Опции варьируются в зависимости от Model Element Category и выбранных Data Visibility.
Сконфигурируйте имена и аргументы метода класса. Когда вы генерируете код С++ из модели, функции модели появляются как методы класса в сгенерированном коде. Для интеграции с требованиями внешнего кода или интерфейса можно настроить имя сгенерированных методов класса. Кроме того, для периодических функций базовой скорости и функций Simulink, можно сконфигурировать имя, порядок и идентификатор сгенерированных аргументов.
Сгенерированные методы класса называются методами точки входа и являются местоположениями в коде, где происходит передача управления программой (выполнение). Методы точки входа варьируются в зависимости от типа модели Simulink и могут быть сгруппированы в следующие типы:
Тип модели | Тип функции модели | Описание | Имя функции модели | Имя ожидаемого метода |
---|---|---|---|---|
Экспорты функций | Экспортированная функция | Экспортированная функция для подсистемы. | ExportedFunction: , где - имя вызова функции Inport блока в модели | или (если указано) |
Функция Simulink | Экспортированная функция для блока Simulink Function. | Функция Simulink: где - имя блока Simulink Function в модели | для блока глобального Simulink Function или для масштабированного блока Simulink Function | |
Экспорты функций или скоростей | Инициализируйте функцию | Код инициализации для модели. В начале кода приложения вызовите функцию один раз. Не используйте эту функцию, чтобы сбросить структуру данных модели реального времени ( | Initialize |
|
Функция разбиения | Для раздела модели выводите и обновляйте код. Выбран параметр конфигурации <reservedrangesplaceholder0> модели (по умолчанию). | Раздел: , где - раздел, который был создан явно из блока в модели и показан в Simulink ® Редактор (например, P1) | , где однозначно определяет функцию, сгенерированную для одного из периодов дискретизации модели | |
Периодическая функция многозадачности | Для блоков в модели на основе скорости, настроенной для многозадачности, выхода и обновления кода. Генератор кода производит функцию для каждого периода дискретизации. Выбран параметр конфигурации <reservedrangesplaceholder0> модели (по умолчанию). | Периодический: где - аннотация, которая соответствует периоду шага расчета для периодической или непрерывной скорости многозадачной модели (для примера, D1) | , где однозначно определяет функцию, сгенерированную для одного из периодов дискретизации модели | |
Периодическая однозадачная функция | Для блоков в модели на основе скорости, сконфигурированной для однозадачного, выхода и обновления кода. Выбран параметр конфигурации <reservedrangesplaceholder0> модели (по умолчанию). | Periodic |
| |
Функция сброса | Если модель включает блок Reset Function, сбросьте сгенерированный код. Чтобы сбросить условия или состояние, вызовите функцию из кода приложения. | Сброс: где - имя функции сброса в модели |
| |
Функция завершения | Код для выключения системы. Для моделей, основанных на ERT, можно подавить генерацию этой функции, очистив параметр конфигурации <reservedrangesplaceholder0> модели (по умолчанию ). | Terminate |
|
Сгенерированный интерфейс класса C++, объявленный в файле заголовка модели, включает имя функции и индивидуальных настроек аргументов в сгенерированные методы точки входа:
File: rtwdemo_cpp_workflow.h namespace CustomizedNamespace { class customized_ModelClass { public: // model initialize function- customized name void customized_initialize(); // model step function- customized name & arguments void customized_step(customArg1, const* customArg2); // model terminate function- customized name void customized_terminate(); // Constructor customized_ModelClass(); // Destructor ~customized_ModelClass(); private: … }; }
Откройте редактор Отображения. На вкладке C++ Code нажмите Code Interface и выберите Code Mappings.
Откройте панель Functions. В редакторе Отображения перейдите на вкладку Functions. Чтобы просмотреть полный список функций точки входа для вашей модели, нажмите кнопку Update Diagram.
Сконфигурируйте имена методов.
Чтобы сконфигурировать имя метода точки входа в сгенерированном коде, из столбца Method Name щелкните и непосредственно отредактируйте электронную таблицу. Вы можете ввести пользовательское имя или использовать параметры формата идентификатора для управления динамически сгенерированным именем. Дополнительные сведения о параметрах формата идентификатора см. в разделе Управление форматом идентификатора.
Проверьте имя в столбце Method Preview.
Сконфигурируйте аргументы метода. Для периодических функций базовой скорости и функций Simulink можно сконфигурировать имя, порядок и идентификаторы аргументов метода.
Чтобы сконфигурировать аргументы периодической функции базовой скорости:
Откройте диалоговое окно Step Function Interface. В редакторе Code Mappings, на вкладке Functions, в столбце Method Preview, щелкните гиперссылку предварительного просмотра метода периодической функции базовой скорости:
В диалоговом окне выберите Configure arguments for Step function prototype и нажмите Get default. Это действие запускает представление аргументов метода.
Чтобы изменить порядок аргументов, щелкните и перетащите строки аргументов в средстве просмотра.
Чтобы изменить идентификатор, в C++ Type Qualifier столбце выберите соответствующий идентификатор из выпадающего списка:
Опция идентификатора | Предварительный просмотр |
---|---|
Значение (только для входных портов) | myPeriodicFunction (argInport) |
Ссылка Const (только входные порты) | myPeriodicFunction (const & argInport) |
Указатель на Const | myPeriodicFunction (const * argInport) |
Указатель | myPeriodicFunction (* argInport) |
Const Pointer to const | myPeriodicFunction (const * const argInport) |
Чтобы изменить имя аргумента, в C++ Identifier Name столбце щелкните и непосредственно отредактируйте имя. Вы можете ввести пользовательское имя или использовать параметры формата идентификатора для управления динамически сгенерированным именем. Дополнительные сведения о параметрах формата идентификатора см. в разделе Управление форматом идентификатора.
Если вы вводите то же имя для аргумента inport и аргумента outport, inport и outport появляются как один параметр в сгенерированном методе. Для примера, если вы задаете inport следующим argInport
и аргумент в виде argOutport
, сгенерированный метод будет:
myStepFunction(argInport, argOutport);
Если вы задаете аргумент inport следующим argIO
и аргумент в виде argIO
, сгенерированный метод будет:
myStepFunction(argIO);
Чтобы проверить выбор аргументов, нажмите Validate.
Чтобы применить изменения и выйти из диалогового окна, нажмите кнопку OK.
Чтобы сконфигурировать аргументы функции Simulink:
Откройте диалоговое окно Simulink Function Interface. В редакторе Отображения, на вкладке Functions, в столбце Method Preview, щелкните гиперссылку предварительного просмотра метода функции Simulink:
Чтобы изменить возвращаемый аргумент, выберите опцию возвращаемого аргумента из выпадающего списка C/C++ return argument.
Чтобы изменить порядок аргументов, щелкните и перетащите строки аргументов в средстве просмотра.
Чтобы изменить идентификатор, в C++ Type Qualifier столбце выберите идентификатор из выпадающего списка:
Опция идентификатора | Предварительный просмотр |
---|---|
Автомобиль | mySimulinkFunction (argInport) |
Ссылка на Const | mySimulinkFunction (const & argInport) |
Указатель на Const | mySimulinkFunction (const * argInport) |
Указатель | mySimulinkFunction (* argInport) |
Const Pointer to const | mySimulinkFunction (const * const argInport) |
Чтобы изменить имя аргумента, в C++ Identifier name столбце щелкните и непосредственно отредактируйте имя. Вы можете ввести пользовательское имя или использовать параметры формата идентификатора для управления динамически сгенерированным именем. Дополнительные сведения о параметрах формата идентификатора см. в разделе Управление форматом идентификатора.
Чтобы проверить изменения аргументов функции Simulink, проверьте поле Simulink function prototype, чтобы просмотреть ожидаемый прототип метода.
Чтобы применить изменения и выйти из диалогового окна, нажмите кнопку OK.
Сгенерируйте пользовательский интерфейс класса C++ путем генерации кода из модели. Чтобы проверить свои строения интерфейса класса C++, создайте модель и просмотрите сгенерированные представления класса, члена класса и метода класса.
Сгенерируйте код. Чтобы сгенерировать интерфейс класса C++, на вкладке C++ Code, нажмите Build.
Просмотрите код. Чтобы просмотреть сгенерированный код, на вкладке нажмите View Code. Сгенерированный код появляется рядом с моделью в рабочем пространстве модели.
Итерация. Если сгенерированный интерфейс не соответствует требованиям кода, выполните настройку строения до тех пор, пока требования не будут удовлетворены.
Если сгенерированное представление сгенерированного кода не соответствует вашим требованиям, перенастройте интерфейс и сгенерируйте код снова, пока не будут удовлетворены требования генерации кода. Для получения руководства по пониманию сгенерированного кода смотрите Анализ интерфейса сгенерированного кода.
Поддержка параметров конкретного экземпляра - можно использовать аргументы параметра модели, чтобы сконфигурировать переменные рабочей области, которые были заданы в качестве аргументов. Можно настроить эти аргументы как частные представители вашего класса или как отдельные аргументы, заданные вне класса. Чтобы сконфигурировать в классе, можно задать частную видимость данных и сконфигурировать генерацию методов get и set. Можно также сконфигурировать значения членов класса, определенные в классе (в Property Inspector установите Data Access равными Direct
) или переданные по ссылке через конструктор классов (в Property Inspector установите Data Access равным Pointer
). Настройка доступа к данным поддерживается для сборок верхней модели. Для сборок образца модели код генерируется как ссылки в классе модели. Чтобы сконфигурировать параметры конкретного экземпляра вне класса, установите видимость данных на отдельные аргументы.
Ограничения параметров для конкретного экземпляра включают:
MATLAB® переменные, отмеченные как аргументы модели, не могут быть сконфигурированы как частные члены класса.
Аргументы параметра модели не поддерживаются сборками с щелчком правой кнопкой мыши.
Поведение генерации кода интерфейса - стиль аргументов ввода-вывода спецификации шагового метода поддерживает односкоростные модели и мультирациональные однозадачные модели. Многозадачные модели не поддерживаются. Кроме того, интерфейс инкапсуляции C++ не является интерфейсом по умолчанию, значение игнорируется для параметра Pass fixed-size scalar root inputs by value for code generation.
Stateflow® факторы - Если у вас есть лицензия Stateflow, для диаграммы Stateflow, которая находится в корневой модели, настроенной на использование I/O arguments step method
спецификация функции, и которая использует корневое значение входного порта модели или вызывает подсистему, которая использует корневое значение входного порта модели, выполните одно из следующих действий, чтобы сгенерировать код:
На диаграмме Stateflow снимите флажок Execute (enter) Chart At Initialization.
Вставьте блок Simulink Signal Conversion сразу после корневого входного порта. В диалоговом окне Signal Conversion параметры блоков выберите Исключить этот блок из оптимизации 'Block reduction'.
Simscape™ факторов - Если значение входного порта корня модели соединяется с блоком Simscape, вставьте блок Simulink Signal Conversion между корневым входным портом и блоком преобразования Simscape. В диалоговом окне Signal Conversion параметры блоков выберите Исключить этот блок из оптимизации 'Block reduction'.
Ссылочная модель Факторов - при создании ссылочной модели, которая сконфигурирована для генерации интерфейса класса C++:
Не используйте интерфейс класса C++ в случаях, когда ссылочная модель не может иметь объединенную функцию вывода/обновления. Случаи включают модель, которая имеет непрерывный шаг расчета или сохраняет состояния.
Не используйте виртуальные шины как входы или выходы к ссылочной модели, когда ссылочная модель использует метод шага ввода-вывода аргументов. Когда сигналы шины пересекают контуры модели-ссылки, либо используйте невиртуальные шины, либо используйте метод Default step.