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

Для некоторых приложений можно использовать прагмы и другие художественные оформления кода, чтобы управлять размещением данных (глобальные переменные) и функциональные определения в памяти. Например, конфигурационный файл компоновщика может задать названные разделы в SECTIONS директива и карта каждый раздел к области значений адресов памяти. В коде С вы включаете прагмы, которые присваивают глобальные переменные и функции к этим именованным разделам и, следовательно, к диапазонам памяти. Путем управления размещением памяти вы можете:

  • Сгенерируйте код, который более эффективен для вашего оборудования.

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

С разделами Embedded Coder® и memory вы можете:

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

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

    • Примените прагму по умолчанию к категориям сгенерированных функций, включая функции точки входа, такие как modelшаг.

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

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

Вставьте прагмы при помощи разделов памяти

В этом примере вы конфигурируете размещение памяти по умолчанию для всех данных и функций алгоритма, представленного моделью rtwdemo_roll в качестве примера. Затем для некоторых данных сигнала вы заменяете размещение по умолчанию.

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

  1. Откройте модель в качестве примера.

    open_system('rtwdemo_roll')
    

    Модель сконфигурирована, чтобы сгенерировать эффективный производственный код. Например, параметр конфигурации Default parameter behavior установлен в Inlined.

  2. В галерее Apps, под Code generation, нажимают Embedded Coder. Вкладка C Code открывается. Сгенерируйте код из модели.

  3. В отчете генерации кода смотрите файл rtwdemo_roll.h. Файл задает типы структуры, которые представляют данные, в которых нужен алгоритм. Например, файл задает тип структуры, который представляет состояния блока, такие как состояния блоков Discrete-Time Integrator.

    /* Block signals and states (default storage) for system '<Root>' */
    typedef struct {
      real32_T FixPtUnitDelay1_DSTATE;     /* '<S7>/FixPt Unit Delay1' */
      real32_T Integrator_DSTATE;          /* '<S1>/Integrator' */
      int8_T Integrator_PrevResetState;    /* '<S1>/Integrator' */
    } DW;
    

    Файл также объявляет функции точки входа для модели.

    /* Model entry point functions */
    extern void rtwdemo_roll_initialize(void);
    extern void rtwdemo_roll_step(void);
  4. Смотрите rtwdemo_roll.c. Этот файл задает глобальные переменные структуры, чтобы хранить данные. Файл также задает функции.

В этом примере примите, что ваш конфигурационный файл компоновщика задает названные разделы MYALGORITHM_DATA и MYALGORITHM_CODE в SECTIONS директива. Можно сконфигурировать модель так, чтобы сгенерированный код включал прагмы, помещая память, выделенную для данных и функций в этих именованных разделах.

  • Для глобальной переменной под названием myVar, синтаксис прагмы:

    #pragma SEC_MYALGORITHM_DATA("myVar")
    
    double myVar;

  • Для функции с именем myFunction, синтаксис прагмы является тем же самым за исключением имени раздела:

    #pragma SEC_MYALGORITHM_CODE("myFunction")
    
    void myFunction(void)

Создайте разделы памяти

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

  1. Откройте приложение Embedded Coder. На вкладке C Code выберите Code Interface> Embedded Coder Dictionary.

  2. В диалоговом окне Embedded Coder Dictionary выберите вкладку Memory Sections и нажмите кнопку Add.

  3. Для нового раздела memory, набор эти опции:

    • Name к MYALGORITHM_DATA.

    • Statements Surround к Each variable.

    • Pre Statement к #pragma SEC_MYALGORITHM_DATA("$N"). Маркерный $N обозначает имя каждой переменной, которая использует раздел memory.

  4. Создайте другого, подобный раздел memory, который соответствует MYALGORITHM_CODE.

