主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

编写 2 级 MATLAB S-Function

设置工作环境以编写 2 级 MATLAB S-Function

此示例打开一个目录,其中包含本主题所需的以下文件。

  1. msfuntmpl_basic.m

  2. msfuntmpl.m

  3. msfcn_unit_delay.m

  4. msfcndemo_sfundsc2.slx

关于 2 级 MATLAB S-Function

2 级 MATLAB® S-Function API 允许您使用 MATLAB 语言创建具有多个输入和输出端口的自定义模块,并且能够处理 Simulink® 模型产生的任何类型的信号,包括任何数据类型的矩阵和帧信号。2 级 MATLAB S-FunctionAPI 与用于创建 C MEX S 函数的 API 紧密对应。用于创建 C MEX S-Function 的大部分文档也适用于 2 级 MATLAB S-Function。为了避免重复,本节重点提供有关编写 2 级 MATLAB S-function 的特定信息。

2 级 MATLAB S-Function 是一个 MATLAB 函数,它定义引用 Simulink 模型中的 MATLAB 函数的 Level-2 MATLAB S-Function模块实例的属性和行为。MATLAB 函数本身包含一组回调方法(参阅 2 级 MATLAB S-Function 回调方法),Simulink 引擎在更新或仿真模型时会调用这些方法。回调方法执行初始化和计算 S-Function 定义的模块的输出的实际工作。

为了促进这些任务,引擎将运行时对象作为参量传递给回调方法。运行时对象有效地充当 S-Function 模块的 MATLAB 代理,允许回调方法在仿真或模型更新期间设置和访问模块属性。

关于运行时对象

当 Simulink 引擎调用 2 级 MATLAB S-Function 回调方法时,它会将 Simulink.MSFcnRunTimeBlock 类的实例作为参量传递给该方法。此实例称为 S-Function 模块的运行时对象,其对于 2 级 MATLAB S-Function 回调方法的作用与 SimStruct 结构对于 C MEX S-Function 回调方法的作用相同。该对象使该方法能够提供和获取有关模块端口、参数、状态和工作向量的各种元素的信息。该方法通过获取或设置属性或调用模块运行时对象的方法来实现此目的。有关获取和设置运行时对象属性以及调用运行时对象方法的信息,请参阅 Simulink.MSFcnRunTimeBlock 类的文档。

运行时对象不支持 MATLAB 稀疏矩阵。例如,如果变量 block 是运行时对象,则 2 级 MATLAB S-Function 中的以下行会产生错误:

block.Outport(1).Data = speye(10);

其中 speye 命令形成稀疏单位矩阵。

注意

除了 MATLAB S-Function 之外,其他 MATLAB 程序可以使用运行时对象来获取有关正在仿真的模型中的 MATLAB S-Function 的信息。请参阅使用 Simulink 中的 在仿真期间访问模块数据 以了解更多信息。

2 级 MATLAB S-Function 模板

使用基本的 2 级 MATLAB S-Function 模板 msfuntmpl_basic.m 来开始创建新的 2 级 MATLAB S-Function。该模板包含由 2 级 MATLAB S-Function API 定义的所需回调方法的骨架实现。要编写更复杂的 S-Function,请使用带注解的模板 msfuntmpl.m

要创建 MATLAB S-Function,请复制模板并根据需要编辑副本,以反映您正在创建的 S-Function 的所需行为。以下两节描述了 MATLAB 代码模板的内容。编写 2 级 MATLAB S-Function 的示例 部分描述了如何编写一个用于对单位延迟建模的 2 级 MATLAB S-Function。

2 级 MATLAB S-Function 回调方法

2 级 MATLAB S-Function API 定义了构成 2 级 MATLAB S-Function 的回调方法的签名和一般用途。S-Function 本身提供了这些回调方法的实现。实现反过来又确定了模块属性(例如,端口、参数和状态)和行为(例如,作为时间函数的模块输出以及模块输入、状态和参数)。通过创建具有一组适当的回调方法的 S-Function,您可以定义满足应用程序特定要求的模块类型。

2 级 MATLAB S-Function 必须包含以下回调方法:

  • setup 函数用于初始化基本 S-Function 特性

  • 用于计算 S-Function 输出的 Outputs 函数

您的 S-Function 可以包含其他方法,具体取决于 S-Function 定义的模块的要求。2 级 MATLAB S-Function API 定义的方法通常与 C MEX S-Function API 定义的类似命名的方法相对应。有关在仿真过程中何时调用这些方法的信息,请参阅Simulink Engine Interaction with C S-Functions中的Process View

下表列出了所有 2 级 MATLAB S-Function 回调方法及其 C MEX 对应方法。

使用 setup 方法

