主要内容

创建一个基本的C MEX S-Function

关于C MEX S-Functions

您可以使用以下任何一种方法来创建C MEX s -函数:

  • 手写s函数——您可以从头开始编写一个C MEX s函数。(创建一个基本的C MEX S-Function提供了一个循序渐进的示例。)看到C s -函数模板获取一个完整的C MEX s -函数框架实现,您可以使用它作为创建自己的s -函数的起点。

  • S-Function Builder -这个模块集成了一个C/ c++代码,并根据您使用图形用户界面提供的规范和代码片段构建了一个C MEX s -函数。这消除了从头开始编写s函数的需要。看到使用带有s函数生成器的总线信号来创建s函数有关S-Function Builder的更多信息。

  • 遗留代码工具——这个工具从现有的C代码和使用MATLAB提供的规范中构建一个C MEX s函数®代码。看到使用遗留代码工具集成C函数,以获取有关将遗留C代码集成到Simulink中的更多信息金宝app®模型。

每种方法都涉及到编写s函数的便利性和s函数支持的特性之间的权衡。金宝app尽管手写的s函数支持最广泛的功能,但它们可能很难书写。金宝appS-Function Builder块简化了编写C MEX S-functions的任务,但支持的特性更少。金宝app遗留代码工具提供了从现有C代码创建C MEX s -函数的最简单方法,但支持的特性最少。金宝app看到可用的功能实现,以获取关于编写C MEX s -函数的每种方法的特性和限制的更多信息。

如果你有金宝app仿真软件编码器™,除上述三种方法外金宝app仿真软件编码器产品提供了一种从图形子系统生成C MEX s -函数的方法。如果您是编写C MEX s -函数的新手,那么可以在Simulink子系统中构建部分应用程序,并使用s -函数目标将其转换为s -函数。金宝app生成的文件提供了如何在s函数中实现特定块的详细信息。使用S-function目标的详细信息和限制请参见利用s -函数目标加速仿真、重用代码或保护知识产权(金宝app仿真软件编码器).您可以使用与Simulink引擎交互的API开发一个s函数来表示外部代码。金宝app在代码生成器中使用这个s函数来生成代码。有关代码生成中不同类型s -函数的详细信息,请参见s -函数和代码生成(金宝app仿真软件编码器)

C MEX s -函数必须在模拟过程中向Simulink引擎提供有关函数的信息。金宝app随着模拟的进行,引擎、ODE求解器和C MEX s -函数交互以执行特定的任务。这些任务包括定义初始条件和块特征,计算导数、离散状态和输出。

与MATLAB的s函数一样,Simulink引擎与一个金宝appC MEX s -函数通过调用s -函数实现的回调方法。每个方法执行预定义的任务,例如计算块输出,需要模拟s -函数定义的块的功能。但是,s函数可以根据s函数实现的功能自由地在每个方法中执行任务。例如,mdlOutputs方法必须在当前仿真时间计算块输出。然而,s函数可以以任何适合该函数的方式计算这些输出。这个基于回调的API允许您创建任何所需功能的S-functions和自定义块。

C MEX s -函数可以实现的回调方法集比MATLAB s -函数可用的回调方法集要大。C MEX s -函数只需要实现s -函数API中回调方法的一小部分。如果你的块没有实现一个特定的功能,比如矩阵信号,你可以省略实现一个功能所需要的回调方法。这允许您非常快速地创建简单的块。

C MEX s -函数的一般格式如下所示:

#定义S_FUNCTION_NAMEyour_sfunction_name_here#define S_FUNCTION_LEVEL 2 #include " SimStruct .h" static void mdlinitializesize (SimStruct *S) {}<附加功能的例程/代码>static void mdlTerminate(SimStruct *S) {} #ifdef MATLAB_MEX_FILE /*这个文件被编译为一个mex文件吗?*/ #include "金宝appsimulink.c" /* MEX-file接口机制*/ #else #include "cg_sfun.h" /*代码生成注册函数*/ #endif .h

mdlInitializeSizes是Simulink引擎在与s函数交互时调用的第一个金宝app例程。引擎随后调用其他S-function方法(所有方法都以mdl).在模拟的最后,引擎调用mdlTerminate

介绍一个基本的C - MEX s -函数示例

本节提供了一个C MEX s -函数的示例,您可以使用它作为创建简单C - s -函数的模型。s函数的例子timestwo.c输出为输入的两倍。

下面的模型使用timestwos函数使正弦波的振幅加倍,并在示波器上绘图。

s函数指定的块对话框timestwo作为s函数名;parameters字段为空。

timestwoS-function包含如图所示的S-function回调方法。在S-function的末尾,包括如下所述的代码片段金宝app模型/仿真软件编码器接口

的内容timestwo.c如下所示。示例之后提供了代码描述。

