首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Simulink代码生成:通过Matlab Function集成C函数

  • 23-09-22 01:03
  • 4234
  • 11905
blog.csdn.net

本文研究如何在Matlab Function模块中调用外部的C函数,以及一些注意点。

文章目录

  • 1 问题引入
  • 2 简单例程
    • 2.1 创建C文件和头文件
    • 2.2 在Matlab Function中调用C函数
    • 2.3 仿真及代码生成
  • 3 其他技巧和注意点
    • 3.1 在Simuink中配置C文件和头文件
    • 3.2 C函数传入指针参数
  • 4 总结

1 问题引入

博主以前写过一篇博客《Simulink代码生成:通过Legacy Code Tool集成C函数》,可以在Simulink模型中调用外部的C代码。在Matlab Funciton中,用m语言写着代码,突然想要调用一个现成的C文件中的函数是不是也可以呢。答案是肯定的,而且调用的方法比LCT还要更简单一些。本文会用一个简单的例子来演示在Matlab Function模块中调用外部的C函数的方法。

2 简单例程

2.1 创建C文件和头文件

首先先在当前路径下创建一个C文件和一个头文件,如下图所示:
在这里插入图片描述
C文件内容如下所示,实现了一个简单的勾股定理的计算:

//gougu.c
#include 
#include "gougu.h"

float gougu(float a, float b)
{
    float c;
    c = sqrt((pow(a,2) + pow(b,2)));
    return c;    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

头文件内容如下所示,对函数进行外部声明:

// gougu.h
extern float gougu(float a, float b);
  • 1
  • 2

2.2 在Matlab Function中调用C函数

1)新建一个Simulink空白模型demo.slx,在其中加入两个输入port,一个输出port和Matlab Function:
在这里插入图片描述
这里博主把数据类型强制设为single,为了和C代码匹配,否则后面会报错。在实际使用的过程中如果调用的C代码传参类型和Matlab中不一致也会报错,这个要注意。

2)双击进入Matlab Function,改成如下m代码:
在这里插入图片描述
代码很精简,但是其中每一部分都很重要。

首先是用了coder.cinclude和coder.updateBuildInfo函数,添加了调用函数的C文件和头文件。

coder.cinclude('gougu.h');
coder.updateBuildInfo('addSourceFiles', 'gougu.c');
  • 1
  • 2

接下来先要对输出参数做一个初始化,这点是符合C语言的用法,最好要做,否则有可能Matlab Function无法编译通过。

y = single(0);
  • 1

然后再用coder.ceval函数调用外部函数,其中的第一个参数是函数名,后面的参数依次为C函数传入的参数(将Matlab变量传参进入C函数),等号左边是C函数的返回值赋值给Matlab变量。

y = coder.ceval('gougu',u,u2);
  • 1

这样就完成了这个简单的例子,可以在Simulink里仿真C函数了。

2.3 仿真及代码生成

1)将Matlab Function的输入改成常数,输出改成disp模块,可以先仿真看一下调用的效果。
在这里插入图片描述
注意到Matlab当前路径下生成了一个demo_sfun.mexw64文件,这是编译C代码的过程中产生的mex文件。因此,如果修改了C代码后,要先删掉这个mex64文件再重新运行Simulink仿真。

2)在初步验证仿真结果后,把输入输出改成Port,配置代码生成。生成的demo.c文件如下图所示。
在这里插入图片描述
图中可以看出,在生成的代码中调用了gougu()这个C函数。

在生成的demo.h文件中也会包含gougu.h这个头文件。
在这里插入图片描述
最后软件编译的时候不要忘记把外部的C文件和头文件一起加进去。

3 其他技巧和注意点

3.1 在Simuink中配置C文件和头文件

如果模型中有很多地方用了Matlab Function调用外部C文件,每个地方都写上coder.cinclude和coder.updateBuildInfo配置C文件和头文件会很繁琐。这时,可以考虑在Simuink中配置C文件和头文件,该配置会作用于所有Matlab Function。

首先将Maltab Function中的前两行注释掉:

function y = fcn(u , u2)
% coder.cinclude('gougu.h');
% coder.updateBuildInfo('addSourceFiles', 'gougu.c');

y = single(0);
y = coder.ceval('gougu',u,u2);

end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

接着在Simulink配置中的Simulation Target中加上C文件和头文件:
在这里插入图片描述
然后删除当前路径下的mex64文件,再重新仿真Simulink即可。

3.2 C函数传入指针参数

在C语言中,可以传入指针的参数,利用这个指针获取计算的结果,而不是函数return的返回值。这一点也是可以用MatlabFunction做到的。

例如,将C文件和头文件修改一下:

//gougu.c
#include 
#include "gougu.h"

void gougu(float a, float b, float* c)
{
    *c = sqrt((pow(a,2) + pow(b,2)));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
// gougu.h
extern void gougu(float a, float b ,float* c);
  • 1
  • 2

这样的情况下,函数返回为void类型,而返回的结果用float* c这个指针来代替。这样的话,函数体内的计算结果会存放在该指针所指向的内存空间中。

在Matlab Function中要改成如下所示:

function y = fcn(u , u2)
coder.cinclude('gougu.h');
coder.updateBuildInfo('addSourceFiles', 'gougu.c');

y = single(0);
coder.ceval('gougu',u,u2,coder.wref(y));

end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

区别就在于coder.ceval函数调用外部函数时,将等号左边去掉,而是加了一个coder.wref(y)这样的参数来对应C代码中的float* c。具体用法可以参照coder.wref的帮助文档。

生成代码后,如下所示:
在这里插入图片描述
在step函数中调用gougu()函数时,第三个参数传入了Out1的地址(利用&字符取地址),从而也实现了同样的效果。

4 总结

本文研究了通过Matlab Function集成C函数的方法,做了简单的示例。在实际使用时,会遇到比demo更加复杂的情况,例如数组、结构体怎么处理,再例如C代码没办法进去调试等。因此,使用这种方法需要慎重,要进行充分的验证才行。

>>返回个人博客总目录

注:本文转载自blog.csdn.net的chhttty的文章"https://blog.csdn.net/u013288925/article/details/123385821"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top