2 级 MATLAB S-Function 中的 setup 方法主体初始化相应的 2 级 MATLAB S-Function 模块的实例。从这一点上看,setup 方法类似于 C MEX S-Function 实现的 mdlInitializeSizesmdlInitializeSampleTimes 回调方法。setup 方法执行以下任务:

  • 初始化模块的输入和输出端口的数量。

  • 设置这些端口的属性,例如维度、数据类型、复杂性和采样时间。

  • 指定模块采样时间。有关如何指定有效采样时间的更多信息,请参阅使用 Simulink 中的 指定采样时间

  • 设置 S-Function 对话框参数的数量。

  • 通过将 MATLAB S-Function 中的本地函数句柄传递给 S-Function 块的运行时对象的 RegBlockMethod 方法来注册 S-Function 回调方法。有关使用 RegBlockMethod 方法的信息,请参阅 Simulink.MSFcnRunTimeBlock 的文档。

编写 2 级 MATLAB S-Function 的示例

以下步骤说明如何编写简单的 2 级 MATLAB S-Function。在适用的情况下,这些步骤包括模型 msfcndemo_sfundsc2 中使用的 S-Function 示例 msfcn_unit_delay.m 的示例。所有代码行都使用变量名 block 作为 S-Function 运行时对象。

  1. 从工作文件夹中打开 MATLAB S-Function 模板 msfuntmpl_basic.m。如果复制文件时更改了文件名,请将 function 行中的函数名称更改为相同的名称。

  2. 修改 setup 方法来初始化 S-Function的属性。对于此示例:

    • 将运行时对象的 NumInputPortsNumOutputPorts 属性设置为 1,以初始化一个输入端口和一个输出端口。

    • 调用运行时对象的 SetPreCompInpPortInfoToDynamicSetPreCompOutPortInfoToDynamic 方法来指示输入和输出端口从模型继承其编译属性(维度、数据类型、复杂性和采样模式)。

    • 将运行时对象的 InputPortDirectFeedthrough 属性设置为 false,以指示输入端口没有直接馈通。保留模板文件副本中设置的所有其他输入和输出端口属性的默认值。DimensionsDatatypeIDComplexity 属性设置的值将覆盖使用 SetPreCompInpPortInfoToDynamicSetPreCompOutPortInfoToDynamic 方法继承的值。

    • 将运行时对象的 NumDialogPrms 属性设置为 1 以初始化一个 S-Function 对话框参数。

    • 通过将运行时对象的 SampleTimes 属性值设置为 [-1 0],指定 S-Function 具有继承的采样时间。

    • 调用运行时对象的 RegBlockMethod 方法来注册此 S-Function 中使用的以下四种回调方法。

      • PostPropagationSetup

      • InitializeConditions

      • Outputs

      • Update

      从模板文件副本中删除任何其他已注册的回调方法。在对 RegBlockMethod 的调用中,第一个输入参量是 S-Function API 方法的名称,第二个输入参量是 MATLAB S-Function 中关联的本地函数的函数句柄。

    msfcn_unit_delay.m 中的以下 setup 方法执行前面列出的步骤:

    function setup(block)
    
    %% Register a single dialog parameter
    block.NumDialogPrms  = 1;
    
    %% Register number of input and output ports
    block.NumInputPorts  = 1;
    block.NumOutputPorts = 1;
    
    %% Setup functional port properties to dynamically
    %% inherited.
    block.SetPreCompInpPortInfoToDynamic;
    block.SetPreCompOutPortInfoToDynamic;
    
    %% Hard-code certain port properties
    block.InputPort(1).Dimensions        = 1;
    block.InputPort(1).DirectFeedthrough = false;
    
    block.OutputPort(1).Dimensions       = 1;
    
    %% Set block sample time to [0.1 0]
    block.SampleTimes = [0.1 0];
    
    %% Register methods
    block.RegBlockMethod('PostPropagationSetup',@DoPostPropSetup);
    block.RegBlockMethod('InitializeConditions',@InitConditions);
    block.RegBlockMethod('Outputs',             @Output);  
    block.RegBlockMethod('Update',              @Update);  

    如果您的 S-Function 需要连续状态,请使用运行时对象的 NumContStates 属性在 setup 方法中初始化连续状态的数量。不要在 setup 方法中初始化离散状态。

  3. PostPropagationSetup 方法中初始化离散状态。2 级 MATLAB S-Function 将离散状态信息存储在 DWork 向量中。模板文件中默认的 PostPropagationSetup 方法足以满足本示例的要求。

    以下来自 msfcn_unit_delay.mPostPropagationSetup 方法(名为 DoPostPropSetup)初始化一个名为 x0 的 DWork 向量。

    function DoPostPropSetup(block)
    
      %% Setup Dwork
      block.NumDworks = 1;
      block.Dwork(1).Name = 'x0'; 
      block.Dwork(1).Dimensions      = 1;
      block.Dwork(1).DatatypeID      = 0;
      block.Dwork(1).Complexity      = 'Real';
      block.Dwork(1).UsedAsDiscState = true;

    如果您的 S-Function 使用额外的 DWork 向量,也请在 PostPropagationSetup 方法中初始化它们(参阅 Using DWork Vectors in Level-2 MATLAB S-Functions)。

  4. InitializeConditionsStart 回调方法中初始化离散和连续状态或其他 DWork 向量的值。使用 Start 回调方法获取在仿真开始时初始化一次的值。每当重新启用包含 S-Function 的启用子系统时,请使用 InitializeConditions 方法重新初始化需要的值。

    对于此示例,使用 InitializeConditions 方法将离散状态的初始条件设置为 S-Function 的对话框参数的值。例如 msfcn_unit_delay.m 中的 InitializeConditions 方法是:

    function InitConditions(block)
    
      %% Initialize Dwork
      block.Dwork(1).Data = block.DialogPrm(1).Data;

    对于具有连续状态的 S-Function,使用 ContStates 运行时对象方法初始化连续状态数据。例如:

     block.ContStates.Data(1) = 1.0;
  5. Outputs 回调方法中计算 S-Function 的输出。对于此示例,将输出设置为 DWork 向量中存储的离散状态的当前值。

    msfcn_unit_delay.m 中的 Outputs 方法是:

    function Output(block)
    
      block.OutputPort(1).Data = block.Dwork(1).Data;
    
  6. 对于具有连续状态的 S-Function,在 Derivatives 回调方法中计算状态导数。运行时对象将衍生数据存储在其 Derivatives 属性中。例如,下一行将第一个状态导数设置为等于第一个输入信号的值。

    block.Derivatives.Data(1) = block.InputPort(1).Data;

    此示例不使用连续状态,因此没有实现 Derivatives 回调方法。

  7. 更新 Update 回调方法中的任何离散状态。对于此示例,将离散状态的值设置为第一个输入信号的当前值。

    msfcn_unit_delay.m 中的 Update 方法是:

    function Update(block)
    
      block.Dwork(1).Data = block.InputPort(1).Data;
    
  8. Terminate 方法中执行任何清理,例如清除变量或内存。与 C MEX S-Function 不同,2 级 MATLAB S-Function 不需要具有 Terminate 方法。

