exponenta event banner

Создание классов хранения с помощью пользовательского конструктора классов хранения

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

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

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

Сведения об использовании конструктора пользовательских классов хранения для создания разделов памяти см. в разделе Управление данными и размещением функций в памяти путем вставки прагматиков.

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

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

Изучение примера модели

Откройте 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. Откройте конструктор классов настраиваемых хранилищ.

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

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

  5. В выпадающем списке Файл заголовка измените выбор с Instance specific кому Specify. В новом поле укажите имя файла заголовка. global.h.

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

  7. Нажмите кнопку ОК. Нажмите кнопку Да, чтобы сохранить изменения в пакете классов данных 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. Создайте код для примерной модели.

    slbuild('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 файл, а затем откройте конструктор пользовательских классов хранения впервые в этом пакете, Simulink копирует определения встроенных классов хранения в пакет. Затем в конструкторе пользовательских классов хранения можно изменить скопированные определения. Чтобы сохранить встроенные классы хранения в пакете, скопируйте один из них, нажав кнопку Копировать, а затем измените результирующую копию.

Управление представлением данных путем настройки свойств класса хранения

Custom Storage Class Designer - это инструмент для создания классов хранения и разделов памяти и управления ими. Чтобы открыть Custom Storage Class Designer для определенного пакета, например, +mypkg, в командной строке используйте команду cscdesigner функция:

cscdesigner('mypkg')

Имя папки, представляющей пакет, начинается с +. При использовании функции cscdesigner, опустить + из имени целевого пакета.

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

Вид данных в сгенерированном кодеТехника
СтруктураЗадать тип для FlatStructure. См. раздел Создание структурированных данных.
МакросУстановить инициализацию данных на Macro и очистить Для сигналов. См. раздел Создание макроса.
УказательЗадать доступ к данным для Pointer и Объем данных для Auto, Imported, или Instance specific. Внешний код должен определять переменную указателя.
static данные (данные в области файла)Задайте для области данных значение File.
const или volatile данныеУстановите раздел «Память» в раздел «Память», определяющий const, volatileили и то и другое. Например, используйте один из встроенных разделов памяти MemConst, MemVolatile, и MemConstVolatile. Чтобы создать собственный раздел памяти, см. раздел Управление данными и размещением функций в памяти путем вставки прагматиков.
Вызовы внешних функций для чтения и записи в данныеСм. раздел Вызов пользовательских функций доступа или макросов вместо чтения и записи в переменные.

Разрешить пользователям класса хранения указывать значение свойства

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

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

В конструкторе пользовательских классов хранения для каждого свойства, которое необходимо настроить таким образом, задайте значение свойства, равное Instance specific. Затем, когда пользователь применяет класс хранения к элементу данных, свойство отображается пользователю как пользовательский атрибут для этого элемента данных. Сведения о пользовательских атрибутах экземпляра см. в разделе Свойства класса хранилища.

Создание макроса

Чтобы создать класс хранения, который дает макрос в генерируемом коде, задайте для параметра Инициализация данных значение Macro и очистить Для сигналов.

При установке для параметра Инициализация данных значения Macro, Файл определения не имеет значения. Чтобы запретить пользователям класса хранения указывать бессмысленный файл определения, в конструкторе настраиваемых классов хранения задайте для параметра Файл определения значение Specify и оставьте текстовое поле пустым.

  • Определение макроса в файле заголовка (#define), укажите имя файла заголовка со свойством Header file.

  • Чтобы предоставить определение макроса в качестве параметра компилятора или флага компилятора, задайте для параметра Доступ к данным значение Imported и Header file to Specify. Оставьте текстовое поле Header file пустым. Затем сгенерированный код не определяет макрос и не включает (#include) файл заголовка.

    Чтобы указать параметр или флаг компилятора, используйте параметр конфигурации модели Параметры конфигурации > Создание кода > Пользовательский код > Дополнительные сведения о построении > Определение. См. раздел Область создания кода: Пользовательский код: Дополнительные сведения о построении: Определение.

Создание структурированных данных

Создание класса хранения, объединяющего элементы данных в плоскую структуру (аналогично встроенному классу хранения) Struct), установите Тип в FlatStructure. Откроется вкладка Атрибуты структуры (Structure Attributes).

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

  • Если задано имя Struct Instance specific, пользователи класса хранения указывают имя структурной переменной. В этом случае генератор кода извлекает имя типа структуры из имени переменной.

    Для более точного управления именем и другими характеристиками типа структуры задайте для параметра Имя структуры значение Specify. Управление характеристиками типа осуществляется с помощью отображаемых дополнительных свойств.

  • Создание структуры с битовыми полями (аналогично встроенному классу хранения BitField), выберите Bit-pack boolean. Элементы данных, использующие тип данных boolean отображаются в сгенерированном коде как битовые поля структуры.

Управление присвоением начального значения в сгенерированном коде

  • Чтобы использовать стратегию инициализации Simulink ® Coder™ по умолчанию, установите для параметра Инициализация данных значение по умолчанию ,Auto.

    • Созданный код статически инициализирует данные параметров с помощью оператора назначения в верхней части .c или .cpp исходный файл, за пределами любой функции.

    • Сформированный код динамически инициализирует данные сигнала и состояния как часть функции инициализации модели (именуется model_initialize по умолчанию).

  • Чтобы статически инициализировать данные, установите для параметра Data initialization значение Static.

  • Чтобы динамически инициализировать данные, установите для параметра Инициализация данных значение Dynamic.

  • Чтобы предотвратить инициализацию данных сгенерированным кодом, установите для параметра Инициализация данных значение None. Когда внешний код инициализирует данные, используйте этот параметр, чтобы предотвратить перезапись созданного кода.

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

Использование встроенного класса хранения GetSetвместо непосредственного взаимодействия с переменными можно создать код, вызывающий внешние пользовательские функции. Для получения общей информации о GetSetсм. раздел Доступ к данным через функции с помощью класса хранения GetSet.

Чтобы создать аналогичный класс хранения, задайте для параметра Тип значение 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. В этом случае файл определения не имеет значения. Чтобы запретить пользователям класса хранения указывать бессмысленный файл определения, задайте для параметра Файл определения значение Specify и оставьте текстовое поле пустым.

  • При внедрении get механизм для скалярных данных или данных массива в качестве макроса вместо функции, можно создать код, который пропускает круглые скобки при чтении этих данных. На вкладке Атрибуты функции доступа выберите Получить данные через макрос (опустить круглые скобки).

Создание кода, использующего данные из внешнего кода

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

  • Если код определяет переменную указателя, для создания кода, взаимодействующего с указателем, задайте для параметра Доступ к данным значение Pointer.

  • При создании структурированных данных с помощью параметра Тип (Type) FlatStructure, код должен определять тип структуры и глобальную структурную переменную.

  • Если код инициализирует данные о состоянии или сигнале, можно предотвратить перезапись сгенерированного кода, установив для параметра Инициализация данных значение None. См. раздел Предотвращение дублирования кода инициализации для глобальных переменных

Создание комментариев кода с определениями и объявлениями данных

Чтобы настроить комментарии, отображаемые в созданном коде, на вкладке Комментарии установите для Правила комментариев значение Specify. Чтобы указать комментарий, отображаемый вместе с объявлением каждого элемента данных, используйте поле Комментарий к объявлению (Declaration comment). Чтобы указать комментарий, отображаемый вместе с определением, используйте поле Комментарий определения (Definition comment).

Для структурированных данных (для параметра Тип установлено значение FlatStructure), чтобы указать комментарий, отображаемый с определением типа структуры, используйте поле Комментарий типа (Type comment).

Избегайте ошибок при создании кода путем проверки конфигурации класса хранения

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

Например, проверка класса хранения предупреждает, если вы случайно установили для инициализации данных значение Macro с выбранными сигналами For. Сигнал не может отображаться в сгенерированном коде как макрос.

Сделать классы хранения доступными вне текущей папки

Для использования создаваемого класса хранения необходимо сделать доступным определяющий пакет. Установите текущую папку в папку, содержащую пакет, или добавьте папку, содержащую папку пакета, к пути MATLAB ® (см. раздел Что такое путь поиска MATLAB?). Добавление пакета в путь MATLAB позволяет использовать классы хранения независимо от места установки текущей папки.

Сделать классы хранения доступными в редакторе сопоставлений кодов

Чтобы использовать классы хранения на основе пакетов в редакторе сопоставлений кодов, обратитесь к пакету из словаря встроенного кодера. Сведения о настройке словаря встроенного кодера для обращения к пакету см. в разделе Определения генерации кода в пакете.

Совместное использование класса хранения между пакетами

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

Настройка пакета для обращения к классу хранения, определенному другим пакетом:

  1. В конструкторе классов настраиваемых хранилищ выберите вкладку Класс настраиваемых хранилищ.

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

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

  4. Щелкните Создать привязку (New Reference).

    Новая ссылка с именем и свойствами по умолчанию появится под ранее выбранным определением. Будет выбрана новая привязка, и появится вкладка Привязка (Reference), на которой будут показаны исходные свойства.

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

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

  7. Задайте для настраиваемого класса хранения значение reference, чтобы указать класс хранения для ссылки.

  8. Нажмите кнопку ОК или Применить. Чтобы сохранить изменения навсегда, нажмите кнопку Сохранить.

Управление внешним видом раскрывающегося списка классов хранения

При применении класса хранения к элементу данных класс хранения выбирается из раскрывающегося списка.

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

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

    Например, если класс хранения выдает макрос в созданном коде, то инициализация данных будет иметь значение Macro, чтобы запретить пользователям применять класс хранения к данным сигналов, снимите флажок Для сигналов.

Защита определений классов настраиваемых хранилищ

При нажатии кнопки Сохранить в пользовательском конструкторе классов хранения конструктор сохраняет разделы памяти и определения классов хранения в csc_registration.m в папке пакета. Чтобы определить расположение этого файла, в конструкторе настраиваемых классов хранилища проверьте значение Filename.

Можно предотвратить изменения определений классов хранения всего пакета, преобразовав csc_registration.m из файла MATLAB в P-файл. Используйте pcode функция.

Передовой практикой является сохранение csc_registration.m и csc_registration.p в папке пакета. Таким образом, при изменении классов хранения с помощью конструктора можно удалить csc_registration.p а затем регенерировать его после завершения изменений. Поскольку P-кодированная версия файла имеет приоритет, при наличии обоих файлов в пакете классы хранения защищены, и их нельзя изменить в пользовательском конструкторе классов хранения.

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

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

Связанные темы