主要内容

金宝app发动机与C - s功能的相互作用

您可以检查Simulink如何金宝app®引擎与两个视角的S函数交互:

  • 过程的角度,也就是说,在模拟的某个点上,引擎调用s函数。

  • 数据透视,即发动机和s功能在模拟过程中如何交换信息。

流程视图

下面的图显示了Simulink引擎在s函数中调用回调方法的顺序。金宝app实矩形表示总是在模型初始化期间或在每个时间步骤中发生的回调。虚线矩形表示可能在初始化和/或在模拟循环期间的某些或所有时间步骤中发生的回调。请参阅每个回调方法的文档,以确定引擎调用回调的确切环境。

请注意

流程视图图表示包含连续和离散状态、支持过零检测并驻留在使用可变步长求解器的模型中的s函数的执行。不同的求解器会在图中省略某些步骤。为了更好地理解Simulink引擎如何执行特定的s函数,请使用Simulin金宝appk调试器运行包含s函数的模型。有关更多信息,请参见调试器简介

在下面的模型初始化循环中,Simulink引擎为即将进行的仿真配置s函数。金宝app引擎总是对mdlinitializatizemdlInitializeSampleTime建立s函数的基本属性,包括输入输出端口、s函数对话参数、工作向量、采样次数等。

引擎根据需要调用其他方法来完成S-function初始化。例如,如果s函数使用功向量,引擎调用mdlSetWorkWidths.同样,如果mdlinitializatize方法延迟设置输入和输出端口属性时,引擎调用完成端口初始化所需的任何方法,例如mdlSetInputPortWidth,在信号传播期间。的mdlStart方法调用的mdlCheckParametersmdlProcessParameters方法如果S函数使用对话框参数。

请注意

mdlinitializatize当您在“s -函数块参数”对话框中输入已编译s -函数的名称时,回调方法也会运行。

初始化之后,Simulink引擎执行以下仿真循环。金宝app如果模拟循环被中断,无论是手动或错误发生时,引擎直接跳转到mdlterminate.方法。如果模拟是手动停止的,那么引擎在调用之前首先完成当前时间步骤mdlterminate.

如果您的模型在给定的模型层次结构级别上包含多个S-Function块,那么引擎将在继续执行下一个方法之前为每个S-Function调用特定的方法。例如,引擎调用所有的mdlinitializatize在调用之前的方法mdlinitializateMpletimes方法。该引擎使用块排序顺序来确定执行S函数的顺序。要了解有关引擎如何确定块执行顺序的更多信息,请参阅控制和显示执行顺序

代码生成的调用结构

如果你使用金宝appSimulink Coder™产品为包含S-functions的模型生成代码时,Simulink引擎不会执行上面列出的整个调用序列。金宝app初始化继续进行,直到引擎到达mdlStart方法。引擎然后调用如下图所示的S-function方法mdlRTW方法是独一无二的金宝app仿真软件编码器产品。

如果S函数驻留在有条件执行的子系统中,则可以生成的代码交错呼叫mdlInitializeConditionsmdlStart.考虑以下Simulink模型。金宝app

模型包含两个部分nonvirtual子系统,有条件执行的启用子系统名为Reset,原子子系统名为atomic。每个子系统都包含一个调用S-Function的S-Function块dsfunc.c,它模拟了一个具有两种状态的离散状态空间系统。enabled子系统Reset复位子系统启用时的状态值和子系统禁用时的输出值。

使用通用实时(GRT)目标,生成的代码适用于模型范围开始函数调用这件事开始两个子系统的函数,然后调用模型范围MdlInitialize函数,如下代码所示:

void MdlStart(void){/*剪接*/ /*启动启用的子系统:'/Reset' */ sfcndemo_enablesub_Reset_Start();/* end of Start for子系统:'/Reset' */ /* Start for原子子系统:'/ atomic ' */ sfcndemo_enablesub_Atomic_Start();/* end of Start for子系统:'/Atomic' */ MdlInitialize();

开始函数调用子系统的InitializeConditions功能:

void sfcndemo_enablesub_Reset_Start(void) {sfcndemo_enablesub_Reset_Init();/*剪切*/}

MdlInitialize函数,在MdlStart,包含对此的呼叫InitializeConditions原子子系统的函数:

void MdlInitialize(void){/*原子子系统的初始化条件:'<根>/原子' */ sfcndemo_enablesub_Atomic_Init();}

因此,model-wide开始功能交织呼叫到开始InitializeConditions两个子系统的函数和它们所包含的s函数。

有关的更多信息金宝app仿真软件编码器产品以及它是如何与s功能相互作用的,看s -函数和代码生成(金宝app仿真软件编码器)

外部模式的替代调用结构

在外部模式下运行Simulink模型时,S函数金宝app例程的调用序列如下图所示更改。

引擎调用mdlRTW一次,当它进入外部模式时,以及每次参数更改或单击时再次更新模型建模选项卡。

请注意

在外部模式下运行Si金宝appmulink模型需要金宝app仿真软件编码器产品。

数据视图

s功能块具有输入和输出信号、参数和内部状态,以及其他通用工作区。通常,块输入和输出被写入和从块I/O向量中读取。输入也可以来自

  • 通过root Inport块外部输入

  • 接地(输入信号未接或接地)

块输出也可以通过根Outport块转到外部输出。除了输入和输出信号外,s函数还可以有

  • 持续的状态

  • 离散状态

  • 其他工作区域,如真实,整数或指针工作向量

您可以使用“s -功能块参数”对话框将参数传递给s -功能块。

下图显示了这些不同类型数据之间的一般映射。

一个函数的mdlinitializatize例程设置各种信号和向量的大小。在仿真环路期间调用的S函数方法可以确定信号的大小和值。

s函数法可以通过两种方式访问输入信号:

  • 通过指针

  • 使用连续的输入

使用指针访问信号

在仿真循环中,使用

InputRealPtrstype Uptrs = SSGetInputPortRealSignalPtrs(S,portindex.

这将返回带有索引的输入端口的指针数组portindex.,在那里portindex.从0开始。每个输入端口都有一个指针数组。要访问该数组的元素,必须使用

* uPtrs(元素)

下图描述了如何访问具有两个输入的s函数的输入信号。

如上图所示,输入数组指针可以指向内存中不相邻的位置。

您可以使用此代码检索输出信号。

real_T *y = ssGetOutputPortSignal(S,outputPortIndex);

访问连续输入信号

一个函数的mdlinitializatize方法可以指定其输入信号的元素必须占用连续的内存区域,使用sssetInputPortRequiredContiful..如果输入是连续的,则可以使用其他方法ssgetInputportSignal.来访问输入。

接入各端口输入信号

介绍如何访问特定端口的所有输入信号,并将其写入输出端口。上图显示了指针的输入数组可以指向块I/O向量中的不连续项。特定端口的输出信号形成一个连续的向量。因此,访问输入元素并将它们写入输出元素(假设输入端口和输出端口宽度相等)的正确方法是使用此代码。

int_T元素;int_T porttwidth = ssgetinputporttwidth (S,inputPortIndex); / /输入端口索引InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,inputPortIndex);real_T *y = ssGetOutputPortSignal(S,outputPortIdx);(元素= 0;元素< portWidth;元素++){y[element] = *uPtrs[element];}

一个常见的错误是试图通过指针运算来访问输入信号。例如,如果你要放置

real_T *u = *uPtrs;/ * * /不正确

的初始化下方Uptrs.并更换上述环的内部

* y ++ = * u ++;/ * * /不正确

代码被编译,但是MEX文件可能会使Simulink软件崩溃。金宝app这是因为有可能访问无效内存(这取决于您如何构建模型)。当不正确地访问输入信号时,当进入S-function块的信号不是连续的时,就会发生崩溃。当信号通过虚拟连接块(如Mux或Selector块)时,就会发生不连续的信号数据。

要验证您的S功能是否正确访问了宽输入信号,请将复制信号传递给S函数的每个输入端口。为此,创建一个Mux块,其中输入端口数等于进入S函数的所需信号的宽度。然后,将驱动源连接到每个S函数输入端口,如下图所示。最后,使用此输入信号运行S-函数以验证它不会崩溃并产生预期的结果。

另请参阅

|||

相关主题