Сконфигурируйте прагмы по умолчанию для данных и функций

  1. На вкладке C Code выберите Code Interface> Default Code Mappings или Code Interface> Individual Element Code Mappings

  2. Во вкладке Data Defaults расширьте Inports and Outports, Signals и Parameters.

  3. В таблице выберите строку Inports.

  4. В Property Inspector, набор Memory Section к MYALGORITHM_DATA.

  5. Для других строк в таблице, набор Memory Section к MYALGORITHM_DATA.

  6. Под Function Defaults, для каждой строки в таблице, устанавливает Memory Section на MYALGORITHM_CODE.

  7. В вашей текущей папке удалите существующий slprj папка.

  8. Сконфигурируйте модель, чтобы сгенерировать только код. Выберите параметр конфигурации Configuration Parameters> Generate code only.

  9. Нажмите Generate Code.

Теперь rtwdemo_roll.c файл применяет прагмы к определениям переменных структуры и функций. Для каждой категории данных и функций, которые вы сконфигурировали в редакторе Отображений Кода, код применяет прагму. Например, код применяет MYALGORITHM_DATA прагма к каждой из структур, которые хранят состояния блока, входные параметры корневого уровня и корневой уровень выходные параметры.

/* Block signals and states (default storage) */
#pragma SEC_MYALGORITHM_DATA("rtDW")

DW rtDW;

/* External inputs (root inport signals with default storage) */
#pragma SEC_MYALGORITHM_DATA("rtU")

ExtU rtU;

/* External outputs (root outports fed by signals with default storage) */
#pragma SEC_MYALGORITHM_DATA("rtY")

ExtY rtY;

Сохраните раздел Default Memory после применения класса памяти по умолчанию или шаблона функции

В редакторе Отображений Кода можно использовать Storage Class и столбцы Function Customization Template, чтобы управлять внешним видом по умолчанию данных и функций в сгенерированном коде. Когда вы используете эти столбцы, чтобы применить установку кроме Default, редактор Отображений Кода отбрасывает раздел memory, который вы применили в Property Inspector. Чтобы сохранить раздел memory, используйте Словарь Embedded Coder, чтобы создать класс памяти или шаблон функции, затем примените раздел memory к тому классу памяти или шаблону функции.

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

  1. В Словаре Embedded Coder для модели выберите вкладку Storage Classes и нажмите кнопку Add.

  2. Для нового класса памяти, набора:

    • Name к STRUCT_DATA.

    • Storage Type к Structured.

    • Memory Section к MYALGORITHM_DATA.

  3. В редакторе Отображений Кода, под Data Defaults, в столбце Storage Class, выбирают STRUCT_DATA для этих строк:

    • Inports

    • Outports

    • Signals, states and internal data

  4. Сгенерируйте код из модели.

  5. Смотрите rtwdemo_roll.c. Теперь файл задает одну переменную структуры, которая содержит данные о непараметре, применяя прагму к той переменной.

    /* Storage class 'STRUCT_DATA' */
    #pragma SEC_MYALGORITHM_DATA("STRUCT_DATA_rtwdemo_roll")
    
    rtwdemo_roll_STRUCT_DATA STRUCT_DATA_rtwdemo_roll;

Включите раздел Default Memory в класс памяти для отдельного отображения

Чтобы заменить классы памяти по умолчанию, которые вы задаете в Code Mappings - C> Data Defaults, примените класс памяти непосредственно к элементу данных при помощи редактора Отображений Кода. Непосредственно применяя класс памяти кроме Auto или Model default обходит раздел memory по умолчанию, который вы задаете в Data Defaults. Чтобы сохранить раздел memory, создайте класс памяти в Словаре Embedded Coder и примените желаемый раздел memory к нему. Затем примените класс памяти к отдельным элементам данных в редакторе Отображений Кода. Другие модели не могут получить доступ к классу памяти и разделу memory, который вы задаете в Словаре Embedded Coder. Чтобы совместно использовать класс памяти и разделы раздела memory среди других моделей, сохраните Словарь Embedded Coder в данных о Словаре Данных Simulink (sldd) за пределами вашей модели. Затем совместно используйте словарь между целевыми моделями. Для получения дополнительной информации смотрите, Перемещают Определения от Файла Модели до Словаря Разделяемых данных.

