Этот пример показывает вам процесс генерации простого источника (.c или .cpp) и заголовок (.h) файл с помощью шаблона CFP в качестве примера. Затем это исследует шаблон и код, сгенерированный шаблоном.
Шаблон CFP в качестве примера, , демонстрирует некоторые возможности шаблона API кода, включаяmatlabroot/toolbox/rtw/targets/ecoder/example_file_process.tlc
Генерация простого источника (.c или .cpp) и заголовок (.h) файлы
Использование буферов, чтобы сгенерировать разделы файлов для включает, функции, и так далее
Генерация включает, задает, в сгенерированные файлы стандарта (например, )modelH
Генерация основного программного модуля
Этот раздел настраивает шаблон CFP и конфигурирует модель, чтобы использовать шаблон в генерации кода. Шаблон генерирует (в дополнение к стандартным файлам модели) исходный файл (timestwo.c или .cpp) и заголовочный файл (timestwo.h).
Выполните шаги ниже, чтобы познакомиться с использованием шаблонов CFP:
Скопируйте шаблон CFP в качестве примера, , к папке за пределами MATLAB® структура папок (то есть, не под matlabroot/toolbox/rtw/targets/ecoder/example_file_process.tlc). Если папка не находится на пути MATLAB или пути TLC, то добавьте его в путь MATLAB. Это - хорошая практика, чтобы определить местоположение шаблона CFP в той же папке как ваш системный конечный файл, который находится на пути TLC.matlabroot
Переименуйте скопированный example_file_process.tlc к test_example_file_process.tlc.
Открытый test_example_file_process.tlc в редактор MATLAB.
Не прокомментируйте следующую линию:
%% %assign ERTCustomFileTest = TLC_TRUE
Это теперь читает:
%assign ERTCustomFileTest = TLC_TRUE
Если ERTCustomFileTest не присвоен как показано, шаблон CFP проигнорирован в генерации кода.
Сохраните свои изменения в файле. Сохраните test_example_file_process.tlc открытый, таким образом, можно обратиться к нему позже.
Откройте rtwdemo_udt модель.
Откройте Simulink® Model Explorer. Выберите активную конфигурацию модели модели и откройте панель Code Generation активной конфигурации модели.
На вкладке Templates, в поле File customization template, задают test_example_file_process.tlc. Это - файл, который вы ранее отредактировали и являетесь теперь заданным шаблоном CFP для своей модели.
На вкладке General установите флажок Generate code only.
Нажмите Apply.
В окне модели нажмите Ctrl+B. Во время генерации кода заметьте следующее сообщение в Diagnostic Viewer:
Warning: Overriding example ert_main.c!
Это сообщение отображено потому что test_example_file_process.tlc генерирует основной программный модуль, заменяя действие по умолчанию цели ERT. Это объяснено более подробно ниже.
rtwdemo_udt модель сконфигурирована, чтобы сгенерировать отчет генерации кода HTML. После того, как генерация кода завершена, просмотрите отчет.
Заметьте, что список Generated Code содержит следующие файлы:
Под Main file, ert_main.c.
Под Other files, timestwo.c и timestwo.h.
Файлы были сгенерированы шаблоном CFP. Следующий раздел исследует шаблон, чтобы изучить, как это было сделано.
Сохраните модель, отчет генерации кода и test_example_file_process.tlc файл, открытый, таким образом, можно обратиться к ним в следующем разделе.
Этот раздел исследует выборки от test_example_file_process.tlc и часть кода это генерирует. Обратитесь к комментариям в при чтении следующего обсуждения.matlabroot/rtw/c/tlc/mw/codetemplatelib.tlc
Источник (.c или .cpp) и заголовок (.h) файлы создаются путем вызова LibCreateSourceFile, как в следующих выборках:
%assign cFile = LibCreateSourceFile("Source", "Custom", "timestwo")
...
%assign hFile = LibCreateSourceFile("Header", "Custom", "timestwo")Последующий код относится к файлам ссылкой на файл, возвращенной в LibCreateSourceFile.
Шаблон API кода позволяет вам разделить код, сгенерированный к каждому файлу в разделы, помеченные как Definitions, IncludesФункции, Banner, и так далее. Можно добавить код к каждому разделу так же много раз как требуется. Этот метод дает вам большую гибкость в форматировании ваших файлов пользовательского кода.
Подразделы, Заданные для Встроенных Разделов, описывают доступные разделы файлов и их порядок в сгенерированном файле.
Для каждого раздела сгенерированного файла используйте %openfile и %closefile сохранить текст для того раздела во временных буферах. Затем чтобы записать (добавляют) содержимое буфера к разделу файла, вызывают LibSetSourceFileSection, передача в желаемом теге раздела и ссылке на файл. Например, следующий код использует два буфера (typesBuf и tmpBuf) сгенерировать два раздела (пометил "Includes" и "Functions") из исходного файла timestwo.c или .cpp (ссылаемый как cFile):
%openfile typesBuf
#include "rtwtypes.h"
%closefile typesBuf
%<LibSetSourceFileSection(cFile,"Includes",typesBuf)>
%openfile tmpBuf
/* Times two function */
real_T timestwofcn(real_T input) {
return (input * 2.0);
}
%closefile tmpBuf
%<LibSetSourceFileSection(cFile,"Functions",tmpBuf)>Эти два раздела генерируют целый timestwo.c или .cpp файл:
#include "rtwtypes.h"
/* Times two function */
FLOAT64 timestwofcn(FLOAT64 input)
{
return (input * 2.0);
}timestwo.c или .cpp файл, сгенерированный в предыдущем примере, был независим от стандартных файлов кода, сгенерированных из модели (например, или modelC.cpp, , и так далее). Можно использовать подобные методы, чтобы сгенерировать пользовательский код в файлах модели. Шаблон API кода включает функции, чтобы получить имена стандартных файлов моделей и другой связанной с моделью информации. Следующая выборка вызывает modelHLibGetMdlPubHdrBaseName получить имя для файл. Это затем получает ссылку на файл и генерирует определение в modelHDefines раздел :modelH
%% Add a #define to the model's public header file model.h
%assign pubName = LibGetMdlPubHdrBaseName()
%assign modelH = LibCreateSourceFile("Header", "Simulink", pubName)
%openfile tmpBuf
#define ACCELERATION 9.81
%closefile tmpBuf
%<LibSetSourceFileSection(modelH,"Defines",tmpBuf)>Исследуйте сгенерированный rtwdemo_udt.h файл, чтобы видеть сгенерированный #define директива.
Основанные на ERT системные конечные файлы определяют, ли и как сгенерировать пример основной программный модуль (ert_main.c или ert_main.cpp) на основе настроек параметров конфигурации модели Генерируют пример основная программа и Target operating system. Можно заменить поведение по умолчанию и сгенерировать a main программа настраивается для вашего целевого окружения.
Два файла TLC поддерживают генерацию примера main программный модуль:
bareboard_srmain.tlc: Код TLC для генерации односкоростного примера main программный модуль для целевого окружения несмонтированной платы. Функция TLC FcnSingleTaskingMain генерирует код.
bareboard_mrmain.tlc: Код TLC для генерации многоскоростного примера main программный модуль для целевого окружения несмонтированной платы. Функция TLC FcnMultiTaskingMain генерирует код.
В файле шаблона CFP в качестве примера , этот код генерирует сингл - или многозадачный пример matlabroot/toolbox/rtw/targets/ecoder/example_file_process.tlcmain программный модуль. Логика зависит от информации, полученной от вызовов шаблона кода до LibIsSingleRateModel и LibIsSingleTasking.
%% Create a simple main. Files are located in MATLAB/rtw/c/tlc/mw. %if LibIsSingleRateModel() || LibIsSingleTasking() %include "bareboard_srmain.tlc" %<FcnSingleTaskingMain()> %else %include "bareboard_mrmain.tlc" %<FcnMultiTaskingMain()> %endif
Файлы bareboard_srmain.tlc и bareboard_mrmain.tlc используйте интерфейс шаблонного программирования кода, чтобы сгенерировать пример main программные модули ert_main.c или ert_main.cpp.
По умолчанию генератор кода производит пример main программный модуль. Чтобы отключить генерацию того модуля, установите переменную TLC OverrideSampleERTMain к TLC_TRUE.
Например:
%if GenerateSampleERTMain
%assign CompiledModel.OverrideSampleERTMain = TLC_TRUE
%warning Overriding example ert_main.c!
%endifВ качестве альтернативы можно реализовать SelectCallback функционируйте для своей цели. SelectCallback функцией является функция MATLAB, которая инициирована когда вы:
Загрузите модель.
Обновите настройки параметра конфигурации модели.
Создайте модель.
Ваш SelectCallback очищается параметр конфигурации модели Генерируют пример основная программа. Очистка параметра предотвращает переменную TLC GenerateSampleERTMain от того, чтобы быть установленным до TLC_TRUE.
Для получения информации о том, как создать SelectCallback функционируйте, смотрите Структуру rtwgensettings.
Этот код показывает, как очистить Генерировать пример основной параметр программы в контексте SelectCallback функция.
slConfigUISetVal(hDlg, hSrc, 'GenerateSampleERTMain', 'off'); slConfigUISetEnabled(hDlg, hSrc, 'GenerateSampleERTMain',0); hSrc.refreshDialog;
Создание a main программа для вашего целевого окружения требует индивидуальной настройки. Например, в среде несмонтированной платы, необходимо присоединить rt_OneStep к прерыванию по таймеру и настраивают сгенерированный код, генерация код TLC или оба. Для получения дополнительной информации см. Инструкции для Изменения Основной Программы и Инструкций для Изменения rt_OneStep.
Можно задать пользовательские лексемы в файле CGT и прямом сгенерированном коде в связанный встроенный раздел. Эта функция дает вам дополнительный контроль над форматированием кода в каждом встроенном разделе. Например, вы могли добавить подразделы во встроенные разделы, которые уже не задают подразделы. Пользовательские разделы должны быть сопоставлены с одним из встроенных разделов: Includes, Defines, Types, EnumsОпределения, Declarations, или Functions. Чтобы создать пользовательские разделы, вы должны
Добавьте пользовательскую лексему в раздел вставки кода вашего файла CGT.
В вашем файле CFP:
Соберите код, который будет сгенерирован к пользовательскому разделу в буфер.
Объявите, что ассоциация между пользовательским разделом и встроенным разделом, с кодом обрабатывают API-функцию по шаблону LibAddSourceFileCustomSection.
Испустите код к пользовательскому разделу с API-функцией шаблона кода LibSetSourceFileCustomSection.
Следующие примеры кода иллюстрируют сложение пользовательской лексемы, Myincludes, к файлу CGT и последующей ассоциации пользовательского раздела Myincludes со встроенным разделом Includes в файле CFP.
Примечание
Если вы уже не создали пользовательский CGT и файлы CFP для вашей модели, скопируйте файлы шаблона по умолчанию и matlabroot/toolbox/rtw/targets/ecoder/ert_code_template.cgt к папке работы, которая находится вне структуры папок MATLAB, но на MATLAB или пути TLC, переименуйте их (например, добавьте префиксный matlabroot/toolbox/rtw/targets/ecoder/example_file_process.tlctest_ к каждому файлу), и обновление панель Templates диалогового окна Configuration Parameters, чтобы сослаться на них.
Во-первых, добавьте маркерный Myincludes к разделу вставки кода вашего файла CGT. Например:
%<Includes> %<Myincludes> %<Defines> %<Types> %<Enums> %<Definitions> %<Declarations> %<Functions>
Затем в файле CFP, добавьте код, чтобы сгенерировать include директивы в буфер. Например, в вашей копии файла CFP в качестве примера, вы могли вставить следующий раздел между Includes разделите и Create a simple main раздел:
%% Add a custom section to the model's C file model.c %openfile tmpBuf #include "moretables1.h" #include "moretables2.h" %closefile tmpBuf %<LibAddSourceFileCustomSection(modelC,"Includes","Myincludes")> %<LibSetSourceFileCustomSection(modelC,"Myincludes",tmpBuf)>
LibAddSourceFileCustomSection вызов функции объявляет ассоциацию между встроенным разделом Includes и пользовательский раздел Myincludes. Myincludes подраздел Includes. LibSetSourceFileCustomSection вызов функции направляет код в tmpBuf буферизуйте к Myincludes раздел сгенерированного файла. LibSetSourceFileCustomSection синтаксически идентично LibSetSourceFileSection.
В сгенерированном коде появляются включать директивы, сгенерированные к пользовательскому разделу после того, как другой код направил к Includes.
#include "rtwdemo_udt.h" #include "rtwdemo_udt_private.h" /* #include "mytables.h" */ #include "moretables1.h" #include "moretables2.h"
Примечание
Размещение пользовательской лексемы в этом примере файл CGT произвольно. Путем определения местоположения %<Myincludes> после %<Includes>, файл CGT указывает только что Myincludes код появляется после Includes код.
Пользовательские лексемы автоматически переводятся в синтаксис TLC как часть процесса сборки. Выйти из лексемы, которая должна подготовить его к нормальному расширению TLC, использованию'! Символ. Например, маркерный %<!TokenName> расширен до %<TokenName> программой преобразования шаблона. Можно задать допустимый код TLC, включая вызовы функции TLC: %<!MyTLCFcn()>.
Пользовательские лексемы не поддерживаются, когда вы генерируете Код С++.