本文研究 Initialize Function子系统、建模方法及其生成的代码。


文章目录

  • 1 问题引入
  • 2 Initialize Function子系统
  • 3 建模示例与代码生成
  • 3.1 模型搭建
  • 3.2 代码生成
  • 4 生成Terminate或Reset函数
  • 5 总结


1 问题引入

博主在以前的博客中经常研究step函数中的内容,因为step函数中的代码和Simulink模型中的算法密切相关。对于初始化函数,博主研究的比较少,但也十分重要。在控制器上电的时候,由操作系统调用一次初始化函数。

通过配置Simulink.Signal对象,可以将输入输出的初始化函数生成在initialize中,具体方法可以参考《Simulink代码生成: 信号线、参数配置》。

simulink function 网络 simulink initialize function_simulink


除了这种方式,也可以在Initialize Function子系统中搭建初始化函数的模型。相比于上一种方式,Initialize Function子系统生成的初始化函数可以更加灵活,而不仅限于赋值一个常数。

2 Initialize Function子系统

新建一个Initialize Function子系统,如下图。

simulink function 网络 simulink initialize function_建模_02


子系统中央用initialize标识出它是一个Initialize Function子系统,可以和其他子系统区分开来。双击进入子系统,可以看到顶部有一个Event Listener模块。该模块可以配置成Initialize、Terminate和Reset三种形式,对应了三种子系统。

simulink function 网络 simulink initialize function_simulink_03


下面默认的输入很输出分别是常数模块和State Writer模块,后面建模演示的过程中不用这两种模块。

simulink function 网络 simulink initialize function_初始化_04

3 建模示例与代码生成

本章节假设输出信号初始化为一个外部的全局变量经过简单的放大运算,来演示博主平时使用Initialize Function子系统建模和生成代码的方法。

3.1 模型搭建

1)在Matlab命令行输入以下命令。

>> a1 = Simulink.Signal;

然后会在工作区新建一个名为a1的Signal对象。

simulink function 网络 simulink initialize function_初始化_05


2)双击工作区的a1对象,将Data type,Dimensions,Dimensions mode,Complexity,Storage Class属性改为下图所示。

simulink function 网络 simulink initialize function_建模_06


注意,这里Storage Class属性为ImportedExtern,表示这是一个外部的全局变量。后续建模会将a1这个全局变量在初始化函数中赋值给输出信号。3)进入Initialize Function子系统中,建立一个Data Store Read模块,一个Gain模块和outport模块。Data Store Read模块读出的名字是上一步建立的a1。

simulink function 网络 simulink initialize function_建模_07


这么做的含义是,想要在生成的初始化函数中,将外部的全局变量a1乘以2,然后赋值给Output变量。4)退出到Initialize Function子系统外的顶层模型,建立一个Function-Call子系统。

simulink function 网络 simulink initialize function_simulink_08


这个Function-Call子系统就会生成一个对应的step函数。双击进入Function-Call子系统,配置一个简单的输入输出和Gain模块。那么step函数中应该是将输入变量乘以2再赋值给输出变量。

simulink function 网络 simulink initialize function_赋值_09


5)退出到顶层模型,用merge模块把Initialize Function子系统和Function-Call子系统的输出信号合并到一起。这个用法的原因是,这两个输出信号本质上是一个变量,只是出现在了不同函数中。在《Simulink代码生成: If-Action子系统及其代码》一文中也曾经有过这种用法。

simulink function 网络 simulink initialize function_初始化_10


这样的话,这个简单的demo模型就建立好了。

3.2 代码生成

配置好Embedded Coder,然后Ctrl + B生成代码如下。

simulink function 网络 simulink initialize function_simulink_11


主要观察以下demo.c中的step函数和initialize函数。在step函数中,每个步长将In1乘以2赋值给Out1;在initialize函数中,将a1乘以2赋值给Out1,作为Out1的初始值。

说明通过Initialize Function子系统,就可以通过建模的方法,在初始化函数中赋初始值。相比与在数据字典中填写初始值,这种方法会更加灵活,一更多的可操作空间。

4 生成Terminate或Reset函数

通过配置Initialize Function子系统中的Event Listener模块,就可以将该模块变成Terminate或Reset子系统。子系统上会有不同的图标和文字,如下图。

simulink function 网络 simulink initialize function_初始化_12


simulink function 网络 simulink initialize function_赋值_13


生成代码的时候也会生成对应函数的代码。

simulink function 网络 simulink initialize function_simulink_14


simulink function 网络 simulink initialize function_初始化_15

5 总结

Initialize Function子系统可以很灵活地控制生成初始化函数的代码,因此对初始化函数有一定需求的时候可以考虑这种建模方式。