主要内容

创建一个基本的C mex s函数

关于C MEX S函数

您可以使用以下任何方法创建C MEX S函数:

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

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

  • 遗留代码工具 - 此实用程序从现有C代码和使用MATLAB提供的规格构建C MEX S函数®代码。看使用遗留代码工具集成C函数有关将传统C代码集成到Simulink的详细信息万博1manbetx®楷模。

这些方法中的每一种都涉及易于编写S函数和S函数支持的功能之间的权衡。万博1manbetx虽然手写的S函数支持最广泛的功能,但它们可能很难写。万博1manbetxS-Function Builder块简化了编写C MEX S函数的任务,但支持更少的功能。万博1manbetx遗留代码工具提供了从现有C代码中创建C MEX S函数的最简单方法,但支持最少的功能。万博1manbetx看可用的S函数实现有关这些方法的特征和限制来编写C MEX S函数的更多信息。

如果你有万博1manbetx仿真软件编码器™,除了前三种方法外,还有万博1manbetxSimulink编码器产品提供了一种从图形子系统中生成C MEX S函数的方法。如果您是新的编写C MEX S函数,可以在Simulink子系统中构建应用程序的部分,并使用S函数目标将其转换为S函数。万博1manbetx生成的文件提供有关如何在S函数中实现特定块的洞察力。有关使用S函数目标的详细信息和限制,请参阅通过使用S函数目标加速模拟,重用代码或保护知识产权(万博1manbetxSimulink编码器)。您可以使用与Simulink引擎交互的API开发S-Function来表示外部代码。万博1manbetx使用此S函数与代码生成器生成代码。有关代码生成中的不同类型的S函数的详细信息,请参阅S函数和代码生成(万博1manbetxSimulink编码器)

C MEX S函数必须在模拟期间提供有关Simulink引擎的功能的信息。万博1manbetx由于模拟继续,发动机,颂歌求解器和C MEX S函数相互作用以执行特定任务。这些任务包括定义初始条件和块特征,以及计算导数,离散状态和输出。

与MATLAB的函数一样,Simulink引擎与A相互作用万博1manbetxC MEX S函数通过调用S函数实现的回调方法。每种方法执行预定义的任务,例如计算块输出,所以需要模拟S函数定义的功能的块。但是,S函数可根据S函数实现的功能,在每个方法中自由地执行任务。例如,mdloutputs.方法必须在当前仿真时间计算块输出。但是,S函数可以以适合该功能的任何方式计算这些输出。此基于回调的API允许您创建S函数,并因此创建任何所需功能的S函数。

C MEX S函数可以实现的呼叫方法集大于MATLAB S函数的最大值。C MEX S函数必须仅在S函数API中仅实现回调方法的一个小子集。如果您的块未实现特定的特征,例如矩阵信号,则可以自由省略实现功能所需的回调方法。这允许您非常快速地创建简单的块。

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

#define s_function_name.your_sfunction_name_he#define s_function_level 2 #include“simstruc.h”静态void mdlinitializatized(simstruct * s){}<额外的S函数例程/代码>static void mdlTerminate(SimStruct *S) {} #ifdef MATLAB_MEX_FILE /*这个文件被编译为一个mex文件吗?* / #include“万博1manbetxsimulink.c”/ * mex文件界面机制* / #else #include“cg_sfun.h”/ *代码生成注册函数* / #endif

mdlInitializeSizes是第一个例程在与S函数交互时Simulink引擎呼万博1manbetx叫。引擎随后调用其他S函数方法(所有开始mdl)。在模拟结束时,发动机呼叫mdlTerminate

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

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

下面的模型使用Timestwo.S函数使正弦波的幅度加倍并将其绘制在范围内。

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

Timestwo.S-函数包含此图中显示的S函数回调方法。在S函数末尾,包括如上所述的代码片段万博1manbetx模型/仿真软件编码器接口

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

