В этом примере показано, как программно создать определения кода в словаре Embedded Coder. Чтобы автоматизировать создание словаря Embedded Coder в скрипте или создать определения программно, используйте этот интерфейс программирования.
В этом примере вы создаете словарь Embedded Coder Dictionary в словаре данных Simulink, чтобы несколько моделей могли совместно использовать определения кода. Вы создаете определения кода, которые управляют именованием и размещением глобальных данных и функций. Вы также используете определение раздела памяти, которое включает прагму, чтобы поместить данные и функции в быструю память. Чтобы проверить архитектуру, которую вы настраиваете через определения кода, примените определения к модели, а затем сгенерируйте код.
Создайте словарь данных Simulink, чтобы хранить определения кода. Хранение определений в словаре данных позволяет вам использовать определения в нескольких моделях путем связывания каждой модели со словарем данных, как показано на Apply Генерация Кода Definitions.
dataDictionary = Simulink.data.dictionary.create('dataDictionary.sldd');
Создайте словарь Embedded Coder Dictionary в словаре данных. Когда вы создаете словарь, представьте его с coder.Dictionary
объект. Используйте объект для выполнения операций во всем словаре Embedded Coder Dictionary и для доступа к его разделам.
codeDictionary = coder.dictionary.create('dataDictionary.sldd');
The coder.Dictionary
объект содержит три coder.dictionary.Section
объекты, которые представляют разделы словаря Embedded Coder: Классы памяти, разделы памяти и шаблоны индивидуальной настройки функций. A coder.dictionary.Section
объект содержит coder.dictionary.Entry
объекты, которые представляют определения в этом разделе. Чтобы взаимодействовать с определением и получить доступ к его свойствам, используйте coder.dictionary.Entry
объект, который представляет его.
Когда вы создаете словарь Embedded Coder, словарь загружает определения из Simulink
упаковать так, чтобы словарь Embedded Coder Dictionary затем содержал встроенные определения. Если в пакете хранятся пользовательские определения кода, загрузите этот пакет в словарь. Когда вы используете Embedded Coder Dictionary, чтобы сконфигурировать интерфейс кода для модели, можно применить определения из загруженных пакетов.
Чтобы создать определения разделов памяти, добавьте записи в раздел «Разделы памяти». Классы памяти и шаблоны индивидуальной настройки функций, находящиеся в одном словаре, могут использовать эти разделы памяти. В данном примере добавьте раздел памяти с именем FastMem
, который выделяет память при помощи прагмы. Когда вы применяете раздел памяти к классу памяти или шаблону функции, их сгенерированные определения и объявления находятся в разделе памяти.
memorySections = getSection(codeDictionary,'MemorySections'); msFast = addEntry(memorySections,'FastMem'); set(msFast,'PreStatement','#pragma begin FAST'); set(msFast,'Comment','/*Fast onchip RAM*/'); set(msFast,'PostStatement','#pragma end FAST');
В данном примере создайте класс памяти с именем ExportToPrivateHeader
, который генерирует объявление глобальной переменной в заголовочном файле $R_private.h
и определение в $R_private.c
. Область лексемы $R
обозначает имя корневой модели, для которой вы генерируете код. Чтобы использовать переменную во внешнем коде, примените этот класс памяти к элементу данных и включите заголовочный файл во внешний код.
storageClasses = getSection(codeDictionary,'StorageClasses'); exportToPrivateH = addEntry(storageClasses,'ExportToPrivateHeader'); set(exportToPrivateH,'HeaderFile','$R_private.h','DataScope','Exported');
Чтобы применить раздел памяти FastMem
для класса памяти используйте coder.dictionary.Entry
объект, который представляет раздел памяти.
set(exportToPrivateH,'MemorySection',msFast);
Создайте другое определение класса памяти с именем ImportFromHeader
для данных, которые определяет внешний код. Поскольку класс памяти имеет 'DataScope'
установлено на 'Imported'
сгенерированный код читает и записывает в переменную, заданную вашим внешним кодом.
importFromH = addEntry(storageClasses,'ImportFromHeader'); set(importFromH,'DataScope','Imported','HeaderFile','$R_input.h','DataInit','Dynamic');
Чтобы создать шаблон индивидуальной настройки функции, создайте другое coder.dictionary.Section
объект, представляющий раздел Function Customization Templates. Добавьте запись в этот раздел, которая представляет собой определение, которое управляет внешним видом сгенерированных функций точки входа. Примените раздел памяти FastMem
в шаблон функции.
functionTemplates = getSection(codeDictionary,'FunctionCustomizationTemplates'); fcGlobal = addEntry(functionTemplates,'GlobalFunctions'); set(fcGlobal,'FunctionName','$R$N'); set(fcGlobal,'MemorySection',msFast); saveChanges(dataDictionary);
Подтвердите настройки ваших определений кода, применив их к модели и сгенерировав код. Вы можете сконфигурировать интерфейс кода модели, чтобы использовать определения кода программно или с помощью редактора Отображения.
Откройте модель rtwdemo_configinterface
и связать модель со словарем данных, который вы создали.
rtwdemo_configinterface set_param('rtwdemo_configinterface','DataDictionary','dataDictionary.sldd');
Модель содержит четыре входных порта. In1
настроен на использование класса памяти ImportFromFile
. В данном примере вы конфигурируете другие входные порты, чтобы считать данные из внешнего кода по умолчанию. Модель также содержит данные о состоянии для блока Delay, который вы конфигурируете, чтобы быть доступным по внешнему коду. При применении классов памяти ImportFromHeader
и ExportToPrivateHeader
элементам модели сгенерированный код соответствует этой архитектуре.
Чтобы сконфигурировать модель с определениями генерации кода, получите отображение кода для модели.
cm = coder.mapping.api.get('rtwdemo_configinterface');
Используйте отображение кода, чтобы сконфигурировать данные для использования определений классов памяти. Для данных о состоянии в блоке Delay задайте класс памяти ExportToPrivateHeader
.
setState(cm,'rtwdemo_configinterface/Delay','StorageClass','ExportToPrivateHeader');
Задайте класс памяти по умолчанию ImportFromHeader
для корневых входных данных. Для входных портов модели по умолчанию сгенерированный код использует данные, которые внешний код определяет в файле rtwdemo_configinterface_input.c
. Чтобы скомпилировать и связать этот внешний файл при сборке сгенерированного кода, установите параметр конфигурации CustomSource
на rtwdemo_configinterface_input.c
.
setDataDefault(cm,'Inports','StorageClass','ImportFromHeader'); set_param('rtwdemo_configinterface','CustomSource','rtwdemo_configinterface_input.c');
Задайте шаблон индивидуальной настройки функции GlobalFunctions
для генерации кода по умолчанию функций выполнения.
setFunctionDefault(cm,'Execution','FunctionCustomizationTemplate','GlobalFunctions');
Проверьте, что определения кода соответствуют вашим спецификациям.
Откройте редактор Отображения. В редакторе Simulink откройте приложение Embedded Coder. На вкладке Код С выберите Code Interface > Default Code Mappings.
В редакторе Отображения, на вкладке Data Defaults, разверните раздел Inports and Outports. Категория Inports показывает класс памяти ImportFromHeader
. На вкладке Inports входные порты In2
, In3
, и In4
используйте класс памяти по умолчанию для модели ImportFromHeader
. Входной порт In1
имеет другой заданный класс памяти, ImportFromFile
. Этот параметр переопределяет класс памяти по умолчанию, так что In1
считывает данные из другого внешнего файла.
На вкладке Signals/States состояние X показывает класс памяти ExportToPrivateHeader
.
На вкладке Function Defaults (Параметры функции по умолчанию) в категории Execution (Выполнение) отображается шаблон GlobalFunctions
.
Откройте словарь Embedded Coder. На вкладке Кода С выберите Код Interface > Embedded Coder Dictionary. Определения кода, которые вы добавили в словарь, появляются на вкладках.
Сгенерируйте код для модели.
slbuild('rtwdemo_configinterface', 'generateCodeOnly', true);
### Starting build procedure for: rtwdemo_configinterface ### Successful completion of code generation for: rtwdemo_configinterface Build Summary Top model targets built: Model Action Rebuild Reason =========================================================================================== rtwdemo_configinterface Code generated Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 26.762s
Заголовочный файл rtwdemo_configinterface_private.h
определяет данные состояния блока Delay в соответствии с классом памяти ExportToPrivateHeader
. Внешний код может получить доступ к этим данным о состоянии.
file = fullfile('rtwdemo_configinterface_ert_rtw','rtwdemo_configinterface_private.h'); rtwdemodbtype(file,'/* Storage class', ... '#endif');
/* Storage class 'ExportToPrivateHeader' */ /*Fast onchip RAM*/ #pragma begin FAST extern MYTYPE X; /* '<Root>/Delay' */ #pragma end FAST
Поскольку входные порты используют спецификации класса памяти, сгенерированные файлы заголовков не определяют входные данные. Вместо этого сгенерированный файл rtwdemo_configinterface.h
включает внешний заголовочный файл, указанный в определении класса памяти. Сгенерированный код считывает входные данные из переменных, определенных во внешнем файле rtwdemo_configinterface_inputs.c
.
В сгенерированном исходном файле rtwdemo_configinterface.c
функция выполнения (шаг) отражает настройки шаблона индивидуальной настройки функции GlobalFunctions
. Потому что шаблон GlobalFunctions
использует раздел памяти FastMem
, функция выполнения сохранена в разделе памяти и отражает предварительное, постстатментационное и комментарии, которые вы устанавливаете в FastMem
определение.
file2 = fullfile('rtwdemo_configinterface_ert_rtw','rtwdemo_configinterface.c'); rtwdemodbtype(file2,'/* Model step function */', ... '/* Logic:');
/* Model step function */ /*Fast onchip RAM*/ #pragma begin FAST void rtwdemo_configinterface_step(void) {
После настройки словаря Embedded Coder Dictionary можно предоставить общий доступ к словарю команде или организации. Вы и другие пользователи можете применить ваши определения к нескольким моделям, чтобы модели использовали одну и ту же программную архитектуру.
Редактор отображений кода | coder.Dictionary
| coder.dictionary.Entry
| coder.dictionary.Section
| coder.mapping.api.CodeMapping
| Embedded Coder