В rtwdemo_roll, в BasicRollMode подсистема, три блока Усиления представляют параметры алгоритма управления ПИДа. В разделе Retain Default Memory Section After Applying a Default Storage Class или Function Template сконфигурируйте данные о непараметре модели, такой как сигналы и состояния, чтобы появиться в той же структуре путем применения класса памяти по умолчанию STRUCT_DATA. В этом примере вы конфигурируете выходные сигналы блоков Усиления так, чтобы сгенерированный код выделил память для них в MYALGORITHM_DATA разделите, но не появляйтесь в структуре класса памяти по умолчанию. Задайте новый класс памяти myStore в Словаре Embedded Coder и применяют желаемый раздел memory MYALGORITHM_DATA к нему. Затем непосредственно примените класс памяти к выходным сигналам блоков Усиления.

  1. В Словаре Embedded Coder модели выберите вкладку Storage Classes и нажмите кнопку Add.

  2. Для нового класса памяти, набора:

    • Name к myStore.

    • Storage Type к Structured.

    • Memory Section к MYALGORITHM_DATA.

  3. В модели перейдите в BasicRollMode подсистема. Сигналы подсистемы автоматически не заполняются в редактор Отображений Кода. Необходимо вручную добавить сигналы путем приостановки на замещающем знаке, который, кажется, выше или ниже сигнальной линии открывает строку меню. Нажмите кнопку Add Signal. Кнопка также доступна в редакторе Отображений Кода на вкладке Signals/States.

  4. После того, как вы добавите выходные сигналы блоков Усиления, строки сигнала появляются во вкладке Code Mappings -C> Signals/States . Откройте Property Inspector путем выбора строк сигнала. В Секции кода, набор эти свойства:

    • Storage Class к myStore.

    • Identifier к именам блока.

  5. Сгенерируйте код из модели.

  6. Смотрите сгенерированный файл rtwdemo_roll.c. Файл задает переменную myStore_rtwdemo_roll структуры и применяет прагму к переменной.

    /* Storage class 'myStore' */
    #pragma SEC_MYALGORITHM_DATA("myStore_rtwdemo_roll")
    
    rtwdemo_roll_myStore myStore_rtwdemo_roll;

  7. Смотрите сгенерированный файл rtwdemo_roll.h. Переменная структуры содержит выходные сигналы блоков Усиления. Выходные сигналы находятся теперь в отличной структуре, но сохранены в том же MYALGORITHM_DATA раздел memory.

/* Storage class 'myStore', for system '<Root>' */
typedef struct {
  real32_T DispGain;                   /* '<S1>/DispGain' */
  real32_T RateGain;                   /* '<S1>/RateGain' */
  real32_T IntGain;                    /* '<S1>/IntGain' */
} rtwdemo_roll_myStore;

Сконфигурируйте прагму, чтобы окружить группы определений

Если ваш набор инструментальных средств сборки требует, чтобы прагма или другое художественное оформление окружили повторные определения переменных или функций целиком, в Словаре Embedded Coder или Custom Storage Class Designer, установили Statements surround на Group of variables (значение по умолчанию в Custom Storage Class Designer).

Замените размещение памяти по умолчанию для отдельных элементов данных

После того, как вы конфигурируете значения по умолчанию раздела memory в редакторе Отображений Кода (см., Конфигурируют генерацию кода C По умолчанию для Категорий Элементов данных и Функций), чтобы заменить эти настройки по умолчанию для отдельных элементов данных (сигналы, параметры, и состояния), создать класс памяти и любые необходимые разделы памяти при помощи Словаря Embedded Coder. Для получения дополнительной информации смотрите, Выберите Where to Create и Store Memory Section Definition. Когда вы создаете класс памяти, устанавливаете свойство Memory section на соответствующий раздел memory. Затем используйте редактор Отображений Кода, чтобы применить класс памяти к отдельным элементам данных.

Выберите Where to Create и Store Memory Section Definition