#define S_FUNCTION_NAME timesttwo /* . define S_FUNCTION_NAME timesttwo /* . define S_FUNCTION_NAME timesttwo定义,包括*/ #define S_FUNCTION_LEVEL 2 #include " simstruct .h"
静态的空白mdlInitializeSizes(SimStruct *S) {ssSetNumSFcnParams(S, 0);if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)){返回;/* Simulink引擎报告的参数不匹配*/}if (!金宝appssSetNumInputPorts(年代,1))返回;ssSetInputPortWidth(年代,0,DYNAMICALLY_SIZED);ssSetInputPortDirectFeedThrough (0, 1);如果(! ssSetNumOutputPorts(年代,1))返回;ssSetOutputPortWidth(年代,0,DYNAMICALLY_SIZED);ssSetNumSampleTimes (S, 1);/*当指定异常空闲代码时要小心-参见sfuntmpl.doc */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);}
静态的空白mdlInitializeSampleTimes(SimStruct *S) {ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);ssSetOffsetTime(年代,0,0.0);}
静态的空白mdlOutputs(SimStruct *S, int_T tid) {int_T i;InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);real_T *y = ssGetOutputPortRealSignal(S,0); / /输出int_T width = ssgetoutputporttwidth (S,0); / /输出(我= 0;我<宽度;i++) {*y++ = 2.0 *(*uPtrs[i]);} }
静态的空白mdlTerminate(SimStruct * S) {}
#ifdef MATLAB_MEX_FILE /*该文件被编译为mex文件吗?*/ #include "金宝appsimulink.c" /* MEX-file接口机制*/ #else #include "cg_sfun.h" /*代码生成注册函数*/ #endif .h

这个例子有三个部分:

  • 定义,包括

  • 回调方法的实现

  • 金宝app仿真软件(或金宝app仿真软件编码器)产品的接口

定义,包括

这个例子从下面开始定义语句。

#define S_FUNCTION_NAME timesttwo #define S_FUNCTION_LEVEL 2

第一个定义语句指定s函数的名称(timestwo).第二个定义语句指定s函数在2级格式(有关第1级和第2级s函数的更多信息,请参阅转换一级C MEX s -函数).

定义了这两项之后,示例包括simstruc.h,这是一个头文件,用于访问SimStruct数据结构和MATLAB应用程序接口(API)函数。

#define S_FUNCTION_NAME timesttwo #define S_FUNCTION_LEVEL 2 #include " simstruct .h"

simstruc.h文件定义了一个数据结构,称为SimStruct, Simulink引金宝app擎用来维护关于s函数的信息。的simstruc.h文件还定义了宏,使MEX文件能够在中设置值并从块中获取值(例如输入和输出信号)SimStruct(见关于SimStruct函数).

回调方法的实现

下一部分timestwo函数包含必需的回调方法的实现。

mdlInitializeSizes

Simu金宝applink引擎调用mdlInitializeSizes查询输入和输出端口的数量、端口的大小以及s函数所需的任何其他信息(如状态的数量)。

timestwo的实现mdlInitializeSizes指定以下大小信息:

  • 零参数

    因此,功能参数“功能块参数”对话框中的字段必须为空。如果它包含任何参数,则引擎报告参数不匹配。

  • 一个输入端口和一个输出端口

    输入和输出端口的宽度是动态调整的。这告诉引擎s功能可以接受任何宽度的输入信号。缺省情况下,当S-function只有一个输入和输出端口时,动态大小的输入和输出端口的宽度是相等的。

  • 一个样品时间

    mdlInitializeSampleTimesCallback方法指定样本时间的实际值。

  • 除了免费代码

    指定无异常代码可以加快s函数的执行。在指定此选项时必须小心。通常,如果您的s函数没有与MATLAB环境交互,您可以安全地指定此选项。有关详细信息,请参见金宝app与C - s -函数的Simulink引擎交互

mdlInitializeSampleTimes

Simu金宝applink引擎调用mdlInitializeSampleTimes来设置s函数的采样次数。一个timestwo当驱动块执行时,块也执行。因此,它只有一个继承的样本时间,INHERITED_SAMPLE_TIME

mdlOutputs

引擎调用mdlOutputs在每个时间步骤计算块输出。的timestwo的实现mdlOutputs把输入信号乘以2,然后把答案写在输出信号上。

线:

InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);

访问输入信号。的ssGetInputPortRealSignalPtrs宏返回一个指针向量必须访问使用

* uPtrs[我]

有关访问输入信号的详细信息,请参见使用指针访问信号

线:

real_T *y = ssGetOutputPortRealSignal(S,0); / /输出

访问输出信号。的ssGetOutputPortRealSignal宏返回一个指向包含块输出的数组的指针。

线:

int_T width = ssgetoutputporttwidth (S,0); / /输出

获取通过该块的信号的宽度。s函数在输入上循环计算输出。

mdlTerminate

引擎调用mdlTerminate为s功能提供了在仿真结束时执行任务的机会。这是一个强制性的s函数程序。的timestwos函数不执行任何终止操作,并且此例程为空。

金宝app/金宝app编码器接口

在s函数的末尾,包括以下代码以将s函数附加到Simulink或金宝app金宝app仿真软件编码器下载188bet金宝搏产品。

#ifdef MATLAB_MEX_FILE #include "金宝appsimulink.c" #ifdef MATLAB_MEX_FILE #include "simulink.c" #ifdef MATLAB_MEX_FILE #include "simulink.c" #

每个s功能的结尾都需要这个拖车。如果省略它,编译s函数的任何尝试都将用导出文件构建过程中的失败错误消息。

构建timesttwo示例

要编译这个s函数,输入

墨西哥人timestwo.c

在命令行。的墨西哥人命令编译并链接timestwo.c文件使用默认编译器。的墨西哥人命令为要使用的Simulink软件创建一个可动态加载的可执行文件。金宝app如果您有多个matlab支持的编译器,您可以使用金宝app墨西哥人设置命令。看到改变默认的编译器以及金宝app支持编译器

得到的可执行文件称为MEX s -函数,其中MEX代表“MATLAB可执行文件”。MEX文件扩展名因平台而异。例如,在32位的Microsoft上®窗户®system中,MEX文件扩展名为.mexw32