Создайте классы памяти при помощи Custom Storage Class Designer

Чтобы управлять внешним видом данных в сгенерированном коде, можно использовать встроенные классы памяти, такие как ExportToFile (см., Организуют Данные о Параметре в Структуру при помощи Класса памяти Struct). Если встроенные классы памяти не удовлетворяют ваши требования, можно создать собственные классы памяти. Чтобы создать класс памяти, что можно обратиться к объектам данных, создайте класс памяти в пакете при помощи Custom Storage Class Designer. Смотрите Задают Классы памяти, Разделы Памяти и Шаблоны функций для Программной архитектуры.

Чтобы задать класс памяти, который можно применить в модели при помощи редактора Отображений Кода, используйте Embedded Coder Dictionary. Или, создайте класс памяти в пакете и обратитесь к пакету из Словаря Embedded Coder.

Пакет также задает Signal и Parameter классы данных. Смотрите Объекты данных. Объект данных от пакета, такого как Simulink может использовать классы памяти, заданные в том пакете, но не классах памяти, которые заданы в других пакетах.

Для получения информации об использовании Custom Storage Class Designer, чтобы создать разделы памяти, смотрите Данные об Управлении и Функциональное Размещение в Памяти Вставкой Прагм.

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

В этом примере показано, как к коду системы управления, сгенерированному из модели путем создания и применения собственного класса памяти для объектов данных.

Исследуйте модель в качестве примера

Откройте модель rtwdemo_cscpredef. Вы можете код системы управления, сгенерированный из этой модели путем определения собственных классов данных и создания собственных классов памяти.

В этом примере вы экспортируете объявления и определения нескольких сигналов и параметров в модели к одному заголовочному файлу объявления и одному файлу определения.

Создайте пакет класса данных

Чтобы создать классы памяти, вы сначала создаете пакет класса данных, чтобы содержать определения класса памяти. Объекты данных, которые вы создаете из своего пакета, могут использовать классы памяти, которые задает пакет.

  1. Создайте свой собственный пакет класса данных путем копирования папки +SimulinkDemos пакета в качестве примера. Перейдите к папке пакета в качестве примера.

    % Remember the current folder path
    currentPath = pwd;
    
    % Navigate to the example package folder
    demoPath = '\toolbox\simulink\simdemos\dataclasses';
    cd([matlabroot,demoPath])
    

  2. Скопируйте +SimulinkDemos папка к вашему буферу обмена.

  3. Возвратитесь к своей рабочей папке.

    cd(currentPath)

  4. Вставьте +SimulinkDemos папка от вашего буфера обмена в вашу рабочую папку. Переименуйте скопированную папку в +myPackage.

  5. Перейдите в +myPackage папка к файлу Signal.m отредактировать определение Signal класс.

  6. Не прокомментируйте 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.

  7. Сохраните и закройте файл.

  8. Перейдите в +myPackage папка к файлу Parameter.m отредактировать определение Parameter класс. Не прокомментируйте methods разделите, который задает метод setupCoderInfo и замените 'packageName' с 'myPackage'.

  9. Сохраните и закройте файл.

Создайте класс памяти

Можно использовать Custom Storage Class Designer, чтобы создать или отредактировать классы памяти, которые задает пакет класса данных.

  1. Установите свою текущую папку на папку, которая содержит пакет myPackage.

  2. Откройте Custom Storage Class Designer.

    cscdesigner('myPackage')
  3. Выберите класс памяти ExportToFile.

  4. В поле Name переименуйте класс памяти в ExportToGlobal.

  5. В Header file выпадающий список измените выбор от Instance specific к Specify. В новом поле обеспечьте, заголовочный файл называют global.h.

  6. В Definition file выпадающий список измените выбор от Instance specific к Specify. В новом поле предоставьте имени файла определения global.c.

  7. Нажмите OK. Нажмите Yes, чтобы сохранить изменения в пакете класса данных myPackage.

Примените класс памяти

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

  1. Создайте объекты данных представлять некоторые параметры и сигналы в модели в качестве примера. Создайте объекты с помощью пакета класса данных 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;
  2. Установите класс памяти каждого объекта к 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';
    
  3. Выберите опцию 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')
    

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

  1. Сгенерируйте код для модели в качестве примера.

    rtwbuild('rtwdemo_cscpredef')
  2. В Представлении кода для модели просмотрите сгенерированный заголовочный файл 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;

  3. Просмотрите сгенерированный файл 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 или различный пакет, который вы создали. Затем пакет определения и любые пакеты ссылки могут использовать класс памяти. Когда это необходимо, чтобы внести изменение в класс памяти, вы вносите изменение только однажды в пакете определения.

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

  1. В Custom Storage Class Designer выберите вкладку Custom Storage Class.

  2. Использование Выбирать Package, чтобы выбрать пакет ссылки. Пакет должен быть перезаписываем.

  3. В Пользовательской панели определений класса памяти выберите существующее определение, ниже которого вы хотите вставить ссылку.

  4. Нажмите New Reference.

    Новая ссылка с именем по умолчанию и свойствами появляется ниже ранее выбранного определения. Новая ссылка выбрана, и вкладка Reference появляется, который показывает начальные свойства.

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

  6. Установите Относятся к пользовательскому классу памяти в пакете, чтобы задать пакет, который содержит класс памяти, на который вы хотите сослаться.

  7. Установите Пользовательский класс памяти на ссылку задавать класс памяти, на который сошлются.

  8. Нажмите ОК или Применяйтесь. Чтобы сохранить изменения постоянно, нажмите 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.

Далее настройте сгенерированный код путем записи кода TLC

Если создание вашего собственного класса памяти путем управления свойствами в Custom Storage Class Designer не удовлетворяет требования, можно точно управлять сгенерированным кодом путем записи кода TLC для класса памяти. Используйте усовершенствованный режим Custom Storage Class Designer и, для класса памяти, установите Type на Other. Смотрите точно представление данных управления путем записи кода TLC для класса памяти.

Похожие темы