В этом примере показано, как установить владение глобальных данных в коде, сгенерированном из моделей, на которые ссылаются.
Можно создать глобальную переменную в сгенерированном коде путем применения класса памяти к элементу данных в модели, на которую ссылаются (см. Настройку генерации кода 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 выпадающий список к Code
.
6. В airflow_calc
модель, выберите est_airflow
Блок Outport.
7. В Model Data Editor смотрите значение в столбце Класса памяти. Сигнал, что этот блок представляет, est_airflow
, использует класс памяти ExportToFile
. С этой установкой сигнал появляется в сгенерированном коде как глобальная переменная. Блок Outport пометил fb_correction
также использование эта установка.
8. В Model Data Editor выберите вкладку Parameters и нажмите кнопку дополнительной информации Show/refresh. Model Data Editor теперь показывает информацию о переменных рабочей области и объектах, таких как Simulink.Parameter
объекты, что использование модели, чтобы установить значения параметров блоков.
9. В поле содержимого Фильтра введите numerator
. Simulink.Parameter
объект numerator_param
, то, которое находится в базовом рабочем пространстве, устанавливает значение параметра Числителя в блоке Discrete Filter, пометил Throttle Transient
. Объект использует класс памяти ExportToFile
.
10. Выберите вкладку Signals. В поле содержимого Фильтра введите e0
. e0
сигнала, который является внутренним к
airflow_calc
модель, на которую ссылаются, также ExportToFile
использования. Сигнал является внутренним, потому что это не ввод или вывод корневого уровня модели.
11. Откройте fuel_calc
модель.
open_system('fuel_calc')
12. В Model Data Editor для этой модели, на вкладке Inports/Outports, представлении Change набора к Code
. Inport блокирует est_airflow
и fb_correction
используйте тот же класс памяти, ExportToFile
, когда соответствующий Выходной порт блокируется в airflow_calc
. Блок Outport пометил fuel_rate
также использование ExportToFile
.
Сгенерируйте код от моделей контроллеров, sldemo_fuelsys_dd_controller
.
evalc('rtwbuild(''sldemo_fuelsys_dd_controller'')');
В отчете генерации кода, в соответствии с Моделями, на которые Ссылаются, кликают по гиперссылке, чтобы смотреть код, сгенерированный для 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
модель, на вкладке Modeling, в соответствии с Проектом, нажимает Property Inspector.
2. В Model Data Editor выберите вкладку Inports/Outports.
3. Выберите строку, которая соответствует блоку Outport est_airflow
. Property Inspector показывает свойства блока Outport.
4. В Property Inspector, в соответствии с Кодом, владельцем набора к airflow_calc
. Генератор кода помещает определение глобальной переменной с кодом, сгенерированным для airflow_calc
.
5. Для fb_correction
, используйте Model Data Editor и Property Inspector к владельцу набора к airflow_calc
.
6. Выберите вкладку Parameters.
7. Найдите строку, которая соответствует объекту параметра, numerator_param
. В строке дважды кликните значок в левом столбце. Model Explorer открывает и отображает свойства numerator_param
.
8. В панели Иерархии модели расширьте airflow_calc узел так, чтобы вы видели зависимый узел Рабочего пространства модели.
9. Используйте Model Explorer, чтобы переместить numerator_param
от базового рабочего пространства до airflow_calc
рабочее пространство модели. Например, в панели Иерархии модели, выберите Base Workspace. Затем перетащите numerator_param
от Содержимого разделяют на области к узлу Рабочего пространства модели в панели Иерархии модели. С этим изменением генератор кода принимает тот airflow_calc
владеет numerator_param
, и помещает определение переменной в код, сгенерированный для airflow_calc
.
10. В fuel_calc
модель, на вкладке Modeling, в соответствии с Проектом, нажимает Property Inspector.
11. Поскольку Inport блокирует est_airflow
и fb_correction
, используйте Model Data Editor и Property Inspector к владельцу набора к airflow_calc
. С этой настройкой, fuel_calc
код не задает переменные.
12. Для блока Outport используйте Model Data Editor и Property Inspector к владельцу набора к 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. В каждой из этих трех моделей выберите Configuration Parameters> владелец Use от объекта данных для размещения определения данных. С этой очищенной установкой (значение по умолчанию), генератор кода игнорирует значения, которые вы задаете для Владельца.
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('rtwbuild(''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
представлены блоками Выходного порта в airflow_calc
и Inport блокируется в fuel_calc
. Если вы хотите изменить настройку одного из этих сигналов, необходимо внести изменение в обеих моделях. Например, если вы хотите изменить класс памяти est_airflow
от ExportToFile
к Volatile
, необходимо изменить класс памяти дважды: однажды для блока Outport в airflow_calc
и снова для блока Inport в fuel_calc
.
Чтобы сделать обслуживание каждого сигнала легче, сохраните настройки генерации кода в Simulink.Signal
объект, который может существовать в базовом рабочем пространстве или словаре данных.
1. В Model Data Editor для airflow_calc
, на вкладке Inports/Outports найдите строку, которая соответствует est_airflow
. Для той строки, в столбце Имени Сигнала, кликают по ячейке.
2. В ячейке, рядом с est_airflow
текст, кликните по кнопке действий (с тремя вертикальными точками). Выберите Create и Resolve.
3. В диалоговом окне Create New Data, установленном Значении к Simulink.Signal
и нажмите Create. Simulink.Signal
возразите названному est_airflow
появляется в базовом рабочем пространстве. В Model Data Editor, для est_airflow
, флажок во флажке Resolve устанавливается, что означает, что блок Outport получает настройки генерации кода от объекта сигнала в базовом рабочем пространстве.
4. В est_airflow
диалоговое окно свойства, Класс памяти набора к ExportToFile
.
5. Владелец набора к airflow_calc
.
6. Используйте Model Data Editor, чтобы создать подобный объект сигнала для fb_correction
.
В Model Data Editor для fuel_calc
, на вкладке Inports/Outports, в столбце Твердости, устанавливают флажки для 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('rtwbuild(''sldemo_fuelsys_dd_controller'')');