Чтобы управлять внешним видом данных в сгенерированном коде, можно использовать встроенные классы памяти, такие как ExportToFile
(см., Организуют Данные о Параметре в Структуру при помощи Класса памяти Struct). Если встроенные классы памяти не удовлетворяют ваши требования, можно создать собственные классы памяти. Чтобы создать класс памяти, что можно обратиться к объектам данных, создайте класс памяти в пакете при помощи Custom Storage Class Designer. Смотрите Задают Классы памяти, Разделы Памяти и Шаблоны функций для Программной архитектуры.
Чтобы задать класс памяти, который можно применить в модели при помощи редактора Отображений Кода, используйте Embedded Coder Dictionary. Или, создайте класс памяти в пакете и обратитесь к пакету из Словаря Embedded Coder.
Пакет также задает Signal
и Parameter
классы данных. Смотрите Объекты данных. Объект данных от пакета, такого как Simulink
может использовать классы памяти, заданные в том пакете, но не классах памяти, которые заданы в других пакетах.
Для получения информации об использовании Custom Storage Class Designer, чтобы создать разделы памяти, смотрите Данные об Управлении и Функциональное Размещение в Памяти Вставкой Прагм.
В этом примере показано, как к коду системы управления, сгенерированному из модели путем создания и применения собственного класса памяти для объектов данных.
Откройте модель rtwdemo_cscpredef. Вы можете код системы управления, сгенерированный из этой модели путем определения собственных классов данных и создания собственных классов памяти.
В этом примере вы экспортируете объявления и определения нескольких сигналов и параметров в модели к одному заголовочному файлу объявления и одному файлу определения.
Чтобы создать классы памяти, вы сначала создаете пакет класса данных, чтобы содержать определения класса памяти. Объекты данных, которые вы создаете из своего пакета, могут использовать классы памяти, которые задает пакет.
Создайте свой собственный пакет класса данных путем копирования папки +SimulinkDemos
пакета в качестве примера. Перейдите к папке пакета в качестве примера.
% Remember the current folder path currentPath = pwd; % Navigate to the example package folder demoPath = '\toolbox\simulink\simdemos\dataclasses'; cd([matlabroot,demoPath])
Скопируйте +SimulinkDemos
папка к вашему буферу обмена.
Возвратитесь к своей рабочей папке.
cd(currentPath)
Вставьте +SimulinkDemos
папка от вашего буфера обмена в вашу рабочую папку. Переименуйте скопированную папку в +myPackage
.
Перейдите в +myPackage
папка к файлу Signal.m
отредактировать определение Signal
класс.
Не прокомментируйте methods
разделите, который задает метод setupCoderInfo
. В вызове функционального useLocalCustomStorageClasses
, замените 'packageName'
с 'myPackage'
. Когда вы закончили, раздел появляется следующим:
methods function setupCoderInfo(h) % Use custom storage classes from this package useLocalCustomStorageClasses(h, 'myPackage'); end end % methods
Функциональный useLocalCustomStorageClasses
позволяет вам применять классы памяти что myPackage
задает к объектам данных, которые вы создаете из myPackage
.
Сохраните и закройте файл.
Перейдите в +myPackage
папка к файлу Parameter.m
отредактировать определение Parameter
класс. Не прокомментируйте methods
разделите, который задает метод setupCoderInfo
и замените 'packageName'
с 'myPackage'
.
Сохраните и закройте файл.
Можно использовать Custom Storage Class Designer, чтобы создать или отредактировать классы памяти, которые задает пакет класса данных.
Установите свою текущую папку на папку, которая содержит пакет myPackage
.
Откройте Custom Storage Class Designer.
cscdesigner('myPackage')
Выберите класс памяти ExportToFile
.
В поле Name переименуйте класс памяти в ExportToGlobal
.
В Header file выпадающий список измените выбор от Instance specific
к Specify
. В новом поле обеспечьте, заголовочный файл называют global.h
.
В Definition file выпадающий список измените выбор от Instance specific
к Specify
. В новом поле предоставьте имени файла определения global.c
.
Нажмите OK. Нажмите Yes, чтобы сохранить изменения в пакете класса данных myPackage
.
Чтобы применить ваш собственный класс памяти, вы создаете объекты данных из своего пакета и конфигурируете объекты использовать ваш класс памяти.
Создайте объекты данных представлять некоторые параметры и сигналы в модели в качестве примера. Создайте объекты с помощью пакета класса данных myPackage
.
% Parameters templimit = myPackage.Parameter(202); pressurelimit = myPackage.Parameter(45.2); O2limit = myPackage.Parameter(0.96); rpmlimit = myPackage.Parameter(7400); % Signals tempalarm = myPackage.Signal; pressurealarm = myPackage.Signal; O2alarm = myPackage.Signal; rpmalarm = myPackage.Signal;
Установите класс памяти каждого объекта к ExportToGlobal
.
% Parameters templimit.CoderInfo.StorageClass = 'Custom'; templimit.CoderInfo.CustomStorageClass = 'ExportToGlobal'; pressurelimit.CoderInfo.StorageClass = 'Custom'; pressurelimit.CoderInfo.CustomStorageClass = 'ExportToGlobal'; O2limit.CoderInfo.StorageClass = 'Custom'; O2limit.CoderInfo.CustomStorageClass = 'ExportToGlobal'; rpmlimit.CoderInfo.StorageClass = 'Custom'; rpmlimit.CoderInfo.CustomStorageClass = 'ExportToGlobal'; % Signals tempalarm.CoderInfo.StorageClass = 'Custom'; tempalarm.CoderInfo.CustomStorageClass = 'ExportToGlobal'; pressurealarm.CoderInfo.StorageClass = 'Custom'; pressurealarm.CoderInfo.CustomStorageClass = 'ExportToGlobal'; O2alarm.CoderInfo.StorageClass = 'Custom'; O2alarm.CoderInfo.CustomStorageClass = 'ExportToGlobal'; rpmalarm.CoderInfo.StorageClass = 'Custom'; rpmalarm.CoderInfo.CustomStorageClass = 'ExportToGlobal';
Выберите опцию Signal name must resolve to Simulink signal object для каждого из целевых сигналов в модели. Можно выбрать опцию при помощи диалогового окна Signal Properties, столбец Resolve в Model Data Editor, или при помощи командной строки.
% Signal tempalarm portHandles = get_param('rtwdemo_cscpredef/RelOp1','PortHandles'); outputPortHandle = portHandles.Outport; set_param(outputPortHandle,'MustResolveToSignalObject','on') % Signal pressurealarm portHandles = get_param('rtwdemo_cscpredef/RelOp2','PortHandles'); outputPortHandle = portHandles.Outport; set_param(outputPortHandle,'MustResolveToSignalObject','on') % Signal O2alarm portHandles = get_param('rtwdemo_cscpredef/RelOp3','PortHandles'); outputPortHandle = portHandles.Outport; set_param(outputPortHandle,'MustResolveToSignalObject','on') % Signal rpmalarm portHandles = get_param('rtwdemo_cscpredef/RelOp4','PortHandles'); outputPortHandle = portHandles.Outport; set_param(outputPortHandle,'MustResolveToSignalObject','on')
Сгенерируйте код для модели в качестве примера.
rtwbuild('rtwdemo_cscpredef')
В Представлении кода для модели просмотрите сгенерированный заголовочный файл global.h
. Файл содержит extern
объявления сигналов модели и параметров, которые используют класс памяти ExportToGlobal
.
/* Declaration for custom storage class: ExportToGlobal */ extern boolean_T O2alarm; extern real_T O2limit; extern boolean_T pressurealarm; extern real_T pressurelimit; extern boolean_T rpmalarm; extern real_T rpmlimit; extern boolean_T tempalarm; extern real_T templimit;
Просмотрите сгенерированный файл global.c
. Файл содержит определения сигналов модели и параметров, которые используют класс памяти ExportToGlobal
.
/* Definition for custom storage class: ExportToGlobal */ boolean_T O2alarm; real_T O2limit = 0.96; boolean_T pressurealarm; real_T pressurelimit = 45.2; boolean_T rpmalarm; real_T rpmlimit = 7400.0; boolean_T tempalarm; real_T templimit = 202.0;
Вы не можете непосредственно изменить встроенный класс памяти, такой как ExportToFile
от Simulink
пакет, но можно создать копию, и затем изменить копию. Когда вы создаете новый пакет без csc_registration.m
файл, и затем открывает Custom Storage Class Designer впервые в том пакете, Simulink копирует определения встроенных классов памяти в пакет. Затем в Custom Storage Class Designer можно изменить скопированные определения. В качестве альтернативы, чтобы сохранить встроенные классы памяти доступными в вашем пакете, скопируйте один из них путем нажатия на Copy, затем измените получившуюся копию.
Custom Storage Class Designer является инструментом для создания и разделов managing storage classes и memory. Открыть Custom Storage Class Designer для определенного пакета, например, +mypkg
, в командной строке используйте cscdesigner
функция:
cscdesigner('mypkg')
Имя папки, которая представляет пакет, начинается с +
. Когда вы используете функцию cscdesigner
, не используйте +
с имени целевого пакета.
Чтобы управлять влиянием, которое класс памяти оказывает на данные в модели, вы задаете свойства класса памяти в Custom Storage Class Designer. Чтобы определить, как сгенерировать конкретный вид кода, используйте информацию в таблице.
Вид данных в сгенерированном коде | Метод |
---|---|
Структура | Установите Type на FlatStructure . Смотрите генерируют структурированные данные. |
Макрос | Установите Data initialization на Macro и очистите For signals. Смотрите Генерируют Макрос. |
Указатель | Установите Data access на Pointer и Data scope к Auto , Imported , или Instance specific . Ваш внешний код должен задать переменную указателя. |
static данные (ограниченные по объему файлом данные) | Установите Data scope на File . |
const или volatile данные | Установите Memory section на раздел memory, который задает const , volatile , или оба. Например, используйте один из встроенных разделов памяти MemConst , MemVolatile , и MemConstVolatile . Чтобы создать ваш собственный раздел memory, смотрите Данные об Управлении и Функциональное Размещение в Памяти Вставкой Прагм. |
Вызовы внешних функций, чтобы читать и записать в данные | Смотрите вызывают пользовательские функции средства доступа или макросы вместо того, чтобы читать и записать в переменные. |
Для некоторых свойств класса памяти, таких как Data scope, вместо того, чтобы задать значение в Custom Storage Class Designer, можно позволить пользователям класса памяти задавать значение. Можно создать один, гибкий класс памяти вместо нескольких классов памяти, которые варьируются только несколькими значениями свойств.
Например, предположите, что вы создаете класс памяти, который дает к глобальной переменной в сгенерированном коде. Можно сконфигурировать класс памяти так, чтобы пользователь мог установить свойство Data scope на Exported
для сигнала в модели и наборе свойство к Imported
для различного сигнала.
В Custom Storage Class Designer, для каждого свойства, которое вы хотите сконфигурировать таким образом, устанавливал значение свойства на Instance specific
. Затем когда пользователь применяет класс памяти к элементу данных, свойство появляется пользователю как пользовательский атрибут для того элемента данных. Для получения информации о специфичных для экземпляра пользовательских атрибутах смотрите Storage Class Properties.
Чтобы создать класс памяти, который дает к макросу в сгенерировать коде, устанавливает Data initialization на Macro
и очистите For signals.
Когда вы устанавливаете Data initialization на Macro
, Definition file не имеет никакого значения. Чтобы препятствовать тому, чтобы пользователи класса памяти задали бессмысленный файл определения в Custom Storage Class Designer, устанавливают Definition file на Specify
и оставьте текстовое поле пустым.
Задавать макрос в заголовочном файле (#define
), задайте имя заголовочного файла со свойством Header file.
Чтобы обеспечить макроопределение как параметр компилятора или флаг компилятора, установите Data access на Imported
и Header file к Specify
. Оставьте текстовое поле Header file пустым. Затем сгенерированный код не задает макрос и не включает (#include
) заголовочный файл.
Чтобы задать параметр компилятора или флаг, используйте параметр конфигурации модели Configuration Parameters> Code Generation> Custom Code> Additional build information> Defines. Смотрите Панель Генерации кода: Пользовательский код: Дополнительная информация о Сборке: Задает.
Создать класс памяти, который агрегировал элементы данных в плоскую структуру (похожий на встроенный класс памяти Struct
), установите Type на FlatStructure
. Вкладка Structure Attributes появляется.
Чтобы управлять именем глобальной переменной структуры, которая появляется в сгенерированном коде, используйте свойство Struct name и текстовое поле.
Если вы устанавливаете Struct name на Instance specific
, пользователи класса памяти задают имя переменной структуры. В этом случае генератор кода выводит имя типа структуры с имени переменной.
Чтобы более точно управлять именем и другими характеристиками типа структуры, установите Struct name на Specify
. Управляйте характеристиками типа при помощи дополнительных свойств, которые появляются.
Сгенерировать структуру с битовыми полями (похожий на встроенный класс памяти BitField
), выберите Bit-pack booleans. Элементы данных, которые используют тип данных boolean
появитесь в сгенерированном коде как битовые поля структуры.
Чтобы использовать стратегию инициализации Simulink® Coder™ по умолчанию, установите Data initialization на значение по умолчанию, Auto
.
Сгенерированный код статически инициализирует данные о параметре оператором присваивания наверху .c
или .cpp
исходный файл, за пределами любой функции.
Сгенерированный код динамически инициализирует данные состояния и сигнала как часть функции инициализации модели (названный
по умолчанию).model
_initialize
Чтобы статически инициализировать данные, установите Data initialization на Static
.
Чтобы динамически инициализировать данные, установите Data initialization на Dynamic
.
Чтобы препятствовать тому, чтобы сгенерированный код инициализировал данные, установите Data initialization на None
. Когда ваш внешний код инициализирует данные, используйте эту установку, чтобы препятствовать тому, чтобы сгенерированный код перезаписал вашу инициализацию.
Используя встроенный класс памяти GetSet
, можно сгенерировать код, который вызывает внешние, пользовательские функции вместо того, чтобы непосредственно взаимодействовать с переменными. Для получения общей информации о GetSet
, см. Доступ к данным Через Функции с Классом памяти GetSet.
Чтобы создать подобный класс памяти, установите Type на AccessFunction
.
Задайте имена внешних функций.
Применять тот же get
или set
функциональная схема именования к элементам данных, которые используют класс памяти, установи Get function и Set function к Specify
. Затем в текстовых полях задайте функциональную схему именования, например, get_myData_$N
. Используйте маркерный $N
в схеме именования, чтобы представлять имя каждого элемента данных. Если вы не используете лексему, каждый элемент данных использует то же самое, заданное get
или set
имя функции, таким образом, модель генерирует ошибку, когда вы генерируете код.
Задавать различный get
или set
имя функции для каждого элемента данных, набор Get function или Set function к Instance specific
. Позже, когда вы создаете элемент данных и применяете класс памяти, задаете имя функции путем конфигурирования пользовательских атрибутов элемента данных.
Задайте имя заголовочного файла, который объявляет get
и set
функции со свойством Header file. В этом случае Definition file не имеет никакого значения. Чтобы препятствовать тому, чтобы пользователи класса памяти задали бессмысленный файл определения, установите Definition file на Specify
и оставьте текстовое поле пустым.
Если вы реализуете get
механизм для скалярных или данных массива как макрос вместо функции, можно сгенерировать код, который не использует круглые скобки при чтении тех данных. На вкладке Access Function Attributes выберите Get data through macro (omit parentheses).
Когда ваш внешний код задает данные, чтобы не генерировать дублирующееся определение, необходимо сконфигурировать сгенерированный код, чтобы читать и записать в существующие данные. В Custom Storage Class Designer, набор Data scope к Imported
. Генератор кода не генерирует определение для глобальной переменной или макроса.
Если ваш код задает переменную указателя, чтобы сгенерировать код, который взаимодействует с указателем, установите Data access на Pointer
.
Если вы генерируете структурированные данные установкой Type к FlatStructure
, ваш код должен задать тип структуры и глобальную переменную структуры.
Если ваш код инициализирует состояние или данные сигнала, можно препятствовать тому, чтобы сгенерированный код перезаписал инициализацию установкой Data initialization к None
. Смотрите предотвращают дублирующийся код инициализации для глобальных переменных
Чтобы настроить комментарии, которые появляются в сгенерированном коде на вкладке Comments, устанавливают Comment rules на Specify
. Чтобы задать комментарий, который появляется с объявлением каждого элемента данных, используйте поле Declaration comment. Чтобы задать комментарий, который появляется с определением, используйте поле Definition comment.
Для структурированных данных (вы устанавливаете Type на FlatStructure
), чтобы задать комментарий, который появляется с определением типа структуры, используйте поле Type comment.
Когда вы конфигурируете класс памяти в Custom Storage Class Designer, чтобы проверять на возможные ошибки в настройке, нажмите Validate.
Например, проверка класса памяти предупреждает вас, если вы случайно устанавливаете Data initialization на Macro
с выбранным For signals. Сигнал не может появиться в сгенерированном коде как макрос.
Чтобы использовать класс памяти, который вы создаете, необходимо сделать пакет определения доступным. Или установите свою текущую папку на папку, которая содержит пакет, или добавьте папку, содержащую папку пакета к пути MATLAB® (см. то, Что Путь поиска файлов MATLAB?). Добавление пакета к пути MATLAB позволяет вам использовать классы памяти, неважно, где вы устанавливаете свою текущую папку.
Чтобы использовать основанные на пакете классы памяти в редакторе Отображений Кода, обратитесь к пакету из Словаря Embedded Coder. Чтобы сконфигурировать Словарь Embedded Coder, чтобы относиться к пакету, смотрите, Обращаются к Определениям Генерации кода в Пакете.
Когда вы создаете пакет, можно обратиться к классу памяти, заданному в другом пакете, таком как встроенный пакет Simulink
или различный пакет, который вы создали. Затем пакет определения и любые пакеты ссылки могут использовать класс памяти. Когда это необходимо, чтобы внести изменение в класс памяти, вы вносите изменение только однажды в пакете определения.
Чтобы сконфигурировать пакет, чтобы относиться к классу памяти, который задает другой пакет:
В Custom Storage Class Designer выберите вкладку Custom Storage Class.
Использование Выбирать Package, чтобы выбрать пакет ссылки. Пакет должен быть перезаписываем.
В Пользовательской панели определений класса памяти выберите существующее определение, ниже которого вы хотите вставить ссылку.
Нажмите New Reference.
Новая ссылка с именем по умолчанию и свойствами появляется ниже ранее выбранного определения. Новая ссылка выбрана, и вкладка Reference появляется, который показывает начальные свойства.
Используйте Имя, чтобы задать имя для новой ссылки. Имя должно быть уникальным в пакете импорта, но может скопировать имя в исходном пакете. Имя не может быть ключевым словом TLC.
Установите Относятся к пользовательскому классу памяти в пакете, чтобы задать пакет, который содержит класс памяти, на который вы хотите сослаться.
Установите Пользовательский класс памяти на ссылку задавать класс памяти, на который сошлются.
Нажмите ОК или Применяйтесь. Чтобы сохранить изменения постоянно, нажмите Save.
Когда вы применяете класс памяти к элементу данных, вы выбираете класс памяти из выпадающего списка.
Чтобы управлять порядком пользовательских классов памяти в списке, в Custom Storage Class Designer, используют кнопки Up и Down. Порядок классов памяти в выпадающих списках совпадает с порядком, который вы задаете в Custom Storage Class Designer.
Чтобы препятствовать тому, чтобы пользователь класса памяти применил класс памяти к данным о параметре или предупредил и утвердил данные, используйте флажки For parameters и For signals. Когда вы очищаете одно из этих свойств для соответствующего вида данных, класс памяти не появляется в выпадающем списке.
Например, если ваш класс памяти дает к макросу в сгенерированном коде, потому что вы устанавливаете Data initialization на Macro
, чтобы препятствовать тому, чтобы пользователи применили класс памяти к данным сигнала, очистите For signals.
Когда вы нажимаете Save в Custom Storage Class Designer, Разработчик сохраняет раздел memory и определения класса памяти в csc_registration.m
файл в папке пакета. Чтобы определить местоположение этого файла, в Custom Storage Class Designer, смотрят значение Filename.
Можно предотвратить изменения в определениях класса памяти целого пакета путем преобразования csc_registration.m
файл от файла MATLAB до P-файла. Используйте pcode
функция.
Лучшая практика состоит в том, чтобы сохранить csc_registration.m
и csc_registration.p
в вашей папке пакета. Тот путь, если вы изменяете классы памяти при помощи Разработчика, можно удалить csc_registration.p
и позже регенерируйте его после того, как вы закончите модификации. Поскольку версия P-coded файла более приоритетна, когда оба файла существуют в пакете, классы памяти защищены, и вы не можете изменить их в Custom Storage Class Designer.
Если создание вашего собственного класса памяти путем управления свойствами в Custom Storage Class Designer не удовлетворяет требования, можно точно управлять сгенерированным кодом путем записи кода TLC для класса памяти. Используйте усовершенствованный режим Custom Storage Class Designer и, для класса памяти, установите Type на Other
. Смотрите точно представление данных управления путем записи кода TLC для класса памяти.