S-function学习
Matlab S-function封装学习总结
<div class="operating">
<a class="href-article-edit slide-toggle">版权</a>
</div>
</div>
</div>
</div>
<div class="ai-abstract-box">
<div class="ai-abstract">
<div class="abstract-content">
<img class="lock-img" src="https://img-home.csdnimg.cn/images/20240711042549.png" alt="">
本文介绍了如何在MATLABSimulink中使用C语言进行S-function的封装,包括选择代码模板、配置函数名称、设定输入输出参数、指定采样率、计算输出信号等步骤,并详细讲解了每个步骤的功能和实现方法。同时,文章还提到了如何进行编译、关联模型以及创建Mask界面,以提供友好的用户交互。
</div>
<span>摘要由CSDN通过智能技术生成</span>
</div>
<p class="abstract-ab">展开 <img class="lock-img" src="https://img-home.csdnimg.cn/images/20240708095038.png" alt=""></p></div>
<article class="baidu_pl">
<div id="article_content" class="article_content clearfix">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-704d5b9767.css">
<div id="content_views" class="htmledit_views">
<blockquote>
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
最近学习S-function封装,以下为学习过程中的总结。
一、代码封装
代码模板

选择User-Defined Functions --> S-Function Examples -->C-files -->sfuntmpl_basic.c
查阅函数的作用以及使用方法可通过官网查询,如下
配置 C/C++ S-Function 功能 - MATLAB & Simulink - MathWorks 中国
配置 C/C++ S-Function 功能- MATLAB & Simulink- MathWorks 中国
- 设置函数名称
- #define S_FUNCTION_NAME sfuntmpl_basic //这里修改函数名称
-
- #define S_FUNCTION_LEVEL 2
2. 配置输入、输出、参数
- static void mdlInitializeSizes(SimStruct *S)
- {
-
-
- //(1)参数配置
-
- ssSetNumSFcnParams(S, 0); //设置参数个数 /* Number of expected parameters */
-
- if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
-
- /* Return if number of expected != number of actual parameters */
-
- return;
-
- }
-
-
-
- ssSetNumContStates(S, 0); //指定 块具有的连续状态数
-
- ssSetNumDiscStates(S, 0); //指定 块具有的离散状态数
-
- //(2)输入端口配置
-
- if (!ssSetNumInputPorts(S, 1)) return;//配置输出端口个数
-
- ssSetInputPortWidth(S, 0, 1);//指定输入端口宽度
-
- ssSetInputPortRequiredContiguous(S, 0, true); /*direct input signal access*/
-
- /*
- * Set direct feedthrough flag (1=yes, 0=no).
- * A port has direct feedthrough if the input is used in either
- * the mdlOutputs or mdlGetTimeOfNextVarHit functions.
- */
-
- ssSetInputPortDirectFeedThrough(S, 0, 1);
-
-
-
- //(3)输出端口配置
-
- if (!ssSetNumOutputPorts(S, 1)) return;//配置输入端口个数
-
- ssSetOutputPortWidth(S, 0, 1);//指定输出端口宽度
- ssSetNumSampleTimes(S, 1);
- ssSetNumRWork(S, 0);
- ssSetNumIWork(S, 0);
- ssSetNumPWork(S, 0);
- ssSetNumModes(S, 0);
- ssSetNumNonsampledZCs(S, 0);
-
- /* Specify the sim state compliance to be same as a built-in block */
- ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
-
- ssSetOptions(S, 0);
-
- }
3.指定此 C MEX S 函数运行的采样率
static void mdlInitializeSampleTimes(SimStruct *S)
4.初始化 此 C MEX S 函数的状态向量
static void mdlStart(SimStruct *S)
5.计算输出模块的输出信号
- static void mdlOutputs(SimStruct *S, int_T tid)
- {
-
- //获取输入端口的指针/地址
- const void *ssGetInputPortSignal(SimStruct *S, int_T inputPortIdx)
-
-
-
- const real_T *u0 = (const real_T*) ssGetInputPortSignal(S,0);
-
-
-
- //获取输出端口的指针/地址
- void *ssGetOutputPortSignal(SimStruct *S, int_T port)
-
- real_T *y = ssGetOutputPortSignal(S,0);
-
-
-
- //获取参数指针/地址
- const mxArray *ssGetSFcnParam(SimStruct *S, int_T index)
-
- //获取参数1,double类型
-
- const real_T *param1 = (const real_T *)mxGetData(ssGetSFcnParam(S, 0));
-
- double a = (double) *param1;
-
- //获取参数2,string类型
-
- const unsigned char *param2 = (const unsigned char *)mxArrayToString(ssGetSFcnParam(S, 1));
-
- const int_T p_width = mxGetNumberOfElements(ssGetSFcnParam(S, 1));
-
- unsigned char *str = (unsigned char *)mxCalloc(p_width, sizeof(unsigned char));
-
- memcpy(str, param1, p_width);
- }
6.更新块的状态
static void mdlUpdate(SimStruct *S, int_T tid)
7.计算 C MEX S 函数的导数
static void mdlDerivatives(SimStruct *S)
8.执行仿真终止时所需的任何操作
static void mdlTerminate(SimStruct *S)
- 代码编译
- 环境准备
查看matlab是否安装编译器MinGW-w64
mex -setup
环境安装步骤
将TDM-GCC-64.zip 解压在C盘,注意路径不能有空格
配置环境变量

2.编译指令
mex filename -I./
链接其他库的时候
mex filename -I./ -L./
编译成功后会生成64位Windows版本的动态链接库

![]()
- 关联模型
- 编写m文件
修改slblocks.m文件
- function blkStruct = slblocks
-
- blkStruct.Name = ['add'];
-
- blkStruct.OpenFcn = 'add;
- blkStruct.MaskDisplay = '';
- Browser(1).Library = 'add';
- Browser(1).Name = 'add';
- Browser(1).IsFlat = 0;
- blkStruct.Browser = Browser;
- 打开Simulink,新建Model
添加S-Function 模型

如图 双击S-Function 模型 后,弹出 Block Parameter窗口 ,点击 Edit 后选择Browser 关联代码封装的 .c文件。

S-Function name 填入S-function的函数名称,这样就建立了S-function模块与M文件形式的S-function之间的对应关系;
S-Function parameters 填入S-function需要输入的外部参数的名称,如果有对各变量,则变量中间用逗号隔开,如a,b,c;
S-Function modules 仅当S-function是用C语言编写并用MEX工具编译的C-MEX文件时,才需要填写该参数;

- Mask封装
右键点击S-Function 模块,选中 Mask选项 --> Create Mask Editor 创建模板界面


lcon &Ports 页面填写模块界面输出
- %参数显示
-
- showInfo = sprintf('a: %s\nb: %s\nc: %s\n',get_param(gcb,'a'),get_param(gcb,'b'),get_param(gcb,'c'));
-
- disp(showInfo);
-
-
-
- %输入端口名称显示
-
- port_label('input',1,'DataInput1');
-
-
-
- %输出端口名称显示
-
- port_label('output',1,'DataOutput1');
Parameters & Dialog 界面
设置和绑定参数控件
Initialization页面
可以添加参数初始化命令
Documentation 页面
可以添加模型说明
最后将模块的名称 S-Function更改;
效果如下:

- 将S-Function添加到simulink库中
将 模型复制和保存为Library 文件

设置路径

打开Simulink Library Browser库文件
右键选中 Refresh Library Browser 刷新界面然后就可以出来封装的模型。

</article>


浙公网安备 33010602011771号