主要内容

使用自定义存储类设计器创建存储类

要控制生成代码中数据的外观,可以使用内置存储类,例如ExportToFile(见通过使用结构存储类将参数数据组织成结构).如果内置存储类不能满足您的需求,您可以创建自己的存储类。要创建可应用于数据对象的存储类,请使用自定义存储类设计器在包中创建存储类。看到为软件架构定义存储类、内存段和函数模板

要定义可以通过使用代码映射编辑器在模型中应用的存储类,请使用嵌入式编码字典.或者,在包中创建存储类,并从Embedded Coder Dictionary引用包。

包还定义了信号参数数据类。看到数据对象.包中的数据对象,例如金宝app可以使用该包中定义的存储类,但不能使用其他包中定义的存储类。

有关使用自定义存储类设计器创建内存段的信息,请参见通过插入语控制数据和函数在内存中的位置

创建并应用存储类

这个例子展示了如何通过为数据对象创建和应用您自己的存储类来控制从模型生成的代码。

探索模型示例

打开模型rtwdemo_cscpredef.您可以通过定义自己的数据类和创建自己的存储类来控制从该模型生成的代码。

在本例中,您将模型中多个信号和参数的声明和定义导出到一个声明头文件和一个定义文件中。

创建数据类包

要创建存储类,首先要创建一个数据类包来包含存储类定义。从包中创建的数据对象可以使用包定义的存储类。

  1. 通过复制示例包文件夹来创建您自己的数据类包+金宝app SimulinkDemos.导航到示例包文件夹。

    %记住当前文件夹路径currentPath = pwd;%导航到示例包文件夹demoPath =“\工具箱\仿真软件金宝app\ simdemos \ dataclasses”;cd ([matlabroot demoPath])

  2. 复制+金宝app SimulinkDemos文件夹到剪贴板。

  3. 返回到工作文件夹。

    cd (currentPath)

  4. 粘贴+金宝app SimulinkDemos文件夹从剪贴板中放入工作文件夹。将复制的文件夹重命名为+ myPackage

  5. 内导航+ myPackage文件夹到文件Signal.m编辑。的定义信号类。

  6. 取消的方法定义方法的部分setupCoderInfo.在函数的调用中useLocalCustomStorageClasses、替换“packageName”“myPackage”.当您完成时,该部分显示如下:

    方法函数setupCoderInfo (h)%从这个包中使用自定义存储类useLocalCustomStorageClasses (h,“myPackage”);结束结束%的方法

    这个函数useLocalCustomStorageClasses允许您应用这些存储类myPackage定义用于创建的数据对象myPackage

  7. 保存并关闭文件。

  8. 内导航+ myPackage文件夹到文件Parameter.m编辑。的定义参数类。取消的方法定义方法的部分setupCoderInfo和替换“packageName”“myPackage”

  9. 保存并关闭文件。

创建存储类