#define S_FUNCTION_NAME timesttwo /* . define S_FUNCTION_NAME timesttwo /* . define S_FUNCTION_NAME timesttwo定义和包括* / #define s_function_level 2 #include“simstruc.h”
静止空隙mdlInitializeSizes(SimStruct *S) {ssSetNumSFcnParams(S, 0);if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)){返回;/* Simulink引擎报告的参数不匹配*/}if (!万博1manbetxssSetNumInputPorts(年代,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(s,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 = ssgetoutportwidth(s,0);for(i = 0; i <宽度; i ++){* y ++ = 2.0 *(* UPTRS [i]);}}
静止空隙mdlTerminate(Simstruct * s){}
#ifdef matlab_mex_file / *这个文件被编译为mex文件吗?* / #include“万博1manbetxsimulink.c”/ * mex文件界面机制* / #else #include“cg_sfun.h”/ *代码生成注册函数* / #endif

此示例有三个部分:

  • 定义和包括

  • 回调方法的实现

  • 万博1manbetx仿真软件(或万博1manbetxSimulink编码器)产品的接口

定义和包括

该示例从以下开始定义陈述。

#define s_function_name timestwo #define s_function_level 2

首先定义语句指定S函数的名称(Timestwo.)。第二定义语句指定S函数在于2级格式(有关1级和级别2 S函数的更多信息,请参阅转换级-1 C MEX S函数)。

在定义这两个项目之后,该示例包括simstruc.h,这是一个标题文件,可以访问酝酿数据结构和MATLAB应用程序接口(API)函数。

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

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

回调方法的实现

下一部分Timestwo.S函数包含所需的回调方法的实现。

mdlInitializeSizes

Simu万博1manbetxlink引擎呼叫mdlInitializeSizes查询输入和输出端口的数量、端口的大小以及s函数所需的任何其他信息(如状态的数量)。

Timestwo.实施mdlInitializeSizes指定以下大小信息:

  • 零参数

    因此,这是S函数参数S函数块参数对话框的字段必须为空。如果它包含任何参数,引擎会报告参数不匹配。

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

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

  • 一个采样时间

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

  • 除了免费代码

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

mdlInitializeSampleTimes

Simu万博1manbetxlink引擎呼叫mdlInitializeSampleTimes设置S函数的采样时间。一种Timestwo.只要驱动块执行时,块就会执行。因此,它具有单个继承的采样时间,继承_sample_time.

mdloutputs.

发动机呼叫mdloutputs.在每次步骤中计算块输出。这Timestwo.实施mdloutputs.将输入信号乘以2,并将答案写入输出。

线:

InputRealPtrstype Uptrs = SSGetInputportRealsignalPtrs(S,0);

访问输入信号。这SSGETINPUTPORTREALSIGNALPTRS.宏返回指针的向量,您必须访问使用

* UPTRS [I]

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

线:

real_t * y = ssgetoutputportrealsignal(s,0);

访问输出信号。这ssgetoutputportrealsignal.宏返回指向包含块输出的数组的指针。

线:

int_t width = ssgetoutportwidth(s,0);

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

mdlTerminate

发动机呼叫mdlTerminate提供S-函数的机会在模拟结束时执行任务。这是一个强制性的S函数例程。这Timestwo.S-函数不执行任何终端操作,此例程为空。

万博1manbetx/万博1manbetx编码器接口

在S函数的末尾,包括以下代码以将您的S函数附加到Simulink或万博1manbetx万博1manbetxSimulink编码器s manbetx 845产品。

#ifdef matlab_mex_file #include“s万博1manbetximulink.c”#else #include“cg_sfun.h”#endif

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

构建timesttwo示例

要编译这个s函数,输入

mex timestwo.c.

在命令行。这墨西哥人命令编译并链接timestwo.c.使用默认编译器文件。这墨西哥人命令为使用的Simulink软件创建动态可加载的可执行文件。万博1manbetx如果您有多个MATLAB支持的编译器,则可以使用默认值使万博1manbetx用mex-setup.命令。看更改默认编译器和列表万博1manbetx支持的编译器

生成的可执行文件被称为MEX S函数,其中MEX代表“MATLAB可执行文件”。“MEX文件扩展范围从平台到平台。例如,在32位微软®窗户®system中,MEX文件扩展名为.mexw32