В этом примере показано, как установить принадлежность глобальных данных в коде, созданном на основе ссылочных моделей.
Можно создать глобальную переменную в сгенерированном коде, применив класс хранения к элементу данных в ссылочной модели (см. Настройка генерации кода C для элементов интерфейса модели). При определенных условиях генератор кода помещает определение переменной с кодом, созданным из верхней модели, в иерархию. Это размещение по умолчанию может затруднить определение модели, ответственной за данные, и управление изменениями кода в среде разработки на базе группы.
Чтобы установить принадлежность глобальной переменной путем размещения определения с кодом, созданным из соответствующей модели, примените класс хранения, такой как ExportToFile и укажите пользовательский атрибут Владелец. Кроме того, для объектов параметров, таких как Simulink.Parameter что используется только в одной модели, можно установить владельца, сохранив объект в рабочей области модели вместо базовой рабочей области или словаря данных.
1. Копирование файла сценария prepare_sldemo_fuelsys_dd_ctrl.m в текущую папку.
[~, ~] = copyfile(fullfile(matlabroot,'examples','ecoder','main','prepare_sldemo_fuelsys_dd_ctrl.m'),... 'prepare_sldemo_fuelsys_dd_ctrl.m','f');
2. Запустите копию сценария в текущей папке. Сценарий открывает модель sldemo_fuelsys_dd_controller и готовит его для этого примера.
prepare_sldemo_fuelsys_dd_ctrl
open_system('sldemo_fuelsys_dd_controller')

Эта модель контроллера содержит две модели, airflow_calc и fuel_calc. Два выхода: airflow_calc, est_airflow и fb_correction, являются входами fuel_calc.
3. Откройте окно airflow_calc модель.
open_system('airflow_calc')

4. На вкладке Моделирование (Modeling) щелкните Редактор данных модели (Model Data Editor).
5. В Редакторе данных модели (Model Data Editor) задайте в раскрывающемся списке Изменить вид (Change view) значение Code.
6. В airflow_calc модель, выберите est_airflow Блок аутпорта.
7. В редакторе данных модели проверьте значение в столбце «Класс хранилища». Сигнал, который представляет этот блок, est_airflow, использует класс хранения ExportToFile. При этой настройке сигнал отображается в сгенерированном коде как глобальная переменная. Блок Outport с меткой fb_correction также использует этот параметр.
8. В редакторе данных модели выберите вкладку Параметры (Parameters) и нажмите кнопку Показать/обновить дополнительную информацию (Show/refresh additional information). Редактор данных модели теперь показывает информацию о переменных и объектах рабочего пространства, таких как Simulink.Parameter , которые модель использует для задания значений параметров блока.
9. В поле Содержимое фильтра введите numerator. Simulink.Parameter объект numerator_param, который находится в базовом рабочем пространстве, устанавливает значение параметра «Числитель» в блоке «Дискретный фильтр» с меткой Throttle Transient. Объект использует класс хранения ExportToFile.
10. Выберите вкладку Signals (Сигналы). В поле Содержимое фильтра введите e0. Сигнал e0, которая является внутренней для airflow_calc ссылочная модель, также использует ExportToFile. Сигнал является внутренним, поскольку он не является входом или выходом модели на корневом уровне.
11. Откройте окно fuel_calc модель.
open_system('fuel_calc')

