Программно создавайте определения кода

В этом примере показано, как программно создать определения кода в словаре Embedded Coder. Чтобы автоматизировать создание словаря Embedded Coder в скрипте или создать определения программно, используйте этот интерфейс программирования.

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

Настройка Embedded Coder

Создайте словарь данных 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');

Проверьте, что определения кода соответствуют вашим спецификациям.

  1. Откройте редактор Отображения. В редакторе Simulink откройте приложение Embedded Coder. На вкладке Код С выберите Code Interface > Default Code Mappings.

  2. В редакторе Отображения, на вкладке Data Defaults, разверните раздел Inports and Outports. Категория Inports показывает класс памяти ImportFromHeader. На вкладке Inports входные порты In2, In3, и In4 используйте класс памяти по умолчанию для модели ImportFromHeader. Входной порт In1 имеет другой заданный класс памяти, ImportFromFile. Этот параметр переопределяет класс памяти по умолчанию, так что In1 считывает данные из другого внешнего файла.

  3. На вкладке Signals/States состояние X показывает класс памяти ExportToPrivateHeader.

  4. На вкладке Function Defaults (Параметры функции по умолчанию) в категории Execution (Выполнение) отображается шаблон GlobalFunctions.

  5. Откройте словарь 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 можно предоставить общий доступ к словарю команде или организации. Вы и другие пользователи можете применить ваши определения к нескольким моделям, чтобы модели использовали одну и ту же программную архитектуру.

См. также

| | | | |

Похожие темы