Main Content

导出函数模型概述

导出函数模型是 Simulink® 模型,它们可以生成可与外部环境和调度器集成的独立函数的代码。函数是使用 Function-Call Subsystem、函数调用 ModelSimulink FunctionMessage Triggered SubsystemS-Function 模块定义的。

以下导出函数模型包含使用 Function-Call Subsystem 模块定义的两个函数。有关创建此模型的分步过程,请参阅Create Export-Function Model

从此模型生成的代码具有两个独立函数:一个时滞函数,一个平方函数。

      /*
       * File: export_function_model.c    
       * Code generated for Simulink model 'export_function_model'.
       */
		
	void function_call_100ms(void)         /* Sample time: [0.1s, 0.0s] */
	{
	  export_function_model_Y.output_100ms =
	    export_function_model_DW.UnitDelay_DSTATE;
	
	  export_function_model_DW.UnitDelay_DSTATE =
	    export_function_model_Y.output_100ms + 1.0;	
	}

      void function_call_10ms(void)          /* Sample time: [0.01s, 0.0s] */
	{
	    export_function_model_Y.output_10ms = export_function_model_U.input_10ms *
	    export_function_model_U.input_10ms;
	}

导出函数模型的工作流

用于创建导出函数模型的四种常见流程在生成函数代码之前进行模型仿真和测试的方式有所不同。

当函数调用顺序足够简单而可指定为模型输入时,使用输入矩阵的仿真是测试导出函数模型的首选方法。有关详细信息,请参阅Test Export-Function Model Simulation Using Input Matrix

当函数调用顺序过于复杂而无法使用输入矩阵指定时,请创建测试模型(框架)以模拟目标环境行为。使用此测试模型为导出函数模型提供函数调用输入。有关详细信息,请参阅Test Export-Function Model Simulation Using Function-Call GeneratorsTest Export-Function Model Simulation Using Schedule EditorTest Export-Function Model Simulation Using Stateflow Chart

导出函数模型顶层允许的模块

在顶层,导出函数模型仅允许使用虚拟模块、具有常量 (inf) 采样时间的模块以及以下模块:

  • Inport

  • Outport

  • Bus Creator

  • Bus Selector

  • In Bus Element

  • Out Bus Element

  • Function-Call Subsystem

  • 带函数调用输入端口的 Model

  • Simulink Function

  • Function Element

  • Function Element Call

  • Message Triggered Subsystem

  • Initialize Function

  • Reinitialize Function

  • Reset Function

  • Terminate Function

  • Data Store Memory

  • Merge

  • 带函数调用输入端口的 S-Function

  • Function-Call Split

  • Display

  • Scope

有关详细信息,请参阅非虚拟和虚拟模块采样时间的类型

导出函数模型的要求

要使导出函数模型成功生成函数代码,必须满足以下要求。

模型配置参数:

  • 求解器类型设置为定步长

  • 求解器设置为自动离散

  • 将“代码生成”部分的系统目标文件设置为 ert.tlc。选择 ert.tlc 需要 Embedded Coder® 许可证。

  • 对于函数调用 Model 模块,引用模型的周期性采样时间约束设置为确保采样时间独立

根级函数调用模块 Inport

  • 选中输出函数调用复选框。

  • 不能从 Asynchronous Task Specification 模块接收信号。

根级 Outport 模块必须连接到以下模块之一,或保持不连接或接地:

  • 由根级函数调用 Inport 模块驱动的函数调用模块。此模块可以是 Function-Call Subsystem 模块、函数调用 Model 模块或具有函数调用输入的 S-Function 模块。

  • Simulink Function 模块。

  • Initialize FunctionReinitialize FunctionReset FunctionTerminate Function 模块。

  • 由上述模块驱动的 MergeMux 模块。

根级数据 InportOutport 模块不能连接到虚拟总线数据信号。

根级 Function-Call Subsystem 模块和函数调用 Model 模块:

  • 模块内的所有内部模块都必须支持代码生成。

  • 如果 Trigger 模块的采样时间类型设置为:

    • 已触发,则内部模块必须将采样时间设置为 -1

    • 周期性,则根级函数调用 Inport 模块必须将其采样时间设置为指定的离散时间,并且所有内部模块必须将采样时间设置为 -1 或指定的离散时间。

指定导出函数模型

创建导出函数模型时,通过将您的模型指定为导出函数模型,让 Simulink 将其视为导出函数模型。

要将模型指定为导出函数模型,请打开属性检查器。在显示模型的根级且没有突出显示任何模块的情况下,转至执行选项卡并选中设置执行域复选框。然后,从列表中,选择导出函数

Property Inspector dialog, with "Set execution domain" check box selected and drop-down menu for "Domain" with "Export function" selected