Чтобы задать раздел memory, необходимо выбрать, где создать его: в Словаре Embedded Coder или в Simulink Разделяемый Словарь.

  • Если необходимо использовать раздел memory только в редакторе Отображений Кода, задайте раздел memory в Словаре Embedded Coder.

    Если необходимо использовать раздел memory только в редакторе Отображений Кода и хотеть совместно использовать его с другими моделями, задать раздел memory в словаре данных Simulink® (sldd). Для получения дополнительной информации см. Словарное определение Embedded Coder Доли Между Моделями.

  • Если необходимо использовать раздел memory за пределами редактора Отображений Кода, задайте раздел memory в пакете. Например, задайте разделы памяти в пакете, чтобы сконфигурировать разделы памяти атомарной подсистемы. Для получения дополнительной информации смотрите Раздел Override Memory для Атомарной подсистемы.

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

Замените размещение памяти по умолчанию для функций подсистемы и данных

Когда вы используете атомарные подсистемы, чтобы разделить сгенерированный код в функции (см., Генерируют Код Подсистемы как Отдельную функцию и Файлы), можно применить различные разделы памяти к функциям и данным каждой подсистемы. Можно также указать, что подсистема не использует раздел memory.

Замените раздел Memory для атомарной подсистемы

Разделы memory, которые вы задаете для подсистемы, заменяют значения по умолчанию уровня модели, которые вы устанавливаете в редакторе Отображений Кода. Используйте этот метод, чтобы агрегировать код данных и систему команд для стандартных подпрограмм или субкомпонентов (представленный подсистемами) в различные области памяти. Чтобы применить раздел memory непосредственно к атомарной подсистеме, задайте раздел memory в пакете при помощи Custom Storage Class Designer. Вы не можете использовать раздел memory, который вы задаете в Словаре Embedded Coder. Затем загрузите пакет в модель и сконфигурируйте параметры блоков подсистемы, чтобы задать раздел memory.

Создать раздел memory:

  1. В вашей текущей папке создайте папку под названием +myPackage. Папка задает пакет под названием myPackage. Для получения дополнительной информации смотрите, Создают Пакет Класса Данных.

    Чтобы сделать пакет доступным за пределами вашей текущей папки, опционально, можно добавить папку, содержащую +myPackage папка к пути MATLAB.

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

    cscdesigner('myPackage');
    
  3. В Custom Storage Class Designer выберите вкладку Memory Section.

  4. Нажмите New.

  5. Для нового раздела memory, набор эти опции:

    • Name к MYALGORITHM_DATA.

    • Statements surround к Each variable.

    • Pre statement к #pragma SEC_MYALGORITHM_DATA("$N").

  6. Нажмите Apply и Save.

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

Применять раздел memory в атомарной подсистеме:

  1. Сконфигурируйте Словарь Embedded Coder модели, чтобы загрузить целевой пакет как описано в, Обращаются к Определениям Генерации кода в Пакете.

  2. Чтобы сконфигурировать целевую подсистему, чтобы задать раздел memory, откройте диалоговое окно параметров подсистемы. На вкладке Code Generation:

    • Установите Function packaging на Nonreusable function или Reusable function (для повторно используемого кода).

    • Если вы устанавливаете Function packaging на Nonreusable function, чтобы включить настройку разделов памяти для данных о подсистеме, выберите Function with separate data. Если вы не выбираете Function with separate data, данные о подсистеме наследовали разделы памяти от модели или, если применимо, родительская подсистема.

    • Применять MYALGORITHM_DATA раздел memory непосредственно к функциям подсистемы и данным, используйте эти параметры блоков:

      • Memory section for initialize/terminate functions

      • Memory section for execution functions

      • Memory section for constants

      • Memory section for internal data

      • Memory section for parameters

Укажите, что атомарная подсистема не использует раздел Memory

По умолчанию функции подсистемы и данные наследовали разделы памяти уровня модели, которые вы задаете для соответствующей функции и категорий данных в редакторе Отображений Кода. Например, если вы задаете функциональный шаблон настройки для категории Execution, и тот шаблон несет раздел memory, раздел memory применяется к функциям выполнения подсистемы, а также функциям выполнения точки входа модели.

Чтобы указать, что подсистема не использует раздел memory, откройте диалоговое окно параметров подсистемы. На вкладке Code Generation, установленной эти параметры на Default:

  • Memory section for initialize/terminate functions

  • Memory section for execution functions

  • Memory section for constants

  • Memory section for internal data

  • Memory section for parameters

