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

В этом примере показано, как программно создать определения кода в Словаре 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_advsc и соедините модель со словарем данных, который вы создали.

rtwdemo_advsc
set_param('rtwdemo_advsc','DataDictionary','dataDictionary.sldd');

Модель содержит четыре импорта, который вы конфигурируете, чтобы считать данные из внешнего кода. Модель также содержит данные состояния для блока Delay и для диаграммы Stateflow, которую вы конфигурируете, чтобы быть доступными внешним кодом. Когда вы применяете классы памяти ImportFromHeader и ExportToPrivateHeader к элементам модели сгенерированный код соответствует этой архитектуре.

Чтобы сконфигурировать модель с определениями генерации кода, создайте код, сопоставляющий среду для модели.

coder.mapping.create('rtwdemo_advsc');

Используйте отображение кода, чтобы сконфигурировать данные, чтобы использовать ваши определения класса памяти. Для отображения по умолчанию внутренней категории данных задайте класс памяти ExportToPrivateHeader.

coder.mapping.defaults.set('rtwdemo_advsc','InternalData','StorageClass','ExportToPrivateHeader');

Задайте класс памяти ImportFromHeader для корневых данных об импорте. Для импорта модели сгенерированный код использует данные, что ваш внешний код задает в файле rtwdemo_advsc_input.c. Чтобы скомпилировать и соединить этот внешний файл, когда вы создадите сгенерированный код, установите параметр конфигурации CustomSource к rtwdemo_advsc_input.c.

coder.mapping.defaults.set('rtwdemo_advsc','Inports','StorageClass','ImportFromHeader');
set_param('rtwdemo_advsc','CustomSource','rtwdemo_advsc_input.c');

Задайте функциональный шаблон настройки GlobalFunctions для генерации кода по умолчанию функций выполнения.

coder.mapping.defaults.set('rtwdemo_advsc','Execution','FunctionCustomizationTemplate','GlobalFunctions');

Проверьте, что определения кода отражают ваши технические требования.

  1. В Редакторе Simulink откройте приложение Embedded Coder. В редакторе Отображений Кода, на вкладке Data Defaults, категория Inports показывает классу памяти ImportFromHeader. Внутренняя категория Данных показывает классу памяти ExportToPrivateHeader. На вкладке Function Defaults категория Выполнения показывает шаблон GlobalFunctions.

  2. Откройте Словарь Embedded Coder. Определения кода, которые вы добавили в словарь, появляются во вкладках.

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

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

evalc('rtwbuild(''rtwdemo_advsc'')');

Заголовочный файл rtwdemo_advsc_private.h задает внутренние данные согласно классу памяти ExportToPrivateHeader. Внешний код может получить доступ к этим данным о состоянии блока.

file = fullfile('rtwdemo_advsc_ert_rtw','rtwdemo_advsc_private.h');
rtwdemodbtype(file,'/* Storage class', ...
    '#endif');
/* Storage class 'ExportToPrivateHeader' */

/*Fast onchip RAM*/

#pragma begin FAST

extern MYTYPE rtwdemo_advsc_X_p;       /* '<Root>/Delay' */

#pragma end FAST

Поскольку импорт использует класс памяти ImportFromHeader, сгенерированные заголовочные файлы не задают данные об импорте. Вместо этого сгенерированный файл rtwdemo_advsc.h включает внешний заголовочный файл, который вы задали в определении класса памяти. Сгенерированный код считывает данные об импорте из переменных, заданных во внешнем файле rtwdemo_advsc_inputs.c.

В сгенерированном исходном файле rtwdemo_advsc.c, функция выполнения отражает настройки функционального шаблона настройки GlobalFunctions. Поскольку шаблон GlobalFunctions использует раздел memory FastMem, функция выполнения хранится в разделе memory и отражает предварительный оператор, постоператор, и комментирует, что вы устанавливаете в FastMem определение.

file2 = fullfile('rtwdemo_advsc_ert_rtw','rtwdemo_advsc.c');
rtwdemodbtype(file2,'/* Model step function */', ...
    '/* Chart:');
/* Model step function */

/*Fast onchip RAM*/
#pragma begin FAST

void rtwdemo_advsc_step(void)
{

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

delete dataDictionary.sldd

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

| | | |

Похожие темы