可以使用自定义存储类设计器创建或编辑数据类包定义的存储类。

  1. 将当前文件夹设置为包含包的文件夹myPackage

  2. 打开自定义存储类设计器。

    cscdesigner (“myPackage”
  3. 选择存储类ExportToFile

  4. 的名字字段,将存储类重命名为ExportToGlobal

  5. 头文件下拉列表,更改选择具体的实例指定.在新字段中,提供头文件名称global.h

  6. 定义文件下拉列表,更改选择具体的实例指定.在新字段中,提供定义文件名global.c

  7. 点击好吧.点击是的将更改保存到数据类包中myPackage

应用存储类

要应用您自己的存储类,您需要从包中创建数据对象,并配置对象以使用您的存储类。

  1. 创建数据对象以表示示例模型中的一些参数和信号。使用数据类包创建对象myPackage

    %的参数templimit = myPackage.Parameter (202);pressurelimit = myPackage.Parameter (45.2);O2limit = myPackage.Parameter (0.96);rpmlimit = myPackage.Parameter (7400);%的信号tempalarm = myPackage.Signal;pressurealarm = myPackage.Signal;O2alarm = myPackage.Signal;rpmalarm = myPackage.Signal;
  2. 将每个对象的存储类设置为ExportToGlobal

    %的参数templimit.CoderInfo.StorageClass =“自定义”;templimit.CoderInfo.CustomStorageClass =“ExportToGlobal”;pressurelimit.CoderInfo.StorageClass =“自定义”;pressurelimit.CoderInfo.CustomStorageClass =“ExportToGlobal”;O2limit.CoderInfo。StorageClass =“自定义”;O2limit.CoderInfo。CustomStorageClass =“ExportToGlobal”;rpmlimit.CoderInfo.StorageClass =“自定义”;rpmlimit.CoderInfo.CustomStorageClass =“ExportToGlobal”%的信号tempalarm.CoderInfo.StorageClass =“自定义”;tempalarm.CoderInfo.CustomStorageClass =“ExportToGlobal”;pressurealarm.CoderInfo.StorageClass =“自定义”;pressurealarm.CoderInfo.CustomStorageClass =“ExportToGlobal”;O2alarm.CoderInfo。StorageClass =“自定义”;O2alarm.CoderInfo。CustomStorageClass =“ExportToGlobal”;rpmalarm.CoderInfo.StorageClass =“自定义”;rpmalarm.CoderInfo.CustomStorageClass =“ExportToGlobal”
  3. 选择信号名称必须解析为Simulink信号对象金宝app选项,用于模型中的每个目标信号。您可以使用“信号属性”对话框选择该选项解决列,或者使用命令行。

    %信号tempalarmportHandles = get_param (“rtwdemo_cscpredef / RelOp1”“PortHandles”);outputPortHandle = portHandles.Outport;set_param (outputPortHandle“MustResolveToSignalObject”“上”%信号pressurealarmportHandles = get_param (“rtwdemo_cscpredef / RelOp2”“PortHandles”);outputPortHandle = portHandles.Outport;set_param (outputPortHandle“MustResolveToSignalObject”“上”%信号O2alarmportHandles = get_param (“rtwdemo_cscpredef / RelOp3”“PortHandles”);outputPortHandle = portHandles.Outport;set_param (outputPortHandle“MustResolveToSignalObject”“上”%信号rpmalarmportHandles = get_param (“rtwdemo_cscpredef / RelOp4”“PortHandles”);outputPortHandle = portHandles.Outport;set_param (outputPortHandle“MustResolveToSignalObject”“上”

生成代码

  1. 为示例模型生成代码。

    slbuild (“rtwdemo_cscpredef”
  2. 在模型的Code视图中,查看生成的头文件global.h.该文件包含走读生使用存储类的模型信号和参数的声明ExportToGlobal

    /*自定义存储类声明:ExportToGlobal */ extern boolean_T O2alarm;走读生real_T O2limit;走读生boolean_T pressurealarm;走读生real_T pressurelimit;走读生boolean_T rpmalarm;走读生real_T rpmlimit;走读生boolean_T tempalarm;走读生real_T templimit;

  3. 查看生成的文件global.c.该文件包含使用存储类的模型信号和参数的定义ExportToGlobal

    /*自定义存储类ExportToGlobal */ boolean O2alarm;real_T O2limit = 0.96;boolean_T pressurealarm;real_T压力限制= 45.2;boolean_T rpmalarm;real_T rpmlimit = 7400.0;boolean_T tempalarm;real_T templlimit = 202.0;

修改内置存储类

不能直接修改内置存储类,例如ExportToFile金宝app包,但您可以创建一个副本,然后修改该副本。当你创建一个没有csc_registration.m文件,然后在该包中首次打开自定义存储类设计器,Simulink将内置存储类的定义复制到包中。金宝app然后,在自定义存储类设计器中,您可以修改复制的定义。或者,要在包中保持内置存储类可用,可以通过单击复制其中一个复制,然后修改生成的副本。

通过配置存储类属性控制数据表示

自定义存储类设计器是用于创建和管理存储类和内存段的工具。要打开特定包的自定义存储类设计器,例如,+ mypkg,在命令提示符处使用cscdesigner功能:

cscdesigner (“mypkg”

表示包的文件夹的名称以+.当你使用这个函数时cscdesigner,省略了+从目标包的名称。

要控制存储类对模型中的数据的影响,请在自定义存储类设计器中指定存储类的属性。要确定如何生成特定类型的代码,请使用表中的信息。

生成代码中的数据类型 技术
结构 类型FlatStructure.看到生成结构化数据
数据初始化和明确的信号.看到生成一个宏
指针 数据访问指针数据范围汽车进口,或具体的实例.外部代码必须定义指针变量。
静态数据(file-scoped数据) 数据范围文件
常量挥发性数据 记忆的部分到指定的内存段常量挥发性,或两者兼而有之。例如,使用其中一个内置内存部分MemConstMemVolatile,MemConstVolatile.要创建自己的内存部分,请参见通过插入语控制数据和函数在内存中的位置
调用外部函数来读取和写入数据 看到调用自定义访问函数或宏,而不是对变量进行读写操作

允许存储类用户指定属性值

对于存储类的某些属性,例如数据范围,而不是在自定义存储类设计器中指定值,您可以允许存储类的用户指定值。您可以创建一个灵活的存储类,而不是多个存储类,这些存储类只随几个属性值而变化。

例如,假设您创建了一个存储类,它在生成的代码中生成一个全局变量。您可以配置存储类,以便用户可以设置数据范围财产出口为模型中的信号,并将属性设置为进口不同的信号。

在自定义存储类设计器中,对于希望以这种方式配置的每个属性,将属性值设置为具体的实例.然后,当用户将存储类应用于数据项时,该属性将作为该数据项的自定义属性出现在用户面前。有关特定于实例的自定义属性的信息,请参见存储类属性

生成一个宏

若要创建在生成代码中生成宏的存储类,请设置数据初始化和明确的信号

当您设置数据初始化定义文件没有意义。若要防止存储类的用户指定无意义的定义文件,请在“自定义存储类设计器”中设置定义文件指定并保持文本框为空。

  • 要在头文件中定义宏(#定义),使用头文件财产。

  • 若要将宏定义提供为编译器选项或编译器标志,请设置数据访问进口头文件指定.离开头文件文本框为空。然后,生成的代码不定义宏,也不包括(# include)头文件。

    要指定编译器选项或标志,请使用模型配置参数配置参数>代码生成>自定义代码>额外的构建信息>定义了.看到代码生成窗格:自定义代码:附加生成信息:定义

生成结构化数据

创建将数据项聚合为平面结构(类似于内置存储类)的存储类结构体),设置类型FlatStructure.的结构属性选项卡出现了。

  • 要控制生成代码中出现的全局结构变量的名称,请使用结构体名称属性和文本框。

  • 如果你设置结构体名称具体的实例时,存储类的用户指定结构变量的名称。在本例中,代码生成器从变量的名称派生结构类型的名称。

    要更精确地控制结构类型的名称和其他特征,请设置结构体名称指定.使用出现的附加属性控制类型特征。

  • 生成带有位字段的结构(类似于内置存储类设置),选择Bit-pack布尔值.使用该数据类型的数据项布尔作为结构的位字段出现在生成的代码中。

在生成的代码中控制初始值的分配

  • 使用默认值金宝app®编码器™初始化策略,设置数据初始化为默认值,汽车

    • 生成的代码在.c. cpp源文件,在任何函数之外。

    • 生成的代码动态初始化信号和状态数据,作为模型初始化函数的一部分模型_initialize默认情况下)。

  • 要静态初始化数据,请设置数据初始化静态

  • 要动态初始化数据,请设置数据初始化动态

  • 要防止生成的代码初始化数据,请设置数据初始化没有一个.当外部代码初始化数据时,使用此设置可防止生成的代码覆盖您的初始化。

调用自定义访问函数或宏,而不是对变量进行读写操作

使用内置存储类GetSet,您可以生成调用外部自定义函数的代码,而不是直接与变量交互。查阅有关GetSet,请参阅通过使用存储类GetSet的函数访问数据

要创建类似的存储类,请设置类型AccessFunction

  • 指定外部函数的名称。

    • 应用同样的方法得到使用存储类set的数据项的函数命名方案获取函数集函数指定.然后,在文本框中,指定函数命名方案,例如,get_myData_ $ N.使用令牌$ N在命名方案中表示每个数据项的名称。如果不使用令牌,则每个数据项使用相同的指定得到函数名,因此当您生成代码时,模型会生成一个错误。

    • 指定一个不同的得到每个数据项的函数名获取函数集函数具体的实例.稍后,当您创建数据项并应用存储类时,通过配置数据项的自定义属性来指定函数名。

  • 指定声明的头文件的名称得到功能与头文件财产。在这种情况下,定义文件没有意义。若要防止存储类的用户指定无意义的定义文件,请设置定义文件指定并保持文本框为空。

  • 如果您实现得到将标量或数组数据作为宏而不是函数的机制,您可以生成在读取数据时省略括号的代码。在访问函数属性选项卡上,选择通过宏获取数据(省略括号)

生成使用外部代码数据的代码

当您的外部代码定义数据时,为了避免生成重复的定义,您必须将生成的代码配置为读取和写入现有数据。在自定义存储类设计器中,设置数据范围进口.代码生成器不会为全局变量或宏生成定义。

  • 如果代码定义了指针变量,要生成与指针交互的代码,请设置数据访问指针

  • 如果您通过设置生成结构化数据类型FlatStructure,则代码必须定义结构类型和全局结构变量。

  • 如果您的代码初始化状态或信号数据,您可以通过设置防止生成的代码覆盖您的初始化数据初始化没有一个.看到防止全局变量的初始化代码重复

使用数据定义和声明生成代码注释

要自定义生成代码中出现的注释,请在评论选项卡,设置评论规则指定.要指定与每个数据项声明一起出现的注释,请使用声明发表评论盒子。要指定与定义一起出现的注释,请使用定义注释盒子。

对于结构化数据(您设置类型FlatStructure),要指定与结构类型定义一起出现的注释,请使用类型的评论盒子。

通过验证存储类配置来避免代码生成期间的错误

在自定义存储类设计器中配置存储类时,要检查配置中可能出现的错误,请单击验证

例如,如果意外设置,验证存储类会发出警告数据初始化信号选中。信号不能作为宏出现在生成的代码中。

使存储类在当前文件夹之外可用

要使用您创建的存储类,必须使定义包可用。将当前文件夹设置为包含包的文件夹,或者将包含包文件夹的文件夹添加到MATLAB中®路径(见什么是MATLAB搜索路径?).将这个包添加到MATLAB路径中,使您可以在设置当前文件夹的任何位置使用存储类。

在代码映射编辑器中使存储类可用

要在Code Mappings编辑器中使用基于包的存储类,请从嵌入式编码器字典中引用包。要配置内嵌编码器字典以引用包,请参阅请参阅包中的代码生成定义

在包之间共享存储类

创建包时,可以引用另一个包(如内置包)中定义的存储类金宝app或者你创建的另一个包。然后,定义包和任何引用包都可以使用存储类。当您想要对存储类进行更改时,只需在定义包中进行一次更改。

将一个包配置为引用另一个包定义的存储类:

  1. 在自定义存储类设计器中,选择定制的存储类选项卡。

  2. 使用选择包选择引用包。包必须是可写的。

  3. 自定义存储类定义窗格中,选择要在其下面插入引用的现有定义。

  4. 点击新参考

    具有默认名称和属性的新引用将出现在前面选择的定义下方。新引用被选中,并且参考选项卡显示初始属性。

  5. 使用的名字为新引用指定名称。名称在导入包中必须是唯一的,但可以在源包中重复名称。名称不能是TLC关键字。

  6. 在包中引用自定义存储类指定包含要引用的存储类的包。

  7. 自定义存储类要引用指定要引用的存储类。

  8. 点击好吧应用.要永久保存更改,请单击保存

控制存储类下拉列表的外观

当您将存储类应用于数据项时,您可以从下拉列表中选择存储类。

  • 要控制列表中自定义存储类的顺序,请在自定义存储类设计器中使用向上下来按钮。下拉列表中存储类的顺序与您在自定义存储类设计器中指定的顺序匹配。

  • 要防止存储类的用户将存储类应用于参数数据或信号和状态数据,请使用为参数信号复选框。对于相应类型的数据,当您清除这些属性之一时,存储类不会出现在下拉列表中。

    例如,如果存储类在生成的代码中产生一个宏,因为您设置了数据初始化,以防止用户将存储类应用于信号数据,请清除信号

保护自定义存储类定义

当你点击保存在自定义存储类设计器中,设计器将内存段和存储类定义保存到csc_registration.m文件在包文件夹中。要确定此文件的位置,请在自定义存储类设计器中检查文件名

的转换可以防止对整个包的存储类定义的更改csc_registration.m文件从MATLAB文件到p文件。使用pcode函数。

最好的做法是保持csc_registration.mcsc_registration.p在您的软件包文件夹中。这样,如果您使用设计器修改存储类,则可以删除csc_registration.p然后在完成修改后重新生成它。由于文件的p编码版本优先,当两个文件都存在于包中时,存储类将受到保护,您不能在自定义存储类设计器中修改它们。

通过编写TLC代码进一步定制生成的代码

如果通过操纵自定义存储类设计器中的属性创建自己的存储类不能满足您的需求,您可以通过为存储类编写TLC代码来精细地控制生成的代码。使用自定义存储类设计器的高级模式,并为存储类设置类型其他.看到通过为存储类编写TLC代码精细控制数据表示

相关的话题