Для некоторых приложений можно использовать прагмы и другие художественные оформления кода, чтобы управлять размещением данных (глобальные переменные) и функциональные определения в памяти. Например, конфигурационный файл компоновщика может задать названные разделы в SECTIONS
директива и карта каждый раздел к области значений адресов памяти. В коде С вы включаете прагмы, которые присваивают глобальные переменные и функции к этим именованным разделам и, следовательно, к диапазонам памяти. Путем управления размещением памяти вы можете:
Сгенерируйте код, который более эффективен для вашего оборудования.
Постройте свой код приложения из модулей для более легкого обслуживания и модификации позже в процессе разработки и после развертывания.
С разделами Embedded Coder® и memory вы можете:
Примените прагмы по умолчанию или другие художественные оформления к категориям функций точки входа и данных модели. Чтобы сконфигурировать эти значения по умолчанию, используйте редактор Отображений Кода. Например, вы можете:
Примените прагму по умолчанию к внутренним данным, которые включают состояния блока, которые генератор кода не может устранить посредством оптимизации. Можно применить различную прагму по умолчанию к постоянным параметрам, таким как нескалярные параметры, которые сгенерированный код должен сохранить в памяти.
Примените прагму по умолчанию к категориям сгенерированных функций, включая функции точки входа, такие как
.model
шаг
Замените прагмы по умолчанию для отдельных элементов данных, таких как параметры блоков, состояния и сигналы. Для этого создайте свой собственный класс памяти.
Замените прагмы по умолчанию для отдельных функций, которые соответствуют атомарным подсистемам, которые можно сконфигурировать, чтобы появиться в сгенерированном коде как отдельные функции с отдельными данными. Используйте диалоговое окно параметров подсистемы.
В этом примере вы конфигурируете размещение памяти по умолчанию для всех данных и функций алгоритма, представленного моделью rtwdemo_roll
в качестве примера. Затем для некоторых данных сигнала вы заменяете размещение по умолчанию.
Откройте модель в качестве примера.
open_system('rtwdemo_roll')
Модель сконфигурирована, чтобы сгенерировать эффективный производственный код. Например, параметр конфигурации Default parameter behavior установлен в Inlined
.
В галерее Apps, под Code generation, нажимают Embedded Coder. Вкладка C Code открывается. Сгенерируйте код из модели.
В отчете генерации кода смотрите файл rtwdemo_roll.h
. Файл задает типы структуры, которые представляют данные, в которых нужен алгоритм. Например, файл задает тип структуры, который представляет состояния блока, такие как состояния блоков Discrete-Time Integrator.
/* Block 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_rtwdemo_roll_T;
Файл также объявляет функции точки входа для модели.
/* Model entry point functions */ extern void rtwdemo_roll_initialize(void); extern void rtwdemo_roll_step(void);
Смотрите 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)
В этом примере вы используете две прагмы с различными синтаксисами, таким образом, необходимо создать два раздела памяти.
Под блок-схемой, под Code Mappings - C> Data Defaults, кликают по значку Embedded Coder Dictionary.
В диалоговом окне Embedded Coder Dictionary выберите вкладку Memory Sections.
Нажмите кнопку Add.
Для нового раздела memory, набор эти опции:
Name к MYALGORITHM_DATA
.
Statements Surround к Each variable
.
Pre Statement к #pragma SEC_MYALGORITHM_DATA("$N")
. Маркерный $N
обозначает имя каждой переменной, которая использует раздел memory.
Создайте другого, подобный раздел memory, который соответствует MYALGORITHM_CODE
.
В модели смотрите вкладку Code Mappings - C> Data Defaults.
В таблице выберите строку Inports.
В Property Inspector, набор Memory Section к MYALGORITHM_DATA
.
Для других строк в таблице, набор Memory Section к MYALGORITHM_DATA
.
Под Function Defaults, для каждой строки в таблице, устанавливает Memory Section на MYALGORITHM_CODE
.
В вашей текущей папке удалите существующий slprj
папка.
Сконфигурируйте модель, чтобы сгенерировать только код. Выберите параметр конфигурации Configuration Parameters> Generate code only.
Сгенерируйте код из модели.
Теперь rtwdemo_roll.c
файл применяет прагмы к определениям переменных структуры и функций. Для каждой категории данных и функций, которые вы сконфигурировали в редакторе Отображений Кода, код применяет прагму. Например, код применяет MYALGORITHM_DATA
прагма к каждой из структур, которые хранят состояния блока, входные параметры корневого уровня и корневой уровень выходные параметры.
/* Block states (default storage) */ #pragma SEC_MYALGORITHM_DATA("rtwdemo_roll_DW") DW_rtwdemo_roll_T rtwdemo_roll_DW; /* External inputs (root inport signals with default storage) */ #pragma SEC_MYALGORITHM_DATA("rtwdemo_roll_U") ExtU_rtwdemo_roll_T rtwdemo_roll_U; /* External outputs (root outports fed by signals with default storage) */ #pragma SEC_MYALGORITHM_DATA("rtwdemo_roll_Y") ExtY_rtwdemo_roll_T rtwdemo_roll_Y;
В редакторе Отображений Кода можно использовать Storage Class и столбцы Function Customization Template, чтобы управлять внешним видом по умолчанию данных и функций в сгенерированном коде. Когда вы используете эти столбцы, чтобы применить установку кроме Default
, редактор Отображений Кода отбрасывает раздел memory, который вы применили в Property Inspector. Чтобы сохранить раздел memory, используйте Словарь Embedded Coder, чтобы создать класс памяти или шаблон функции, затем примените раздел memory к тому классу памяти или шаблону функции.
В этом примере вы конфигурируете данные о непараметре модели, такой как сигналы и состояния, чтобы появиться в той же структуре путем создания класса памяти. Сохранить MYALGORITHM_DATA
раздел memory, вы применяете раздел memory к классу памяти.
В Словаре Embedded Coder для модели выберите вкладку Storage Classes и нажмите кнопку Add.
Для нового класса памяти, набора:
Name к STRUCT_DATA
.
Storage Type к Structured
.
Memory Section к MYALGORITHM_DATA
.
В редакторе Отображений Кода, под Data Defaults, в столбце Storage Class, выбирают STRUCT_DATA
для всех строк кроме:
External parameter objects
Model parameters
Global data stores
Constants
Сгенерируйте код из модели.
Смотрите rtwdemo_roll.c
. Теперь файл задает одну переменную структуры, которая содержит данные о непараметре, применяя прагму к той переменной.
/* Storage class 'STRUCT_DATA' */ #pragma SEC_MYALGORITHM_DATA("STRUCT_DATA_rtwdemo_roll") rtwdemo_roll_STRUCT_DATA STRUCT_DATA_rtwdemo_roll;
Чтобы заменить классы памяти по умолчанию, которые вы задаете в Code Mappings - C> Data Defaults, можно применить класс памяти непосредственно к элементу данных при помощи Model Data Editor. Непосредственно применяя любой класс памяти кроме Auto
или Model default
обходит раздел memory по умолчанию, который вы задаете в Data Defaults. Чтобы сохранить раздел memory, необходимо переместить определение раздела memory из Словаря Embedded Coder и в пакет, который является папкой, которая может содержать определения раздела memory и класс памяти. Затем можно создать класс памяти в пакете, применить раздел memory к классу памяти и применить класс памяти непосредственно к отдельным элементам данных в Model Data Editor.
В rtwdemo_roll
, в BasicRollMode
подсистема, три блока Усиления представляют параметры алгоритма управления ПИДа. В этом примере вы конфигурируете выходные сигналы этих блоков так, чтобы сгенерированный код выделил память для них и поместил память в MYALGORITHM_DATA
раздел. Вы также конфигурируете сигналы так, чтобы код задал их в mySigs.c
и объявляет их в mySigs.h
.
Создать раздел memory и класс памяти:
В вашей текущей папке создайте папку под названием +myPackage
. Папка задает пакет под названием myPackage
.
Чтобы сделать пакет доступным за пределами вашей текущей папки, опционально, можно добавить папку, содержащую +myPackage
папка к пути MATLAB.
Откройте Custom Storage Class Designer.
cscdesigner('myPackage');
В Custom Storage Class Designer выберите вкладку Memory Section.
Нажмите New.
Для нового раздела memory, устанавливает эти опции, которые совпадают с опциями, которые вы устанавливаете для MYALGORITHM_DATA
в словаре Embedded Coder:
Name к MYALGORITHM_DATA
.
Statements surround к Each variable
.
Pre statement к #pragma SEC_MYALGORITHM_DATA("$N")
.
Нажмите Apply и Save.
В myPackage
папка пакета, создайте папку под названием @Signal
.
В @Signal
папка, создайте файл с именем Signal.m
.
classdef Signal < Simulink.Signal methods function setupCoderInfo(h) useLocalCustomStorageClasses(h, 'myPackage'); end function h = Signal() % SIGNAL Class constructor. end % End of constructor end % methods end % classdef
Файл задает класс под названием myPackage.Signal
, который выведен из встроенного класса Simulink.Signal
. Определение класса заменяет setupCoderInfo
метод, который Simulink.Signal
класс уже реализует. Новая реализация указывает что объекты myPackage.Signal
использование класса пользовательские классы памяти от myPackage
пакет вместо пользовательских классов памяти от встроенного Simulink
пакет.
Установите свою текущую папку на папку, которая содержит +myPackage
папка.
В Custom Storage Class Designer для myPackage
, выберите вкладку Custom Storage Class.
Нажмите New.
Для нового пользовательского класса памяти, набор эти свойства:
Name к myCSC
.
Очистите For parameters.
Memory section к MYALGORITHM_DATA
.
Data scope к Exported
.
Header file к mySigs.h
.
Definition file к mySigs.c
.
Нажмите Apply и Save.
Применять класс памяти в модели:
В модели, на вкладке Modeling, выбирают Model Explorer.
В панели Model Hierarchy Model Explorer выберите Base Workspace.
На панели инструментов Model Explorer кликните по стреле рядом с кнопкой Add Signal и выберите Customize class lists.
В диалоговом окне Customize class lists, под Signal classes, устанавливают флажок рядом с myPackage.Signal и нажимают OK.
В Model Explorer кликните по стреле рядом с Add Signal снова и выберите myPackage Signal. myPackage.Signal
объект появляется в базовом рабочем пространстве.
Удалите myPackage.Signal
объект от базового рабочего пространства. Теперь, когда вы используете Model Data Editor, чтобы применить классы памяти к сигналам, можно выбрать классы памяти из myPackage
пакет.
В модели перейдите в BasicRollMode
подсистема.
Под блок-схемой выберите вкладку Model Data Editor> Signals.
В модели выберите три блока Усиления.
В Model Data Editor, в таблице данных, для любой из подсвеченных строк, устанавливает Storage Class на myCSC
.
Сгенерируйте код из модели.
Смотрите сгенерированный файл mySigs.c
. Файл задает глобальные переменные, которые соответствуют блоку Gain выходные параметры в модели. Прагма применяется к определениям.
/* Definition for custom storage class: myCSC */ #pragma SEC_MYALGORITHM_DATA("DispGain") real32_T DispGain; #pragma SEC_MYALGORITHM_DATA("IntGain") real32_T IntGain; #pragma SEC_MYALGORITHM_DATA("RateGain") real32_T RateGain;
Теперь два определения MYALGORITHM_DATA
раздел memory существует: Один в Словаре Embedded Coder и один в myPackage
. Когда вы вносите изменения в раздел memory, вносите те же изменения для каждого определения.
Если ваш набор инструментальных средств сборки требует, чтобы прагма или другое художественное оформление окружили повторные определения переменных или функций целиком, в Словаре Embedded Coder или Custom Storage Class Designer, установили Statements surround на Group of variables
(значение по умолчанию в Custom Storage Class Designer).
После того, как вы конфигурируете значения по умолчанию раздела memory в редакторе Отображений Кода (см., Конфигурируют генерацию кода C По умолчанию для Категорий Данных модели и Функций), чтобы заменить эти настройки по умолчанию для отдельных элементов данных (сигналы, параметры, и состояния), создать класс памяти и любые необходимые разделы памяти при помощи Custom Storage Class Designer. В Разработчике, когда вы создаете класс памяти, устанавливают свойство Memory section на соответствующий раздел memory. Затем используйте Model Data Editor, чтобы применить класс памяти к отдельным элементам данных.
Чтобы задать раздел memory, необходимо выбрать, где создать его: в Словаре Embedded Coder или в пакете (при помощи Custom Storage Class Designer).
Если необходимо использовать раздел memory только в редакторе Отображений Кода, задайте раздел memory в Словаре Embedded Coder.
Если необходимо использовать раздел memory за пределами редактора Отображений Кода, например, в Model Data Editor, задайте раздел memory в пакете.
Опционально, можно включить использование раздела memory пакета в редакторе Отображений Кода путем загрузки пакета в Словарь Embedded Coder (см., Обращаются к Определениям Генерации кода в Пакете). Однако, если вы создаете классы памяти в словаре, вы не можете применить раздел memory пакета к ним. Чтобы сопоставить раздел memory с классами памяти, которые вы задаете в Словаре Embedded Coder и с другими классами памяти, которые вы задаете в пакете, обеспечьте два определения раздела memory: один в словаре и один в пакете.
Если вы задаете раздел memory в Словаре Embedded Coder модели, вы не можете использовать раздел memory в других моделях. Чтобы совместно использовать раздел memory, переместите определение словарю данных Simulink® (sldd
). Затем совместно используйте словарь между целевыми моделями. Для получения дополнительной информации см. Словарное определение Embedded Coder Доли Между Моделями.
Если вы задаете раздел memory в пакете, любая модель может использовать раздел memory. Добавьте папку, содержащую папку пакета к пути MATLAB® (см. то, Что Путь поиска файлов MATLAB? MATLAB.
Пакеты могут получить доступ и использовать разделы памяти, которые заданы в других пакетах, включая пользовательские пакеты и встроенные пакеты, такие как Simulink
. Только одна копия раздела memory существует в пакете, который задает его. Другие пакеты относятся к разделу memory, указывая на него в его исходном местоположении. Изменения в разделе memory, включая изменения во встроенном разделе memory в более поздних версиях продукта MathWorks®, сразу доступны в каждом пакете ссылки.
Чтобы сконфигурировать пакет, чтобы относиться к разделу memory, который задан в другом пакете:
Откройте Custom Storage Class Designer. В командной строке введите cscdesigner
.
Выберите вкладку Раздела Memory.
Использование Выбирать Package, чтобы выбрать пакет, в котором вы хотите сослаться на класс или раздел, заданный в некотором другом пакете.
В панели определений раздела Memory выберите существующее определение, ниже которого вы хотите вставить ссылку.
Нажмите New Reference.
Новая ссылка с именем по умолчанию и свойствами появляется ниже ранее выбранного определения. Новая ссылка выбрана, и вкладка Reference появляется, который показывает начальные свойства ссылки.
Используйте Поле имени, чтобы ввести имя для новой ссылки. Имя должно быть уникальным в пакете импорта, но может скопировать имя в исходном пакете.
Установите Относятся к разделу memory в пакете, чтобы задать пакет, который содержит раздел memory, на который вы хотите сослаться.
Раздел Set Memory к ссылке, чтобы задать раздел memory, на который сошлются.
Нажмите ОК или Применяйтесь, чтобы сохранить изменения в памяти. Чтобы сохранить изменения постоянно, нажмите Save.
Когда вы применяете раздел 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 защищены.
.
Когда вы используете атомарные подсистемы, чтобы разделить сгенерированный код в функции (см., Генерируют Код Подсистемы как Отдельную функцию и Файлы), можно применить различные разделы памяти к функциям и данным каждой подсистемы. Можно также указать, что подсистема не использует раздел memory.
Чтобы использовать различные разделы памяти, чтобы заменить значения по умолчанию уровня модели, которые вы устанавливаете в редакторе Отображений Кода, смотрите Раздел Override Memory для Атомарной подсистемы.
Чтобы указать, что подсистема не использует раздел memory (другими словами, чтобы препятствовать тому, чтобы подсистема наследовала значения по умолчанию уровня модели), видят, Указывают Что Атомарная подсистема Не Использование Раздел Memory.
Разделы memory, которые вы задаете для подсистемы, заменяют значения по умолчанию уровня модели, которые вы устанавливаете в редакторе Отображений Кода. Используйте этот метод, чтобы агрегировать код данных и систему команд для стандартных подпрограмм или субкомпонентов (представленный подсистемами) в различные области памяти. Применять раздел memory непосредственно к атомарной подсистеме:
Задайте разделы memory в пакете. Вы не можете использовать раздел memory, который вы задаете в Словаре Embedded Coder.
В целевой модели, набор Configuration Parameters> Code Generation> Advanced parameters> Memory Sections> Package к имени пакета. Если пакет не появляется в списке, нажмите Refresh package list.
Сконфигурируйте Словарь Embedded Coder модели, чтобы загрузить целевой пакет как описано в, Обращаются к Определениям Генерации кода в Пакете.
Сконфигурируйте целевую подсистему, чтобы использовать раздел memory. В диалоговом окне параметров подсистемы, на вкладке Code Generation:
Установите Function packaging на Nonreusable function
или Reusable function
(для повторно используемого кода).
Если вы устанавливаете Function packaging на Nonreusable function
, чтобы включить настройку разделов памяти для данных о подсистеме, выберите Function with separate data. Если вы не выбираете Function with separate data, данные о подсистеме наследовали разделы памяти от модели или, если применимо, родительская подсистема.
Используйте параметры, такие как Memory section for initialize/terminate functions, чтобы применить разделы памяти по умолчанию к функциям подсистемы и данным.
По умолчанию функции подсистемы и данные наследовали разделы памяти уровня модели, которые вы задаете для соответствующей функции и категорий данных в редакторе Отображений Кода. Например, если вы задаете функциональный шаблон настройки для категории Execution, и тот шаблон несет раздел memory, раздел memory применяется к функциям выполнения подсистемы, а также функциям выполнения точки входа модели.
Чтобы указать, что подсистема не использует раздел memory:
В целевой модели, набор Configuration Parameters> Code Generation> Advanced parameters> Memory Sections> Package к одному из этих значений:
Если Словарь Embedded Coder модели не обращается к определениям генерации кода в пакете (см., Обращаются к Определениям Генерации кода в Пакете), установите Package на Simulink
.
Если Словарь Embedded Coder модели относится к пакету, установите Package на тот пакет.
В целевой подсистеме, на вкладке Code Generation, установленные параметры, такие как Memory section for initialize/terminate functions к Default
. С этой установкой подсистема не использует раздел memory в данных или функциях, которые представляет каждый параметр.
Настройки, которые вы задаете для атомарной, подсистемы одноразового использования с отдельными данными, применяются только к данным и функциям той подсистемы, не к данным в столь же сконфигурированных дочерних подсистемах. Атомарные, дочерние подсистемы одноразового использования с отдельными данными могут наследовать разделы памяти от содержания модели, не от родительской подсистемы.
Если вы используете Build This Subsystem или Build Selected Subsystem, чтобы сгенерировать код для атомарной подсистемы, которая задает разделы памяти, генератор кода игнорирует технические требования уровня подсистемы и использует технические требования уровня модели вместо этого. Для получения информации о создании подсистем смотрите, Генерируют Код и Исполняемые файлы для Отдельных Подсистем (Simulink Coder).
В примере Вставляют Прагмы при помощи Разделов Памяти, чтобы применить раздел memory к отдельным элементам данных сигнала, вы создаете пользовательский класс памяти при помощи Custom Storage Class Designer. Предположим, что вы хотите применить различный раздел memory к каждому из сигналов. Вместо того, чтобы копировать пользовательский класс памяти (myCSC
) и соединение различного раздела memory с копией, которая приводит к двум очень похожим пользовательским классам памяти, к Custom Storage Class Designer, для myCSC
, установите Memory section на Instance specific
. Затем когда вы применяете пользовательский класс памяти к элементу данных, можно выбрать раздел memory для того элемента данных.
Генератор кода не применяет разделы памяти к данным, которые используют эти встроенные классы памяти:
ExportedGlobal
ImportedExtern
ImportedExternPointer
В Custom Storage Class Designer спецификатор типа хранения, который вы задаете для раздела memory при помощи текстового поля Qualifier, влияет только на элементы данных, которые используют установку класса памяти кроме этих встроенных классов памяти:
ExportedGlobal
ImportedExtern
ImportedExternPointer
Генератор кода не использует спецификатор от других категорий данных.
Когда вы создаете подсистему в библиотеке пользовательского блока, вы не можете задать разделы памяти для определения подсистемы в библиотеке. Вместо этого задайте разделы памяти для экземпляров подсистемы, которые вы помещаете в свои модели.
Эта модель показывает, как вставить прагмы для функций и данных в сгенерированном коде.
Исследуйте модель в качестве примера
Откройте модель в качестве примера.
open_system('rtwdemo_memsec')
Инструкции
Узнайте о разделах памяти путем нажатия на ссылку на документацию в модели.
Просмотрите разделы memory в пакете ECoderDemos путем нажатия кнопки в модели и затем выбора вкладки Разделов Memory.
Просмотрите разделы memory, выбранные для этой модели путем нажатия кнопки в модели. Настройки уровня модели являются также настройками по умолчанию для атомарных подсистем.
Откройте диалоговое окно Параметров SubSystem для подсистем, чтобы видеть настройки раздела memory для каждой из атомарных подсистем в модели.
Сгенерируйте код путем нажатия кнопки в модели. Отчет генерации кода отображен автоматически. Смотрите данные и функциональные определения в .c
файлы и наблюдают, как сгенерированные прагмы соответствуют заданным разделам памяти.