Этот пример показывает вам процесс генерации простого источника (.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
или .cpp
модуль на основе настроек Того, чтобы генерировать пример основная программа и опции Target operating system на панели Templates диалогового окна Configuration Parameters. Можно использовать шаблон CFP, чтобы заменить нормальное поведение и сгенерировать основной программный модуль, настроенный для целевого окружения.
Чтобы поддержать генерацию основных программных модулей, два файла TLC обеспечиваются:
bareboard_srmain.tlc
: Код TLC, чтобы сгенерировать пример односкоростной основной программный модуль для целевого окружения несмонтированной платы. Код сгенерирован одной функцией TLC, FcnSingleTaskingMain
.
bareboard_mrmain.tlc
: Код TLC, чтобы сгенерировать многоскоростной основной программный модуль для целевого окружения несмонтированной платы. Код сгенерирован одной функцией TLC, FcnMultiTaskingMain
.
В файле шаблона CFP в качестве примера
, следующий код генерирует или сингл - или многозадачный matlabroot
/toolbox/rtw/targets/ecoder/example_file_process.tlcert_main.c
или .cpp
модуль. Логика зависит от информации, полученной из вызовов API шаблона кода 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
используйте шаблон API кода, чтобы сгенерировать ert_main.c
или .cpp
.
При генерации собственного основного программного модуля вы отключаете генерацию по умолчанию ert_main.c
или .cpp
. Переменная TLC GenerateSampleERTMain
генерация средств управления ert_main.c
или .cpp
. Можно непосредственно обеспечить эту переменную к TLC_FALSE
. Примеры bareboard_mrmain.tlc
и bareboard_srmain.tlc
используйте этот метод, как показано в следующей выборке от bareboard_srmain.tlc
.
%if GenerateSampleERTMain %assign CompiledModel.GenerateSampleERTMain = TLC_FALSE %warning Overriding example ert_main.c! %endif
В качестве альтернативы можно реализовать SelectCallback
функционируйте для своей цели. SelectCallback
функцией является функция MATLAB, которая инициирована когда вы:
Загрузите модель.
Обновите любые параметры конфигурации в диалоговом окне Configuration Parameters.
Создайте модель.
Ваш SelectCallback
функция должна отменить выбор и отключить Генерировать пример основная опция программы. Это предотвращает переменную TLC GenerateSampleERTMain
от того, чтобы быть установленным до TLC_TRUE.
Смотрите раздел Structure (Simulink Coder) rtwgensettings для получения информации о создании SelectCallback
функция.
Следующий код иллюстрирует, как отменить выбор и отключить Генерировать пример основная опция программы в контексте SelectCallback
функция.
slConfigUISetVal(hDlg, hSrc, 'GenerateSampleERTMain', 'off'); slConfigUISetEnabled(hDlg, hSrc, 'GenerateSampleERTMain',0);
Создание основной программы для вашего целевого окружения требует некоторой индивидуальной настройки; например, в среде несмонтированной платы необходимо присоединить 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()>
.