Simulink代码生成: Optimization配置

本文研究Embedded Coder中的Optimization配置,通过一些模型示例和代码直观地比较配置对代码生成的影响。由于配置选项很多,本文会长期更新。

文章目录

  • 1 Optimization配置
  • 2 Default parameter behavior
    • 2.1 描述
    • 2.2 模型示例
    • 2.3 生成代码
    • 2.4 分析与思考
  • 3 Pass reusable subsystem outputs as
    • 3.1 描述
    • 3.2 模型示例
    • 3.3 生成代码
    • 3.4 分析与思考

1 Optimization配置

Optimization配置中包含了代码生成的优化选项。在Simulink配置窗口的Code Generation下可以找到Optimization配置。
Simulink代码生成: Optimization配置_第1张图片
后文会研究Optimization配置中的一些常用选项。

2 Default parameter behavior

2.1 描述

该配置直译过来是“默认参数行为”,其含义是,生成代码时常量参数的形式。

该配置中包含两个选项:Tunable和Inlined。如果选Tunable,意为可调式,生成的代码就会以StorageClass中的Auto类来表现常数参数。如果选Inlined,意为内联式,会把参数“内联”到代码中,表现为直接的数值。

配置中默认为Inlined。
Simulink代码生成: Optimization配置_第2张图片

2.2 模型示例

打开Simulink,建立一个简单的带有Gain模块的模型。
Simulink代码生成: Optimization配置_第3张图片
将Gain模块的增益系数写为3.观察后续这个系数在代码中的表现方式。
Simulink代码生成: Optimization配置_第4张图片

2.3 生成代码

1)当Default parameter behavior选为Tunable时,生成的代码如下:
Simulink代码生成: Optimization配置_第5张图片
可以看出,输入变量乘以一个系数demo_P.Gain_Gain。这个变量在demo_data.c中定义。
Simulink代码生成: Optimization配置_第6张图片
2)当Default parameter behavior选为Inlined时,生成的代码如下:
Simulink代码生成: Optimization配置_第7张图片
这里可以看出,系数直接写成了3.0F这个浮点数。也就是说,把Gain参数“内联”到代码中了。

2.4 分析与思考

比较两种代码生成的方式,显然是Inlined更好。这是因为将参数生成全局变量会占据芯片的RAM资源。

在企业级项目中,每个模型都可能有数十个这种常量,广泛地存在于Constant,Gain等模块中。如果这些常量占据了大量的RAM资源,就可能会导致链接过程中出现资源溢出。

3 Pass reusable subsystem outputs as

3.1 描述

这个配置项影响了可复用子系统的输出生成的代码。

下拉框包含两个选项。默认的是Individual arguments,指的是输出为局部变量。还有一个选项是Structure reference,他会生成一个全局结构体变量,然后可复用子系统对应的函数会调用这个结构体的指针。
Simulink代码生成: Optimization配置_第8张图片

3.2 模型示例

建立如下图模型,将两个完全相同的子系统配置为原子子系统以及可复用函数。这样模型就符合这个配置项的场景了。

原子子系统内随便什么模型都可以,这里用了个比较简单的Gain模块。
Simulink代码生成: Optimization配置_第9张图片

3.3 生成代码

1)当Pass reusable subsystem outputs as这个配置选为Individual arguments时,代码生成如下:
Simulink代码生成: Optimization配置_第10张图片
可以看出,在只有一个返回值的情况下,子系统所对应的函数直接把计算结果返回。在step函数中直接把结果赋值给Out1或者Out2。

因为模型比较简单,在step函数中把局部变量优化掉了。如果比较复杂的模型会把demo_Subsystem的结果先赋值给一个局部变量,然后参与后续的运算。

2)当Pass reusable subsystem outputs as这个配置选为Structure reference时,代码生成如下:
Simulink代码生成: Optimization配置_第11张图片
可以看出函数复杂了一些。首先是生成了一个结构体的全局变量demo_B,这里面存的是子系统的输出值。然后子系统对应的函数,用了个结构体指针获取返回值。

再看看下图中的Step函数:
Simulink代码生成: Optimization配置_第12张图片
step函数是先用demo_Subsystem这个函数更新了全局变量结构体里的成员,然后再把成员变量的值赋值给Out1或Out2。这样,在这个过程中就没有局部变量了,而是多了全局变量。

3.4 分析与思考

正所谓鱼和熊掌不可兼得,这两种方式就是对局部变量和全局变量的取舍。多生成一些全局变量,就用Structure reference,多生产一些局部变量,就用Individual arguments

博主根据个人经验认为,汽车ECU软件一般已经用了很多全局变量,包括模型输入输出接口和观测量等都是全局变量。所以全局变量占据的RAM资源是比较稀缺和紧张的,这里按照Simulink默认的Individual arguments配置比较好,也就是多生成些局部变量。

而且,从代码复杂度的角度来说,也是Individual arguments配置更优。

你可能感兴趣的:(Simulink代码生成)