С этими настройками подсистема не использует раздел memory для данных или функций, которые представляет каждый параметр.

Ограничения и другие факторы

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

  • Если вы используете Build This Subsystem или Build Selected Subsystem, чтобы сгенерировать код для атомарной подсистемы, которая задает разделы памяти, генератор кода игнорирует технические требования уровня подсистемы и использует технические требования уровня модели вместо этого. Для получения информации о создании подсистем смотрите, Генерируют Код и Исполняемые файлы для Отдельных Подсистем.

Совместно используйте раздел Memory между пакетами (память пакета разделяет только),

Пакеты могут получить доступ и использовать разделы памяти, которые заданы в других пакетах, включая пользовательские пакеты и встроенные пакеты, такие как Simulink. Только одна копия раздела memory существует в пакете, который задает его. Другие пакеты относятся к разделу memory, указывая на него в его исходном местоположении. Изменения в разделе memory, включая изменения во встроенном разделе memory в более поздних версиях продукта MathWorks®, сразу доступны в каждом пакете ссылки.

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

  1. Откройте Custom Storage Class Designer. В командной строке введите cscdesigner.

  2. Выберите вкладку Раздела Memory.

  3. Использование Выбирать Package, чтобы выбрать пакет, в котором вы хотите сослаться на класс или раздел, заданный в некотором другом пакете.

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

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

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

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

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

  8. Раздел Set Memory к ссылке, чтобы задать раздел memory, на который сошлются.

  9. Нажмите ОК или Применяйтесь, чтобы сохранить изменения в памяти. Чтобы сохранить изменения постоянно, нажмите Save.

Управляйте внешним видом раздела Memory выпадающий список (память пакета разделяет только),

Когда вы применяете раздел memory пакета, вы выбираете раздел memory из выпадающего списка. Чтобы управлять порядком разделов memory в списке, в Custom Storage Class Designer, используют кнопки Up и Down. Порядок разделов памяти в выпадающих списках совпадает с порядком в Custom Storage Class Designer.

Защитите определения разделов памяти пакета (память пакета разделяет только),

Когда вы нажимаете Save в Custom Storage Class Designer, Разработчик сохраняет раздел memory и пользовательские определения класса памяти в csc_registration.m файл в папке пакета. Чтобы определить местоположение этого файла, в Custom Storage Class Designer, смотрят значение Filename.

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

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

.

Ограничения

  • Генератор кода не применяет разделы памяти к данным, которые используют эти встроенные классы памяти:

    • ExportedGlobal

    • ImportedExtern

    • ImportedExternPointer

  • В Custom Storage Class Designer спецификатор типа хранения, который вы задаете для раздела memory при помощи текстового поля Qualifier, влияет только на элементы данных, которые используют установку класса памяти кроме этих встроенных классов памяти:

    • ExportedGlobal

    • ImportedExtern

    • ImportedExternPointer

    Генератор кода не использует спецификатор от других категорий данных.

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

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

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

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

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

open_system('rtwdemo_memsec')

  1. Чтобы просмотреть разделы memory в пакете ECoderDemos, нажмите кнопку Memory Section Definitions в модели и затем выберите вкладку Разделов Memory.

  2. Чтобы сконфигурировать разделы memory для функций и данных, нажмите кнопку Configure Memory Sections For This Model. В редакторе Отображений Кода выберите соответствующую строку, и затем задайте разделы памяти в Property Inspector.

  3. Настройки уровня модели являются настройками по умолчанию для атомарных подсистем. Откройте параметр подсистемы выпадающие списки, чтобы видеть настройки раздела memory для каждой из атомарных подсистем в модели. Можно заменить установку уровня модели по умолчанию путем конфигурирования параметров блоков подсистемы.

  4. Чтобы сгенерировать код, нажмите кнопку Generate Code Using Embedded Coder. Отчет генерации кода открывается автоматически. Смотрите данные и функциональные определения в .c файлы и наблюдают, как сгенерированные прагмы соответствуют заданным разделам памяти.

Похожие темы