Библиотечная генерация кода предоставляет способ генерации кода для набора переиспользуемых компонентов, которые модели могут использовать совместно. Для каждой переиспользуемой библиотечной подсистемы верхнего уровня задается набор функциональных интерфейсов, которые блокируют интерфейс подсистемы. Интерфейс функции состоит из подсистемы входа и выхода настроек параметров блоков и параметров конфигурации модели.
Функциональные интерфейсы являются независимыми моделями, которые вы сохраняете с помощью сопутствующей библиотеки. Перед генерацией кода для модели, содержащей образцы повторно используемой подсистемы библиотеки, вы генерируете код для библиотеки. Библиотечная генерация кода делает библиотеку владельцем кода. Чтобы сделать отдельные модели владельцем кода, можно сгенерировать код для переиспользуемых подсистем библиотеки в общую папку утилит. Для получения дополнительной информации смотрите Сгенерировать переиспользуемый код из библиотечных подсистем, общих для моделей.
Чтобы показать, как использовать функциональные интерфейсы и генерацию кода на основе библиотеки, этот пример использует модель rtwdemo_libcodegen_mdl
и библиотечные rtwdemo_libcodegen_lib
. Модель содержит два образцов переиспользуемой подсистемы библиотеки Atomic_Controller
. Для Atomic_Controller_Single
, тип данных входного сигнала single
. Для Atomic_Controller_Double
, тип данных входного сигнала double
. Чтобы открыть файлы модели и библиотеки, в командной строке MATLAB введите:
rtwdemo_libcodegen_mdl rtwdemo_libcodegen_lib
Чтобы выполнить генерацию кода на основе библиотеки, необходимо сконфигурировать подсистему библиотеки как переиспользуемую.
В диалоговом окне параметров Subsystem блоков выберите Treat as atomic unit.
В диалоговом окне Параметры блока Subsystem, на вкладке Code Generation, установите параметр Function packaging на Reusable function
.
Каждый функциональный интерфейс, соответствующий одной и той же переиспользуемой библиотечной подсистеме, должен иметь уникальное имя. Чтобы задать уникальное имя, выполните следующие действия:
В диалоговом окне параметров Subsystem блоков, на вкладке Code Generation, установите параметр Function name options равным User specified
.
Для параметра Function name задайте $R
и $N
лексемы. The $R
лексема представляет имя интерфейса функции. The $N
лексема представляет имя подсистемы.
В диалоговом окне Create Function Interface для параметра Name задайте имя, описывающее контекст.
Установите параметр File name option равным Auto
или Use function name
.
Модель rtwdemo_libcodegen_mdl
содержит два образцов переиспользуемой подсистемы библиотеки Atomic_Controller
. Каждый образец представляет интерфейс функции. В библиотеке rtwdemo_libcodegen_lib
щелкните правой кнопкой мыши значок в нижней правой части переиспользуемой подсистемы библиотеки Atomic_Controller
. Выберите Manage Function Interfaces. Два функциональных интерфейса имеют имена Single
и Double
потому что Atomic_Controller
принимает single
и double
типы данных.
Чтобы создать функциональные интерфейсы, в библиотеке щелкните правой кнопкой мыши подсистему и выберите C/C++ Function Interfaces > Create Function Interface. Задайте Name интерфейса функции.
Затем, чтобы сконфигурировать интерфейсы функции, выберите один из следующих методов.
Чтобы создать функциональные интерфейсы из связанных образцов повторно используемой подсистемы библиотеки:
В библиотеке щелкните правой кнопкой мыши значок на самой нижней правой стороне переиспользуемой подсистемы библиотеки и выберите Create Function Interface. В диалоговом окне выберите параметр Specify library block instance to create function interface.
Для параметра Simulink model with instance выберите модель, которая содержит подсистему.
Для параметра Library block instance name выберите подсистему.
Нажмите OK и закройте диалоговое окно Create Function Interface.
Для каждого интерфейса функции повторите предыдущие шаги.
Примечание
Можно создать интерфейс функции из модели, которая содержит образец связанной повторно используемой подсистемы библиотеки. Вы должны быть в ракурсе Кода. Чтобы открыть перспективу код, из меню apps, выберите Embedded Coder. Если подсистема имеет функциональные интерфейсы, в правом нижнем углу подсистемы появляется значок. Щелкните значок правой кнопкой мыши и выберите Create Function Interface. Если подсистема не имеет интерфейсов функций, щелкните правой кнопкой мыши подсистему и выберите C/C++ Function Interfaces > Create Function Interface.
Чтобы экспортировать и сконфигурировать интерфейс функции как независимую модель:
В библиотеке щелкните правой кнопкой мыши значок на самой нижней правой стороне переиспользуемой подсистемы библиотеки и выберите Manage Function Interfaces.
Выберите интерфейсы функций, которые вы хотите изменить.
Нажмите Export.
В Save As окне укажите текущую рабочую папку. Экспортированный интерфейс функции является файлом .slx, который имеет имя интерфейса функции плюс приложение _export
.
Откройте экспортированную модель. Внесите изменения в настройки параметров входных и выходных блоков подсистемы и настройки параметров конфигурации модели. Сохраните модель.
В библиотеке щелкните правой кнопкой мыши переиспользуемую подсистему библиотеки и выберите C/C++ Function Interfaces > Create Function Interface. Задайте Name интерфейса функции.
Для параметра Simulink model with instance выберите экспортированную модель, которая находится в текущей рабочей папке.
Для параметра Library block instance name выберите подсистему.
Нажмите OK и закройте диалоговое окно Create Function Interface.
В библиотеке щелкните правой кнопкой мыши значок на самой нижней правой стороне подсистемы и выберите Configure Function Interface.
В диалоговом окне Configure Function Interface для входных и выходных параметров подсистемы задайте значения для параметров Data Type, Dimensions и Signal Type. Чтобы изменить настройки входных и выходных параметров другой подсистемы, следуйте методу экспорта в предыдущем разделе.
Чтобы изменить параметры конфигурации модели, нажмите кнопку переключения передач и внесите изменения. Нажмите Apply. Закройте диалоговое окно Параметры конфигурации.
Чтобы заменить интерфейс функции существующим интерфейсом из модели образца, выберите Regenerate Using Instance.
Задайте значения для параметров Simulink model with instance и Library block instance name. Нажмите Regenerate.
Нажмите Apply и закройте диалоговое окно Configure Function Interface.
После того, как вы задаете функциональные интерфейсы для подсистем в вашей библиотеке, сгенерируйте код для библиотеки. Перед генерацией кода для вашей модели необходимо сгенерировать код для библиотеки. Генератор кода упакует код библиотеки как отдельную библиотеку на C. Сгенерированный код для библиотеки находится в папке, соответствующей вашим аппаратным параметрам (для примера, IntelWin64). Папка кода библиотеки имеет то же имя, что и библиотека, и должна быть на том же иерархическом уровне, что и библиотека.
Чтобы сгенерировать код, проверьте, что библиотека разблокирована. Откройте приложение Embedded Coder и нажмите Build Library.
Когда вы генерируете код для rtwdemo_libcodegen_lib
библиотека, rtwdemo_libcodegen_lib
папка содержит эти .c
и .h
файлы:
Atomic_Controller_Single.h
Atomic_Controller_Single.c
Atomic_Controller_Double.h
Atomic_Controller_Double.c
Эти имена функций являются показательными для $N$R
спецификация параметров Function name options и Function name в диалоговом окне Параметры блока Subsystem.
A _shared
папка содержит код для общих утилит (для примера, утилит с фиксированной точкой и Интерполяционной таблицей и Блоками MATLAB function), дополнительных файлов и экспортированных параметров и типов.
Когда вы генерируете код для модели, которая содержит образец повторно используемой библиотечной подсистемы, которая может использовать предварительно генерированный библиотечный код, модель связывается с библиотечным кодом. Генератор кода использует контрольную сумму, чтобы определить переиспользуемость. Сгенерированный код для модели должен быть в той же папке, что и библиотека. В командной строке MATLAB введите:
Simulink.fileGenControl('set', 'CodeGenFolderStructure',... Simulink.filegen.CodeGenFolderStructure.TargetEnvironmentSubfolder);
Simulink.fileGenControl
.Если модель не может использовать код библиотеки, можно указать, выдает ли Embedded Coder предупреждение или ошибку во время генерации кода. В диалоговом окне Параметров конфигурации установите значение параметра Behavior when pregenerated library subsystem кода отсутствует.
Можно сгенерировать код для библиотеки, но не выполнять make-файл путем ввода следующих команд:
library='rtwdemo_libcodegen_lib' set_param(library, 'GenCodeOnly', 'on') slbuild(library)
Примечание
Можно сгенерировать код для библиотеки, состоящей из переиспользуемых подсистем, которые содержат S-функции. Чтобы избежать некомпилируемого кода, в функции TLC, соответствующей S-функции, избегайте направления генератора кода на взаимодействие с файлами модели, такими как model.c
, model.h
, и model_types.h
.
Чтобы сгенерировать код из модели, содержащей образец повторно используемой подсистемы библиотеки, для которой необходимо использовать код библиотеки:
Установите параметр конфигурации модели Shared code placement равным Shared location
.
Задайте значение параметра «Поведение», когда предварительно генерированный код подсистемы библиотеки отсутствует, или оставьте значение по умолчанию, которое предупреждает.
В диалоговом окне Параметров конфигурации настройки параметров на панелях Code Generation должны быть идентичны друг другу. Если настройки отличаются, вы можете получить предупреждение, ошибку или ни один из них не зависит от настройки параметра Behavior when pregenerated library subsystem code is missing.
Если переиспользуемая подсистема библиотеки использует общее локальное хранилище данных и вы конфигурируете отображение по умолчанию для элементов данных моделей, оставьте отображение классов памяти по умолчанию для категории Shared local data stores установленной на Default.
Вот сгенерированный код C для rtwdemo_libcodegen_mdl
.
/* Model step function */ void rtwdemo_libcodegen_mdl_step(void) { /* Outputs for Atomic SubSystem: '<Root>/Atomic_Controller_Double' */ /* Inport: '<Root>/pos_rqst' incorporates: * Inport: '<Root>/fbk_1' * Outport: '<Root>/pos_cmd_one' */ Atomic_Controller_Double(pos_rqst1, rtU.fbk_1, &rtY.pos_cmd_one, &rtDW.Atomic_Controller_Double); /* End of Outputs for SubSystem: '<Root>/Atomic_Controller_Double' */ /* Outputs for Atomic SubSystem: '<Root>/Atomic_Controller_Single' */ /* Inport: '<Root>/pos_rqst1' incorporates: * Inport: '<Root>/fbk_2' * Outport: '<Root>/pos_cmd_two' */ Atomic_Controller_Single(pos_rqst2, rtU.fbk_2, &rtY.pos_cmd_two, &rtDW.Atomic_Controller_Single); /* End of Outputs for SubSystem: '<Root>/Atomic_Controller_Single' */ }
Код содержит вызовы на Atomic_Controller_Single
и Atomic_Controller_Double
функций. Сгенерированный код вытаскивает определения функций из предгенерированного библиотечного кода.
Если у вас есть Simulink® Test™ программного обеспечения можно проверить код, который вы генерируете из повторно используемых библиотечных подсистем. Используйте этот рабочий процесс:
Создайте тестовую обвязку в библиотеке для уникальной пары подсистем и интерфейсов функций.
С SIL/PIL Manager:
Запустите симуляции подсистемы в режиме normal mode и программном обеспечении в цикле (SIL) или процессоре в цикле (PIL).
Сравните числовые результаты в Данные моделирования Inspector.
Просмотрите отчет анализа Simulink Coverage™.
Для получения дополнительной информации смотрите Тестовые Библиотечные блоки (Simulink Test).
Рабочий процесс верификации не поддерживает:
Function-Call Subsystem блоки.
Triggered Subsystem блоки или подсистемы, которые используют события пересечения нулем.
Функциональные интерфейсы, где количество Inports/ Outports не совпадает с количеством Inports/ Outports в графическом интерфейсе.
Параметры, которые используют ExportToFile
класс памяти.
Подсистемы с Outport блоками, которые питаются Mux или Demux блоками.
Виртуальные шины, которые передаются как блоки Inport.
Data Store Memory блоки, которые используют ExportedGlobal
класс памяти.
Блоки, где данные инициализируются вне кода подсистемы, например, блок Width.
Подсветка покрытия кода и аннотация.
Сигнал и состояние логгирования данных.
В таких случаях можно создать модель, содержащую образец переиспользуемой подсистемы библиотеки, и использовать SIL/PIL Manager, чтобы запустить SIL или PIL симуляции.
Поскольку генератор кода использует контрольную сумму для определения переиспользуемости, те же ограничения, которые применяются к генерации кода для моделей, которые используют переиспользуемые подсистемы библиотеки, применяются к генерации кода на основе библиотеки. См. раздел Ограничения. Эти ограничения также применяются:
Вы не можете задать интерфейс функции для переиспользуемой подсистемы библиотеки, которая находится в другой переиспользуемой подсистеме библиотеки.
Только производные от ERT и ERT системные целевые файлы поддерживают библиотечную генерацию кода.
Каждый функциональный интерфейс, который соответствует одной и той же переиспользуемой библиотечной подсистеме, должен быть уникальным.
На платформе Windows избегайте имен библиотек lib.slx
это может помешать процессу компиляции статических библиотек.
Когда вы генерируете код из библиотеки, генератор кода генерирует код только для переиспользуемых подсистем верхнего уровня в библиотеке. Библиотечная подсистема верхнего уровня может быть создана на любом уровне в клиентской модели, а образец в клиентских повторных использованиях модели библиотечный код, если обнаруживает его.
Подсистема библиотеки не может повторно использовать код, если он находится внутри блока Enabled Subsystem с параметром Enable block, States when enabling, установленным на reset
.