Simulink代码生成: #pragma section 自定义Storage Class

目录

1. 问题引入

2.配置过程 

3. 创建自定义的Storage Class

4. 在数据字典SLDD和Base Workspace里调用自定义的Storage Class

5. 更改数据字典里面已经定义好的变量

6. 生成代码验证

7.总结


1. 问题引入

1. 定义变量到指定的段

  开发过程中,需要把标定量放到指定的段中并生成代码,代码效果如下,在应用层都是基于模型开发的前提下,如果手动添加#pragma section 这种预编译指令是不现实的,本文记录一下代码生成的配置过程。

2. 批量把SLDD里面定义的变量放到指定的段

  如果已经定义了数据字典,并定义了很多变量需要放到特定的段中

#pragma section ".rodata.Calib_32" a 4

/* Definition for custom storage class: Section_32_Signa */
VAR(float32, Task_100us_VAR) Ialpha;   /* '<S14>/Gain2' */
VAR(float32, Task_100us_VAR) Ibeta;    /* '<S14>/Gain5' */
VAR(float32, Task_100us_VAR) V_alpha;  /* '<S9>/Add' */
VAR(float32, Task_100us_VAR) V_beta;   /* '<S9>/Add3' */
VAR(float32, Task_100us_VAR) Vd_voltage;/* '<S39>/Switch2' */
VAR(float32, Task_100us_VAR) Vq_voltage;/* '<S66>/Switch2' */

#pragma section

/* ConstVolatile memory section */

#pragma section ".rodata.Calib_32" a 4

/* Definition for custom storage class: Section_32_Param */
volatile CONST(Current_PI_Param, Task_100us_VAR) Current_PI = {
  0.84F,
  48.0F,
  1.869F,
  48.0F
} ;   
#pragma section    

2.配置过程 

1. 创建自定义的Storage Class

在matlab的安装目录找到如下+SimulinkDemos的文件夹,直接复制到当前模型的工程中并改名,这里我们改成+myPackage,并把文件夹添加到matlab的路径中

如图,已经改名并添加了路径

2. 分别对+myPackage包里面Signal.m 和Parameter.m进行调整,两个文件分别对应了Simulink中的Signal类型和Parameter类型,如果少改了一个,在遇到相应类型时不能正常生成相要的代码。

3. 创建自定义的Storage Class

在当前工作空间输入 cscdesigner('myPackage'),弹出如下窗口,其中Memory Section是定义代码生成模板,Custom Storage Class是定义Simulink变量Storage Class

1. 配置Memory Section

 这里配置Signal类型的段和Parameter的段如下图:

Signal类型:

Parameter类型:

 配置完成后 Apply

 2.  配置Custom Storage Class

 新建一个模板,也可以复制已有的模板进行更改

Parameter类型操作也是一样 

最后点Apply,到这一步自定义的Storage Class就完成了

4. 在数据字典SLDD和Base Workspace里调用自定义的Storage Class

 1. 打开Model Explorer窗口,找到Add Simulink Parameter旁边的小箭头,展开如下,点击Customize class lists

2.  如下图,选择定义好的myPackage.Signal 和 myPackage.Parameter, 最后点OK

 

3.  现在可以在Base Workspace 各 SLDD的 Design Data 里面使用自定义的Storage Class

 


5. 更改数据字典里面已经定义好的变量

 如果数据字典里面已经定义了变量,在调用自定义的Storage Class时是不会显示出我们自定义的Storage Class如下:

 

在调整StorageClass属性时,找不到我们定义的StorageClass,因为我们在建数据字典时最初用的是Simulink.signal或者是Simulink.parameter,并不是我们定义的。这时候我们可以手动去改,重新定义变量,但这对变量多且有很多结构体的情况下并不适用,这时候就可以用到Export功能,如下:

 1. 把数据字典里的数据导出到文件,得到一个.m, 这个.m就是数据字典里定义的变量的脚本

 2.  把变量从Simulink.Parameter或者Simulink.Signal改成 myPackage.Parameter 或者myPackage.Signal. 再点下运行,这时新的变量会出现在Base Workspace.

 3.  备份原先的数据字典,清空数据字典里的变量,再从Base Workspace里面导入新的变量,现在的变量就可以直接调用自定义的StorageClass

6. 生成代码验证

7.总结

 这是在实践中遇到的问题,并通过查找相关资料和尝试找到的解决方案,不代表这是最好的方法,在这里记录一下

