目录
将存储类应用于单个信号、状态和参数数据元素
存储类是应用于模型中的数据项(信号、模块参数或状态)的代码生成设置。直接将存储类应用于数据项时,存储类会:
-
使数据项在生成的代码中显示为全局符号,通常是全局变量。
-
防止优化(例如 Default parameter behavior 和 Signal storage reuse)从生成的代码中消除数据项。
-
使用 Embedded Coder®,可以配置生成的代码存储数据项的格式或以其他方式定义数据项的格式。例如,可以应用存储类型限定符const或volatile,或将参数数据项配置成显示为宏 (#define)。
直接将存储类应用于单个数据项以实现以下目的:
-
在执行期间调整参数并监测信号和状态。
-
通过内存段配置内存中的数据位置。
-
生成与外部代码交换数据(例如,全局变量)的代码。
要了解 Code Mapping Editor 如何将存储类默认应用于数据类别,参考Configure Default Code Generation for Data(Embedded Coder)。
将存储类应用于数据项
此示例说明如何将存储类应用于模型中的信号、模块状态和模块参数。
浏览模型示例
打开模型示例 rtwdemo_roll。
open_system('rtwdemo_roll')
导航到 BasicRollMode 子系统。
open_system('rtwdemo_roll/BasicRollMode')
该子系统包含一个Integrator模块,它维护一个状态数据段。从模型的根级别,导航到RollAngleReference子系统。
open_system('rtwdemo_roll/RollAngleReference')
该子系统包含标记为UpThr的Constant模块。在此示例中,将配置Integrator模块的状态和输出信号以及Constant模块的Constant value参数,使其在生成的代码中体现为单独的全局变量。
应用存储类
-
导航到模型的根级别。
-
打开 Simulink Coder App。
-
点击 Model Data Editor 选项卡。出现提示时,将系统目标文件更改为 grt.tlc。
-
在 Model Data Editor 中,点击 Change scope 按钮。这会展开要包含在子系统中的数据元素的列表。
-
选择 Signals 选项卡。
-
将 Change view 下拉列表设置为Code。
-
在 Filter contents 框中,输入 integrator。
-
(可选)使用 Name 列指定 Integrator 模块的输出信号的名称,例如 mySignal。
-
使用 Storage Class 列应用存储类ExportedGlobal。
-
选择 States 选项卡。
-
(可选)使用 Name 列指定状态的名称,例如 myState。
-
使用 Storage Class 列应用存储类ExportedGlobal。
-
选择 Parameters 选项卡。不能将存储类直接应用于模块参数,必须创建一个参数对象,例如 Simulink.Parameter,使用该对象设置模块参数的值,并将存储类应用于该对象。
-
将 Change view 下拉列表设置为 Design。
-
在 Filter contents 框中,输入 UpThr。
-
使用 Value 列将参数值从 6 更改为 UpThr。
-
编辑该参数值时,在UpThr旁边,点击操作按钮(含三个纵点),然后选择Create。
-
在Create New Data对话框中,将Value设置为Simulink.Parameter,将Location设置为点Base Workspace。击 Create。名为UpThr的Simulink.Parameter对象出现在基础工作区中。
-
在 UpThr属性对话框中,将 Value 设置为6,将 Storage class 设置为 ExportedGlobal。点击 OK。
也可以在命令提示符下使用下列命令来配置信号、状态和参数数据。
% Configure signal
portHandles = get_param('rtwdemo_roll/BasicRollMode/Integrator',...
'PortHandles');
outportHandle = portHandles.Outport;
set_param(outportHandle,'Name','mySignal')
set_param(outportHandle,'StorageClass','ExportedGlobal')
% Configure state
set_param('rtwdemo_roll/BasicRollMode/Integrator',...
'StateName','myState')
set_param('rtwdemo_roll/BasicRollMode/Integrator',...
'StateStorageClass','ExportedGlobal')
% Configure parameter
set_param('rtwdemo_roll/RollAngleReference/UpThr','Value','UpThr')
UpThr = Simulink.Parameter(6);
UpThr.StorageClass = 'ExportedGlobal';
生成和检查代码
从模型中生成代码。
set_param('rtwdemo_roll','SystemTargetFile','grt.tlc')
rtwbuild('rtwdemo_roll')
### Starting build procedure for: rtwdemo_roll
### Generated code for 'rtwdemo_roll' is up to date because no structural, parameter or code replacement library changes were found.
### Successful completion of build procedure for: rtwdemo_roll
检查文件 rtwdemo_roll.c。该文件定义全局变量。
file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');
rtwdemodbtype(file,'/* Exported block signals */','real32_T myState;',1,1)
/* Exported block signals */
real32_T mySignal; /* '<S1>/Integrator' */
/* Exported block parameters */
real32_T UpThr = 6.0F; /* Variable: UpThr
* Referenced by: '<S3>/UpThr'
*/
/* Exported block states */
real32_T myState; /* '<S1>/Integrator' */
文件rtwdemo_roll.h声明变量。要访问这些变量,外部代码可以使用#include包含此头文件。在rtwdemo_roll.c中,在文件中搜索变量的名称,例如UpThr。rtwdemo_roll_step 函数中的模型算法会读取和写入变量。
可以选择的内置存储类
数据项的默认存储类设置为 Auto,这意味着代码生成器会确定项目在代码中的体现方式。
决定存储类设定的存储位置
对于直接应用了存储类的每个单独信号或状态数据项(包括 Data Store Memory 模块),Simulink® 会将存储类设定存储在模型文件中或存储在信号数据对象 (Simulink.Signal) 的属性中,该对象是在基础工作区、模型工作区或数据字典中创建的。要将存储类应用于模块参数,必须创建一个参数数据对象(例如 Simulink.Parameter)并在该对象中指定存储类。
-
例如,当通过使用 Model Data Editor 或 Property Inspector 将存储类应用于模型中的信号或状态时,便会将存储类设定存储在模型文件中。
如果使用此方法,则不能通过使用外部信号数据对象来控制数据项的其他特性,例如数据类型。
-
创建信号或参数数据对象时,通过使用对象的CoderInfo属性应用存储类。属性的值是一个Simulink.CoderInfo 对象,该对象的 StorageClass 属性用于指定存储类。将模型中的数据项与该对象关联后,数据项将从该对象中获取存储类。
对于信号、状态和Data Store Memory模块,要决定是在模型中还是在数据对象中存储存储类设定,参考存储信号和状态的设计属性。
使用 Model Data Editor 将存储类应用于输出模块
可以使用 Model Data Editor 将存储类直接应用于根级别Outport模块或应用于驱动该模块的输入信号。
-
要将存储类设定存储在 Outport 模块中,请使用 Model Data Editor 中的 Inports/Outports 选项卡。使用此方法时,在删除驱动该模块的输入信号后,设定会被保留。在开发内部算法之前,请使用此方法配置模型接口。
-
要将设定存储在驱动模块的输入信号中,请使用 Model Data Editor 中的 Signals 选项卡。
以交互方式应用存储类的方法
要将存储类应用于可以搜索、排序和筛选的列表中的多个数据项,请使用 Model Data Editor(在 Modeling 选项卡上,点击 Model Data Editor),如将存储类应用于数据项中所示。
要在关注单个信号、模块状态或参数的同时应用存储类,请使用 Property Inspector(在 Modeling 选项卡上的 Design 下,点击 Property Inspector)、Signal Properties 对话框(用于信号)或模块对话框(用于状态或参数)。在 Code Generation 下,应用存储类。
-
对于参数,首先将参数的值设置为要用于所需参数对象的名称。然后,创建并配置该参数对象,如在生成的代码中创建可调标定参数中所示。
-
对于信号、状态或 Data Store Memory 模块,首先提供信号或状态的名称,代码生成器使用该名称作为对应全局符号的名称。然后,使用Storage class指定存储类(这种情况下,将由模型文件存储设定),或按在Simulink模型中使用数据对象中所示创建一个信号数据对象并将存储类应用于该对象。
以编程方式应用存储类的方法
-
对于模块参数,使用 set_param 设置参数的值。使用其他命令创建和配置所需参数对象的属性。
-
对于信号,使用 get_param 或 find_system 返回生成该信号的模块端口的句柄。使用句柄的参数命名该信号,然后直接应用存储类;或者配置信号以从信号对象获取设置,包括存储类。
-
对于 Inport 模块,配置退出该模块的信号线。对于 Outport 模块,配置该模块或进入该模块的信号线。
-
对于模块状态,使用set_param与模块进行交互。命名状态,然后直接应用存储类;或者配置状态以从信号对象获取存储类。
-
对于 Data Store Memory 模块,使用 set_param 与该模块进行交互。由于数据存储已有名称,因此无需指定名称。使用 StateStorageClass 参数直接应用存储类;或者配置数据存储以从信号对象获取存储类。
要与存储在模型工作区或数据字典中的信号或参数数据对象进行交互,请使用该工作区或字典的编程接口。
将存储类直接应用于信号线
此示例说明如何以编程方式将存储类直接应用于信号线。
-
打开模型示例 rtwdemo_secondOrderSystem。
rtwdemo_secondOrderSystem
-
获取名为 Force: f(t) 的模块的输出句柄。
portHandles = ... get_param('rtwdemo_secondOrderSystem/Force: f(t)','PortHandles'); outportHandle = portHandles.Outport;
-
将对应信号的名称设置为 ForceSignal。
set_param(outportHandle,'Name','ForceSignal')
-
将信号的存储类设置为 ExportedGlobal。
set_param(outportHandle,'StorageClass','ExportedGlobal')
-
从模型中生成代码。代码会声明并定义一个全局变量 ForceSignal 来表示信号。
将存储类直接应用于模块状态
此示例说明如何以编程方式将存储类应用于模块状态。
-
打开模型示例 rtwdemo_basicsc。
rtwdemo_basicsc
-
将 Delay 模块的状态命名为 myState。
set_param('rtwdemo_basicsc/Delay','StateName','myState')
-
将状态的存储类设置为 ExportedGlobal。
set_param('rtwdemo_basicsc/Delay',... 'StateStorageClass','ExportedGlobal')
-
从模型中生成代码。代码会声明并定义一个全局变量 myState 来表示状态。
参数对象配置快速参考图
此图显示用于控制生成的代码中参数对象表示的代码生成和存储类选项。