有关其他回调方法的信息,请参阅2 级 MATLAB S-Function 回调方法。有关运行时对象属性的列表,请参阅 Simulink.MSFcnRunTimeBlock 和父类 Simulink.RunTimeBlock 的参考页。

实例化 2 级 MATLAB S-Function

要在模型中使用 2 级 MATLAB S-Function,请将 Level-2 MATLAB S-Function模块的实例复制到模型中。打开该模块的“模块参数”对话框,然后在 S-Function name 字段中输入实现 S-Function 的 MATLAB 文件的名称。如果您的 S-Function 使用任何附加参数,请在“模块参数”对话框的参数字段中以逗号分隔的列表形式输入参数值。

可变大小信号的操作

以下是对 2 级 MATLAB S-Function 模板(msfuntmpl_basic.m)的修改以及允许您使用可变大小信号的附加操作。

function setup(block)
% Register the properties of the output port
block.OutputPort(1).DimensionsMode = 'Variable';
block.RegBlockMethod('SetInputPortDimensionsMode',  @SetInputDimsMode);

function DoPostPropSetup(block)
%Register dependency rules to update current output size of output port a depending on
%input ports b and c
block.AddOutputDimsDependencyRules(a, [b c], @setOutputVarDims);

%Configure output port b to have the same dimensions as input port a
block.InputPortSameDimsAsOutputPort(a,b);

%Configure DWork a to have its size reset when input size changes.
block.DWorkRequireResetForSignalSize(a,true);

function SetInputDimsMode(block, port, dm)
% Set dimension mode
block.InputPort(port).DimensionsMode = dm;
block.OutputPort(port).DimensionsMode = dm;

function setOutputVarDims(block, opIdx, inputIdx)
% Set current (run-time) dimensions of the output
outDimsAfterReset = block.InputPort(inputIdx(1)).CurrentDimensions;
block.OutputPort(opIdx).CurrentDimensions = outDimsAfterReset;

从 2 级 MATLAB S-Function 生成代码

为包含 2 级 MATLAB S-Function 的模型生成代码需要您提供相应的目标语言编译器 (TLC) 文件。您不需要 TLC 文件来加速包含 2 级 MATLAB S-Function 的模型。加速器模式软件以解释模式运行 2 级 MATLAB S-Function。但是,如果 M-file S-function 位于模型引用中,则 M-file S-Function 不适用于加速模式。有关为 MATLAB S-Function 编写 TLC 文件的更多信息,请参阅 内联 S-Function (Simulink Coder)Inline MATLAB File S-Functions (Simulink Coder)

MATLAB S-Function 示例

2 级 MATLAB S-Function 示例提供了一组自文档模型,说明了 2 级 MATLAB S-Function 的用法。在 MATLAB 命令提示符下输入 sfundemos 来查看示例。

MATLAB S-Function 限制

  • 2 级 MATLAB S-Function 不支持过零检测。

  • 您无法从 2 级 MATLAB S-Function 触发函数调用子系统。

另请参阅

| | |

主题