还可以通过设置模型的 IsExportFunctionModel 参数将模型指定为导出函数模型。

set_param(ModelName,'IsExportFunctionModel','on')

Simulink 在画布的左下角显示 Badge showing "f()" 标记,表示模型指定为导出函数模型。

将模型指定为导出函数模型后,Simulink 会执行编译时检查,以便在模型不满足导出函数模型要求时发出警告。

如果加载在 R2022a 之前的版本中创建并保存的模型,Simulink 会将该模型指定为导出函数模型,前提是该模型满足导出函数模型的要求。在某些情况下,您可能需要手动将这样的模型指定为导出函数模型。

函数调用子系统的采样时间

在导出函数模型中,您可以为根级函数调用 Inport 模块以及根级 Function-Call Subsystem 模块或函数调用 Model 模块内的 Trigger 模块指定采样时间。下表显示了如何指定这些采样时间。

Trigger 模块的采样时间类型Trigger 模块采样时间Inport 模块采样时间仿真期间的函数调用速率

已触发

未指定,参数处于非活动状态。

-1(继承)

在仿真时,由连接到 Inport 模块的函数调用发起方设置仿真速率。

指定的离散时间

在测试模型中连接到 Inport 模块的函数调用发起方的采样时间必须等于 Inport 模块的指定离散时间。

在仿真时,组件以指定的离散速率执行。如果函数调用源使用不同的采样时间,Simulink 将显示错误消息。

周期性

如果从 Model 模块引用导出函数模型,则应用周期函数调用运行时检查。

-1(继承)或 Inport 模块的指定离散时间。

-1(继承)

不允许此配置。Simulink 显示错误消息。

指定的离散时间。

在仿真时,组件按指定的离散采样时间执行。如果函数调用源使用不同的采样时间,Simulink 将显示错误消息。

根级函数调用 Inport 模块的执行顺序

通过为函数调用 Inport 模块指定采样时间和优先级,您可以在仿真期间控制函数调用子系统和函数调用模型的执行顺序。您也可以使用调度编辑器或 Stateflow® 图来测试调度。有关详细信息,请参阅Test Export-Function Model Simulation Using Schedule EditorTest Export-Function Model Simulation Using Stateflow Chart

  1. 指定仿真执行的采样时间。右键点击函数调用 Inport 模块,然后选择模块参数

  2. 选择“信号属性”选项卡。在采样时间框中,输入离散时间。

  3. 指定仿真的模块优先级。右键点击函数调用 Inport 模块,然后选择属性

  4. 优先级框中,输入优先级值。

  5. 显示仿真的模块执行顺序。在调试选项卡上,选择叠加信息 ,然后从下拉对话框中选择执行顺序。这一显示内容对生成的代码没有任何影响。

在以下导出函数模型中,先运行 Function-Call Subsystem 2Inport采样时间设置为 0.01 (10 ms)),然后运行 Function-Call Subsystem 1Inport 模块的采样时间设置为 0.1 (100 ms))。

确定相对执行顺序

Simulink 使用以下规则比较函数调用 Inport 模块属性以确定其相对执行顺序:

  1. 优先级 - 优先级较高(数字较小)的先执行

  2. 采样时间(采样时间较小的先执行)

  3. 端口号(端口号较小的先执行)

  4. 如果模型的 OrderFunctionsByDependency 参数设置为 'on',则具有相同采样时间的模块将根据模块所连接到的函数的相对数据依存关系进一步排序。

要查看 OrderFunctionsByDependency 参数的效果,请考虑以下模型。

Three function-call subsystems, numbered 1, 2, and 3. Number 1 has sample time of 100 ms. Number 2 and Number 3 have sample time of 10 ms. The output of Number 3 is connnected to the input of Number 2. The Inport blocks driving Number 1, Number 2, and Number 3 are annotated with F2, F0 and F1, respectively.

Inport 模块 1 最后执行,因为它比采样时间相同的 Inport 模块 2 和 3 具有更长的采样时间。如果 OrderFunctionsByDependency 设置为 'off',则 Inport 模块 2 根据其端口号在 Inport 模块 3 之前执行。执行顺序是 2、3、1。

OrderFunctionsByDependency 参数默认设置为 'off'。要打开它,请使用以下命令。

set_param(ModelName,'OrderFunctionsByDependency','on')
如果 OrderFunctionsByDependency 设置为 'on',则 Inport 模块 3 在 Inport 模块 2 之前执行,因为函数调用子系统 2 和 3 之间存在数据依存关系。执行顺序是 3、2、1。

Three function-call subsystems, numbered 1, 2, and 3. Number 1 has sample time of 100 ms. Number 2 and Number 3 have sample time of 10 ms. The output of Number 3 is connnected to the input of Number 2. The Inport blocks driving Number 1, Number 2, and Number 3 are annotated with F2, F1 and F0, respectively.

