Этот пример показывает вам процесс генерации простого источника (.c
или .cpp
) и заголовок (.h
) файл с помощью шаблона CFP в качестве примера. Затем это исследует шаблон и код, сгенерированный шаблоном.
Шаблон CFP в качестве примера,
, демонстрирует некоторые возможности шаблона API кода, включаяmatlabroot
/toolbox/rtw/targets/ecoder/example_file_process.tlc
Генерация простого источника (.c
или .cpp
) и заголовок (.h
) файлы
Использование буферов, чтобы сгенерировать разделы файлов для включает, функции, и так далее
Генерация включает, задает, в сгенерированные файлы стандарта (например,
)model
H
Генерация основного программного модуля
Этот раздел настраивает шаблон 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
файл, сгенерированный в предыдущем примере, был независим от стандартных файлов кода, сгенерированных из модели (например,
или model
C.cpp
,
, и так далее). Можно использовать подобные методы, чтобы сгенерировать пользовательский код в файлах модели. Шаблон API кода включает функции, чтобы получить имена стандартных файлов моделей и другой связанной с моделью информации. Следующая выборка вызывает model
HLibGetMdlPubHdrBaseName
получить имя для
файл. Это затем получает ссылку на файл и генерирует определение в model
HDefines
раздел
:model
H
%% 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()>
.
Пользовательские лексемы не поддерживаются, когда вы генерируете Код С++.