12. В редакторе данных модели для этой модели на вкладке Ввод/вывод (Inports/Outports) задайте для параметра Изменить вид (Change view) значение Code. Блоки ввода est_airflow и fb_correction использовать один и тот же класс хранения, ExportToFile, как соответствующие блоки Outport в airflow_calc. Блок Outport с меткой fuel_rate также использует ExportToFile.
Создать код из модели контроллера, sldemo_fuelsys_dd_controller.
evalc('slbuild(''sldemo_fuelsys_dd_controller'')');
В отчете о создании кода в разделе Ссылочные модели (Referenced Models) щелкните гиперссылку для проверки кода, созданного для airflow_calc.
Файл airflow_calc.c определяет глобальную переменную, представляющую сигнал e0. Потому что блоки, записывающие и считывающие e0 существуют только в airflow_calcгенератор кода предполагает, что этой модели принадлежит сигнал.
file = fullfile('slprj','ert','airflow_calc','airflow_calc.c'); rtwdemodbtype(file,'/* Definition for custom storage class: ExportToFile */',... 'real32_T e0;',1,1)
/* Definition for custom storage class: ExportToFile */ real32_T e0; /* '<Root>/Sum1' */
В отчете о создании кода вернитесь к коду, созданному для sldemo_fuelsys_dd_controller.
Файл sldemo_fuelsys_dd_controller.c определяет другие глобальные переменные.
file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',... 'sldemo_fuelsys_dd_controller.c'); rtwdemodbtype(file,... '/* Definition for custom storage class: ExportToFile */',... 'real32_T numerator_param[2] = { 0.01F, -0.01F } ;',1,1);
/* Definition for custom storage class: ExportToFile */
real32_T est_airflow; /* '<Root>/airflow_calc' */
real32_T fb_correction; /* '<Root>/airflow_calc' */
real32_T fuel_rate; /* '<Root>/fuel_calc' */
real32_T numerator_param[2] = { 0.01F, -0.01F } ;
Потому что сигналы est_airflow и fb_correction проходят между двумя моделями и через модель контроллера верхнего уровня, генератор кода предполагает, что sldemo_fuelsys_dd_controller владеет сигналами. Генератор кода делает аналогичное предположение о fuel_rate. Потому что объект параметра numerator_param существует в базовой рабочей области, объект может использоваться любой моделью в иерархии. Поэтому генератор кода предполагает, что sldemo_fuelsys_dd_controller является владельцем параметра.
Каждый общий сигнал и объект параметра можно настроить таким образом, чтобы соответствующее определение переменной отображалось в коде, сгенерированном для соответствующей модели.
В этом примере настройки генерации кода настраиваются следующим образом:
Код, созданный для airflow_calc модель определяет сигналы, которые проходят между двумя моделями; est_airflow и fb_correction.
Код, созданный для airflow_calc определяет данные параметра, numerator_param.
Код, созданный для fuel_calc определяет вычисляемый выходной сигнал, fuel_rate.
1. В airflow_calc на вкладке «Моделирование» в разделе «Модель» выберите «Инспектор свойств».
2. В Редакторе данных модели (Model Data Editor) выберите вкладку Ввод/вывод (Inports/Outports).
3. Выберите строку, соответствующую блоку Outport est_airflow. Инспектор свойств показывает свойства блока Outport.
4. В инспекторе свойств в разделе «Код» задайте для параметра «Владелец» значение airflow_calc. Генератор кода помещает определение глобальной переменной с кодом, сгенерированным для airflow_calc.
5. Для fb_correction, с помощью редактора данных модели и инспектора свойств задайте для параметра «Владелец» значение airflow_calc.
6. Выберите вкладку Параметры (Parameters).
7. Найдите строку, соответствующую объекту параметра, numerator_param. В строке дважды щелкните значок в левом столбце. Откроется Обозреватель моделей (Model Explorer), в котором отображаются свойства numerator_param.
8. На панели Иерархия модели (Model Hierarchy) разверните узел airflow_calc, чтобы можно было увидеть подчиненный узел Рабочая область модели (Model Workspace).
9. Перемещение с помощью Проводника моделей numerator_param из базового рабочего пространства в airflow_calc рабочее пространство модели. Например, на панели Иерархия модели (Model Hierarchy) выберите Базовая рабочая область (Base Workspace). Затем перетащите numerator_param из области Содержимое (Contents) в узел Рабочее пространство модели (Model Workspace) на панели Иерархия модели (Model Hierarchy). При этом изменении генератор кода предполагает, что airflow_calc владеет numerator_paramи помещает определение переменной в код, созданный для airflow_calc.
10. В fuel_calc на вкладке «Моделирование» в разделе «Модель» выберите «Инспектор свойств».
11. Для блоков ввода est_airflow и fb_correction, с помощью редактора данных модели и инспектора свойств задайте для параметра «Владелец» значение airflow_calc. При такой конфигурации fuel_calc код не определяет переменные.
12. Для блока «Outport» используйте редактор данных модели и инспектор свойств, чтобы задать для параметра «Owner» значение fuel_calc.
Кроме того, чтобы настроить данные в моделях, используйте следующие команды в командной строке:
temp = Simulink.Signal; temp.CoderInfo.StorageClass = 'Custom'; temp.CoderInfo.CustomStorageClass = 'ExportToFile'; temp.CoderInfo.CustomAttributes.Owner = 'airflow_calc'; set_param('airflow_calc/est_airflow','SignalName','est_airflow') set_param('airflow_calc/est_airflow','SignalObject',copy(temp)) set_param('airflow_calc/fb_correction','SignalName','fb_correction') set_param('airflow_calc/fb_correction','SignalObject',copy(temp)) mdlwks = get_param('airflow_calc','ModelWorkspace'); assignin(mdlwks,'numerator_param',copy(numerator_param)); portHandles = get_param('fuel_calc/est_airflow','portHandles'); outportHandle = portHandles.Outport; set_param(outportHandle,'Name','est_airflow') set_param(outportHandle,'SignalObject',copy(temp)) portHandles = get_param('fuel_calc/fb_correction','portHandles'); outportHandle = portHandles.Outport; set_param(outportHandle,'Name','fb_correction') set_param(outportHandle,'SignalObject',copy(temp)) temp.CoderInfo.CustomAttributes.Owner = 'fuel_calc'; set_param('fuel_calc/fuel_rate','SignalName','fuel_rate') set_param('fuel_calc/fuel_rate','SignalObject',copy(temp)) clear temp portHandles outportHandle numerator_param
13. В каждой из трех моделей выберите Параметры конфигурации > Использовать владельца из объекта данных для размещения определения данных. Если этот параметр снят (по умолчанию), генератор кода игнорирует значения, указанные для владельца.
set_param('fuel_calc','EnableDataOwnership','on') set_param('airflow_calc','EnableDataOwnership','on') set_param('sldemo_fuelsys_dd_controller','EnableDataOwnership','on')
14. Сохраните ссылочные модели.
save_system('fuel_calc') save_system('airflow_calc')
Создать код из модели контроллера, sldemo_fuelsys_dd_controller.
evalc('slbuild(''sldemo_fuelsys_dd_controller'')');
Теперь, файл sldemo_fuelsys_dd_controller.c не определяет ни одну из глобальных переменных.
В отчете о создании кода проверьте код, созданный для airflow_calc.
Файл airflow_calc.c теперь определяет глобальные переменные, которые принадлежат airflow_calc.
file = fullfile('slprj','ert','airflow_calc','airflow_calc.c'); rtwdemodbtype(file,'/* Definition for custom storage class: ExportToFile */',... 'real32_T numerator_param[2] = { 0.01F, -0.01F } ;',1,1)
/* Definition for custom storage class: ExportToFile */
real32_T e0; /* '<Root>/Sum1' */
real32_T est_airflow; /* '<Root>/Sum' */
real32_T fb_correction; /* '<Root>/Discrete Integrator' */
real32_T numerator_param[2] = { 0.01F, -0.01F } ;
Проверка кода, созданного для fuel_calc. Файл fuel_calc.c определяет глобальную переменную fuel_rate.
file = fullfile('slprj','ert','fuel_calc','fuel_calc.c'); rtwdemodbtype(file,'/* Definition for custom storage class: ExportToFile */',... 'real32_T fuel_rate;',1,1)
/* Definition for custom storage class: ExportToFile */ real32_T fuel_rate; /* '<S2>/Merge' */
Элементы данных сигнала est_airflow и fb_correction представлены блоками Outport в airflow_calc и по блокам ввода в fuel_calc. Если требуется изменить конфигурацию одного из этих сигналов, необходимо внести изменения в обе модели. Например, если требуется изменить класс хранения est_airflow от ExportToFile кому Volatile, необходимо изменить класс хранения дважды: один раз для блока Outport в airflow_calc и снова для блока Inport в fuel_calc.
Чтобы облегчить обслуживание каждого сигнала, сохраните настройки генерации кода в Simulink.Signal , который может существовать в базовой рабочей области или словаре данных.
1. В редакторе данных модели для airflow_calc, на вкладке Inports/Outports найдите строку, соответствующую est_airflow. Для этой строки в столбце «Имя сигнала» щелкните ячейку.
2. В ячейке рядом с est_airflow нажмите кнопку действия (с тремя вертикальными точками). Выберите Создать и разрешить.
3. В диалоговом окне «Создание новых данных» задайте для параметра «Значение» значение Simulink.Signal и нажмите кнопку «Создать». A Simulink.Signal объект с именем est_airflow отображается в базовой рабочей области. В редакторе данных модели для est_airflow, флажок в поле Разрешить (Resolve) установлен, что означает, что блок Исходящий (Outport) получает настройки генерации кода из объекта сигнала в базовой рабочей области.
4. В est_airflow диалоговое окно свойств, задайте для класса Storage значение ExportToFile.
5. Задать для владельца значение airflow_calc.
6. Используйте Редактор данных модели (Model Data Editor) для создания аналогичного объекта сигнала для fb_correction.
В редакторе данных модели для fuel_calc, на вкладке Inports/Outports в столбце Resolve установите флажки для est_airflow и fb_correction. Теперь каждый блок Inport получает настройки генерации кода из соответствующего объекта сигнала.
Кроме того, чтобы создать сигнальный объект и настроить блоки и линии в модели, в командной строке используйте следующие команды:
est_airflow = Simulink.Signal; est_airflow.CoderInfo.StorageClass = 'Custom'; est_airflow.CoderInfo.CustomStorageClass = 'ExportToFile'; est_airflow.CoderInfo.CustomAttributes.Owner = 'airflow_calc'; fb_correction = Simulink.Signal; fb_correction.CoderInfo.StorageClass = 'Custom'; fb_correction.CoderInfo.CustomStorageClass = 'ExportToFile'; fb_correction.CoderInfo.CustomAttributes.Owner = 'airflow_calc'; set_param('airflow_calc/est_airflow', 'StorageClass', 'Auto') set_param('airflow_calc/est_airflow','MustResolveToSignalObject','on') set_param('airflow_calc/fb_correction', 'StorageClass', 'Auto') set_param('airflow_calc/fb_correction','MustResolveToSignalObject','on') portHandles = get_param('fuel_calc/est_airflow','portHandles'); outportHandle = portHandles.Outport; set_param(outportHandle, 'StorageClass', 'Auto') set_param(outportHandle,'MustResolveToSignalObject','on') portHandles = get_param('fuel_calc/fb_correction','portHandles'); outportHandle = portHandles.Outport; set_param(outportHandle, 'StorageClass', 'Auto') set_param(outportHandle,'MustResolveToSignalObject','on') clear portHandles outportHandle
7. Сохранение моделей и создание кода из sldemo_fuelsys_dd_controller. Код тот же, что и до создания Simulink.Signal объекты. Теперь можно вносить изменения в сигнальные объекты вместо соответствующих блоков и линий в моделях.
save_system('airflow_calc') save_system('fuel_calc') evalc('slbuild(''sldemo_fuelsys_dd_controller'')');