请注意,OrderFunctionsByDependency 参数仅影响设置了该参数的模型。该参数不会传播到引用模型中。

如果两个模块的优先级参数具有不同的值,具有较高优先级的模块将先执行。如果优先级参数相等,则速率更快(采样时间较小)的模块将先执行。如果两个模块的优先级和采样时间都相同,则具有较小端口号的模块将先执行。例外情况是,当模块之间存在数据依存关系并且 OrderFunctionsByDependency 设置为 'on' 时,依赖模块在其依赖的模块后执行。

注意

如果顶层模型的仿真模式是加速或快速加速,Simulink 不会对引用的导出函数模型内根级函数调用 Inport 模块的执行顺序进行运行时仿真检查。

假设一个导出函数模型有五个根级函数调用 Inport 模块,分别是模块 A 到 E,模块属性如下表所示。这些模块没有数据依存关系,或 OrderFunctionsByDependency 设置为 'off'。为了确定它们的相对执行顺序,Simulink 会比较它们的优先级参数、采样时间(如果采样时间不同并且不是继承的)和端口号。

根级函数调用模块 InportABCDE
优先级1030404030
采样时间-10.20.10.1-1
端口号54321
  • 在五个模块中,模块 A 的优先级最高。A 先执行。

  • B 和 E 在 A 之后但在 C 和 D 之前执行。由于 B 和 E 有相同的优先级,Simulink 将比较其采样时间,以确定执行顺序。E 的采样时间为 -1(继承),该值小于 B 的采样时间 0.2,因此 E 在 B 之前执行。

  • C 和 D 具有相同的优先级和同样的非继承唯一采样时间。D 的端口号 (2) 小于 C (3),因此 D 在 C 之前执行。

这些函数调用 Inport 模块的相对执行顺序是 A、E、B、D、C。

嵌套的导出函数模型

嵌套的导出函数模型提供了额外的组织层。以下模型包含两个通过 Model 模块引用的导出函数模型。

注意

导出函数模型不能包含使用异步函数调用输入的引用模型,但可以包含函数调用子系统和函数调用模型。使用异步函数调用输入的模型可以包含导出函数模型、函数调用子系统或函数调用模型。

包含多实例函数调用模型的导出函数模型

您可以在导出函数模型中使用 Function-Call Subsystem 模块或函数调用 Model 模块。如果使用函数调用 Model 模块,则还可以创建模型的多个实例。

  1. 使用包含 Trigger 模块的模型定义您的算法。将触发器类型设置为函数调用

  2. Model 模块引用模型。结果是一个函数调用模型。

  3. 连接一个函数调用 Inport 模块并选中输出函数调用复选框。添加信号 InportOutport 模块。更新模型 (Ctrl+D)。结果是一个包含函数调用模型的导出函数模型。

  4. 复制引用模型和端口模块以创建模型的第二个实例。这两个实例由不同任务中的不同根级函数调用 Inport 模块调用。

注意

包含设置为多实例导出函数的引用模型的顶层非导出函数模型不支持代码生成。有关详细信息,请参阅Total number of instances allowed per top model

导出函数模型和使用异步函数调用输入的模型

导出函数模型功能可用于具有异步函数调用输入端口的模型,也称为 JMAAB-B 模型。这些模型主要用在通过 Simulink 调度器调用函数的 Simulink 环境中。

比较特性导出函数模型使用异步函数调用输入的模型
定义这些模型具有未连接到 Asynchronous Task Specification 模块的根级函数调用 Inport 模块。这些 Inport 模块触发函数调用子系统或函数调用模型(包含 Trigger 模块的 Model 模块)。这些模型包含连接到 Asynchronous Task Specification 模块的根级函数调用 Inport 模块。这些 Inport 模块会触发函数调用子系统或函数调用模型。
根级模块只有在函数调用上下文中执行的模块才允许位于根级。在非函数调用上下文中执行的模块也允许位于根级。
数据传输使用数据传输指示符解释仿真结果。默认情况下,导出函数模型中的数据传输在生成的代码中不受保护。有关详细信息,请参阅函数调用子系统的锁存输入数据可使用 Rate Transition 模块保护以不同速率运行的函数调用子系统之间的数据传输。有关详细信息,请参阅 Rate Transition
仿真支持这些模型支持所有仿真模式下的独立仿真和测试模型仿真。这些模型支持所有仿真模式下的测试模型仿真,以及普通、加速和快速加速模式下的独立仿真。
代码生成支持支持顶层模型和独立代码生成。支持顶层模型和独立代码生成。

另请参阅

| | | | |

相关主题