在前两节的基础上我们继续来学习代码的优化,没看过我前两篇文章的可以先去看一下,否则可能觉得模型出现的很突兀。这一节我们来学习原子子系统,废话不多说,我们直接开始学习,看完了这一篇你就会明白什么是原子子系统以及原子子系统到底有什么作用。
一. 重复的功能模块
在现实应用当中我们经常能遇到功能相同的模块,现在假设有三个模块,其功能一模一样。实现的都是:
Y
1
=
(
X
1
+
X
2
)
∗
X
3
Y1 = (X1+X2) * X3
Y1=(X1+X2)∗X3
所搭建的3个功能相同的模型如下图。
在Build(Ctrl+D)没有问题后,我们来生成代码(Ctrl+B),所生成的代码如图所示。可以看到同样的功能代码生成了三次,这看上去好像也没什么,也就占了三行。但在实际编写代码时,实现一个功能的代码可能有成百上千行,此时我们再将代码写三次抑或是更多次,每次变量名还不能一样,这种做法显然是非常愚蠢的。因此通常的做法是将一个功能模块封装成一个函数,需要时我们只需要调用这个函数就可以了,这样可以大大减少代码量以及增加代码的可读性。原子子系统就可以解决以上问题,接下来我们就来揭开它神秘的面纱。
二. 建立原子子系统
(1)首先,我们需要建立一个原子子系统,选中第一个功能模块,鼠标右键,选择创建子系统。
(2)创建完成后,基于视觉上的享受,我们将子系统模块调整至合适大小,将所有信号线拉直,这看似对功能没有什么影响,但如果模块多了,功能复杂了,这将是非常有意义的一件事,否则别人阅读起来将是非常困难的,甚至自己过一段时间也会感觉很难看懂。实际上如果你去一家大企业工作,他们也是这么要求的,信号线基本不允许交叉,每一个信号线尽量保证是直的,除非确实需要弯。因此,我们要提前养成良好的习惯。回到正题,接下来选中所创建的子系统,鼠标右键,然后选择Block Parameters(Subsystem)创建一个子系统。
(3)在弹出的对话框中进行如下设置。Function packaging是必须进行设置的,如果是默认状态,生成的代码将不会改变。Function name可以设置也可以不设置,不设置系统将自动分配一个名字,基本是:模型名_Subsystem。在这里我还是喜欢自己命名,实际编程时函数的名字也不是随意写的,函数名应该能尽量表示该函数所实现的功能。
(4)其它两个模块也按照上述方式进行设置,或将设置好的模块复制两份,完成后如图所示。
(5)再次生成代码,可以看到生成了一个名为MySelfFunction函数,所实现的功能正是我们之前提到的:
Y
1
=
(
X
1
+
X
2
)
∗
X
3
Y1 = (X1+X2) * X3
Y1=(X1+X2)∗X3
该函数在Calculation.c中被调用了三次,与之前直接写三次 Y1 = (X1+X2) * X3 有所区别,这正是我们想要的。
除了以上建立原子子系统的方式,我们也可以在 Simulink Library Browser 中找到相应的模块,拖拽出来进行相应的配置,结果是一样的。
三. 原子子系统生成单独的文件
时候我们不仅仅需要将功能封装成函数,甚至还需要将一个功能独立成一个文件,方便其它文件调用。这时我们就需要将函数独立出来,接下来我们就进行相应的配置。
(1)依然是选中子系统,右键弹出的对话框选择Block Parameters(Subsystem)。对 File name options 及 File name 进行设置,如图所示(命名可以随意,但最好具有实际意义)。
(2)再次编译并生成代码,可以看到生成了一个名字为 MySelfFunction.c 的源文件和一个名为 MySelfFunction.h 的头文件,函数名字不变,函数调用也没变。
四. 数据类型不同的原子子系统
接下来我们看一下,若将第一个模块的输入类型改变后将会怎样,选中输入端子,将数据类型改成uint16(也可自己定),同样的方式将X2和X3的数据类型也改为uint16,另外两个子系统模块输入不变。
完成以上修改后再次进行编译,可以发现系统报错,原因是不同数据类型的原子子系统使用了相同的函数名。
将第一个子模块的函数名变为MySelfFunction1(为了区别于MySelfFunction),这样函数名就不会重复了,再次进行代码生成。
可以看到,新生成的 MySelfFunction.c 文件中增加了一个输入类型为uint16,返回类型为uint32的函数MySelfFunction1(),为什么返回类型会变,是为了防止数据溢出。输入类型不同,返回类型不同的两个函数不可能是同一个函数,这也是之前报错的原因。
在函数的调用时也可以看到,不同的数据类型调用了不同的函数,这才是符合要求的。
五. 总结
以上就是原子子系统的建立方法及用途,在实际的工作中原子子系统将会经常用到,希望以上内容能够对大家有所帮助。接下来的文章中,我们将继续讲解代码的其它优化,欢迎大佬批评指正,同时也欢迎小伙伴们前来交流。