Matlab S-function封装学习总结

本文介绍了如何在MATLABSimulink中使用C语言进行S-function的封装,包括选择代码模板、配置函数名称、设定输入输出参数、指定采样率、计算输出信号等步骤,并详细讲解了每个步骤的功能和实现方法。同时,文章还提到了如何进行编译、关联模型以及创建Mask界面,以提供友好的用户交互。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

最近学习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 中国

  1. 设置函数名称
#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)
  • 代码编译
  1. 环境准备

查看matlab是否安装编译器MinGW-w64

mex -setup

环境安装步骤

将TDM-GCC-64.zip 解压在C盘,注意路径不能有空格

配置环境变量

2.编译指令

mex filename -I./

链接其他库的时候

mex filename -I./ -L./

编译成功后会生成64位Windows版本的动态链接库

  • 关联模型
  1. 编写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;

  1. 打开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 刷新界面然后就可以出来封装的模型。

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值