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

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

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

Настройте словарь Embedded Coder

Создайте словарь данных Simulink, чтобы сохранить определения кода. Хранение определений в словаре данных включает, вы, чтобы использовать определения в многоуровневых моделях путем соединения каждой модели со словарем данных как показано в Применяете Определения Генерации кода.

dataDictionary = Simulink.data.dictionary.create('dataDictionary.sldd');

Создайте Словарь Embedded Coder в словаре данных. Когда вы создаете словарь, представляете его coder.Dictionary объект. Используйте объект выполнить операции на целом Словаре Embedded Coder и получить доступ к разделам его.

codeDictionary = coder.dictionary.create('dataDictionary.sldd');

coder.Dictionary объект содержит три coder.dictionary.Section объекты, которые представляют разделы Словаря Embedded Coder: Классы памяти, Разделы Памяти и Функциональные Шаблоны настройки. coder.dictionary.Section объект содержит coder.dictionary.Entry объекты, которые представляют определения в том разделе. Чтобы взаимодействовать с определением и получить доступ к его свойствам, используйте coder.dictionary.Entry объект, который представляет его.

Когда вы создаете Словарь Embedded Coder, словарь загружает определения от Simulink пакет так, чтобы Словарь Embedded Coder затем содержал встроенные определения. Если вам сохранили определения пользовательского кода в пакете, загружаете тот пакет к словарю. Когда вы используете Словарь Embedded Coder, чтобы сконфигурировать интерфейс кода для модели, можно применить определения от пакетов, которые вы загрузили.

Разделы памяти

Чтобы создать определения раздела memory, добавьте записи в раздел Разделов Memory. Классы памяти и функциональные шаблоны настройки, находящиеся в том же словаре, могут использовать эти разделы памяти. В данном примере добавьте раздел memory под названием FastMem, который выделяет память при помощи прагмы. Когда вы применяете раздел memory к классу памяти или шаблону функции, их сгенерированные определения и объявления находятся в разделе memory.

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');

Применять раздел memory FastMem к классу памяти используйте coder.dictionary.Entry объект, который представляет раздел memory.

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. Добавьте запись в этот раздел, который представляет определение, которое управляет внешним видом сгенерированных функций точки входа. Примените раздел memory 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. На вкладке C Code выберите Code Interface> Default Code Mappings.

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

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

  4. На вкладке Function Defaults категория Выполнения показывает шаблон GlobalFunctions.

  5. Откройте Словарь Embedded Coder. На вкладке C Code выберите Code Interface> Embedded Coder Dictionary. Определения кода, которые вы добавили в словарь, появляются во вкладках.

Сгенерируйте и проверьте код

Сгенерируйте код для модели.

rtwbuild('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 53.991s

Заголовочный файл rtwdemo_configinterface_private.h задает данные о состоянии блока Задержки согласно классу памяти 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 использует раздел memory FastMem, функция выполнения хранится в разделе memory и отражает предварительный оператор, постоператор, и комментирует, что вы устанавливаете в 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, можно совместно использовать словарь с командой или организацией. Вы и другие пользователи можете применить свои определения многоуровневым моделям так, чтобы модели использовали ту же программную архитектуру.

Смотрите также

| | | | |

Похожие темы