<think>好的,用户想了解SimulinkStorage Class不同存储方法的特点对比。首先,我需要回忆一下SimulinkStorage Class的基本概念。Storage Class主要用于代码生成时控制变量在生成的代码中的存储方式,比如全局变量、静态变量或者自动变量等。不同的Storage Class会影响变量的作用域、存储位置以及代码的可读性和效率。 接下来,我需要整理常见的Storage Class类型。根据之前学过的资料,常见的包括Auto、ExportedGlobal、ImportedExtern、ImportedExternPointer、Custom等。Auto是默认的,编译器自动决定存储方式;ExportedGlobal会将变量声明为全局变量,并导出到头文件中;ImportedExtern则用于引用外部已定义的变量;ImportedExternPointer是通过指针引用外部变量;而Custom允许用户自定义存储类,比如使用特定的pragma指令。 然后,用户需要对比它们的特点。可能需要从存储位置、作用域、代码生成结果、适用场景等方面进行比较。例如,ExportedGlobal适合需要多个模块访问的全局变量,但可能增加内存占用;ImportedExtern适合集成已有代码中的变量,减少重复定义;Custom则灵活,可以满足特定编译器或硬件需求。 还需要考虑用户提供的引用内容。引用[1]提到通过#pragma section自定义Storage Class,这可能涉及内存分区的分配,适用于嵌入式系统。引用[2]和[3]讨论自定义Storage Class的配置步骤,以及路径设置的问题,说明自定义存储类需要正确配置数据字典和路径才能生效。 用户可能是在进行代码生成优化,特别是在嵌入式系统中,需要精确控制变量的存储位置,比如将变量放入特定的内存区域以提高性能或满足硬件要求。因此,对比时需强调不同存储类在嵌入式环境中的应用场景。 另外,需要注意不同Storage Class对代码可维护性和移植性的影响。例如,使用ImportedExtern可能会增加代码对外部环境的依赖,而Auto则依赖编译器,可能在不同编译器间表现不一。Custom虽然灵活,但配置复杂,需要更多的维护。 最后,用户可能希望了解如何选择合适的Storage Class,因此总结部分需要给出选择建议,比如根据变量作用域、是否需要与外部代码交互、内存管理需求等因素来决定。同时,可以推荐在需要特定内存布局时使用Custom,并引用提供的参考资料说明配置方法。</think>### Simulink Storage Class 各类存储方法特点对比 在Simulink代码生成中,Storage Class(存储类)决定了模型变量在生成代码中的存储方式,直接影响代码结构、内存分配和可集成性。以下是常见存储类的特点对比: --- #### 1. **Auto (默认)** - **特点**:编译器自动决定存储方式(如栈变量或临时变量) - **适用场景**:简单模型、无需与外部代码交互的变量 - **局限性**:无法控制内存布局,不适合嵌入式系统硬性内存约束场景 --- #### 2. **ExportedGlobal** - **特点**: - 生成全局变量,包含在头文件中(如`extern`声明) - 变量作用域为整个工程[^1] - **代码示例**: ```c /* ExportedGlobal存储类生成代码 */ extern int32_T myVar; // 在.h文件中声明 ``` - **适用场景**:需跨模块访问的全局变量 --- #### 3. **ImportedExtern** - **特点**: - 引用外部已定义的变量 - 生成代码中仅声明`extern`,不分配内存[^2] - **代码示例**: ```c /* ImportedExtern存储类生成代码 */ extern int32_T extVar; // 假设extVar在外部已定义 ``` - **适用场景**:集成已有代码库中的变量 --- #### 4. **ImportedExternPointer** - **特点**: - 通过指针访问外部变量 - 支持动态内存映射 - **代码示例**: ```c /* ImportedExternPointer生成代码 */ extern int32_T *extPtr; // 指向外部定义的内存地址 ``` - **适用场景**:硬件寄存器映射、共享内存区域 --- #### 5. **Custom Storage Class** - **特点**: - 完全自定义变量声明方式(如`#pragma section`指令) - 可指定变量到特定内存段 - **配置示例**: ```c /* 自定义存储类生成代码 */ #pragma section="MY_SECTION" // 指定内存分区 int32_T customVar; ``` - **适用场景**: - 嵌入式系统内存分区需求 - AUTOSAR/ISO26262等标准的内存保护要求 --- ### 对比总结表 | 存储类 | 存储位置 | 作用域 | 代码控制权 | 典型应用场景 | |----------------------|---------------|--------------|------------|-----------------------| | Auto | 编译器决定 | 局部/临时 | 低 | 快速原型开发 | | ExportedGlobal | 全局内存 | 全局 | 中 | 跨模块数据共享 | | ImportedExtern | 外部定义 | 外部链接 | 高 | 集成已有代码库 | | ImportedExternPointer| 外部指针 | 动态映射 | 高 | 硬件寄存器访问 | | Custom | 自定义内存段 | 可指定 | 最高 | 嵌入式系统内存约束[^3]| --- ### 选择建议 1. 优先使用`Auto`进行快速验证 2. 需要与外部代码交互时选择`ImportedExtern`或指针版本 3. 嵌入式系统中需内存分区的场景必须使用`Custom`存储类 4. 注意自定义存储类的路径配置问题(如MATLAB搜索路径影响可见性[^3])
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡洛斯伊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值