在之前的帖子里(http://blogs.mathworks.com/simulink/2014/12/11/simulink-functions-intro/),我重点介绍了怎么使用SimulinkFunction来构造可以导出为函数的模型,这样可以把SimulinkFunction模块放在单独的模型里。在仿真的时候,可以引用这个模型,然后使用FunctionCaller模块来调用它。
还可以将这个FunctionLibrary模型生成代码,在自己的手写代码里就可以任意调用这些函数了。
没有提到的一点是,SimulinkFunction和FunctionCaller模块完全可以反过来用。也就是说,在被引用的模型里放FunctionCaller模块,而在主模型里放被调用的SimulinkFunction模块。
为什么要这样做?简而言之,这是为了模拟一些不直接用于仿真的自定义代码。我们来看看这是如何实现的。
使用FunctionCaller模块来调用外部代码
如果我们把上面的子模型codeGenModel.xls生成代码的话,代码就像下面这样:
默认情况下,这个代码不会被编译,因为编译器不知道上哪找这个timesTwo函数。如果你知道怎么去配置模型,这个函数timesTwo可以从任意地方提供。比如在这个例子里,假设我们有一个timesTwo.c文件。
在模型的配置项里,我可以通过设置把这个文件包含到编译过程中去。
这样,我就可以调用我自己写的timesTwo.c然后编译成可执行文件了。
总结来说,可以通过构造一个SimulinkFunction来模拟外部代码。
我们可以构造一个仿真框架模型(如第二张图的simTop),然后引用我们的算法模型(比如codeGenModel.xls)。对于这个算法子模型来说,被它调用的SimulinkFunction(对于simTop来说)是可见的。但是,当把子模型(codeGenModel单独)生成代码的时候,它并不知道(主模型里的)SimulinkFunction的存在,而相应的,它会链接到你所指定的那个外部代码(timesTwo.c)上去。
我必须得说明一下,这只是众多往Simulink自动生成的代码中插入外部代码的方法之一。
如果在主机上就有外部代码的话,我会推荐使用S-function来包装和重用,可用于仿真和代码生成。
但是,如果没有外部代码,比如说这些代码是目标板上面的OS服务程序,那么这种方法倒有点意思(用SimulinkFunction来模拟这些硬件OS服务程序)。