主要内容

为模型入口函数配置生成的 C 函数接口

什么是入口函数?

入口是代码中发生程序控制权(执行)转移的位置。主函数 (main()) 是进入 C/C++ 程序的入口,在应用程序开始执行时调用。对其他函数的调用(例如从 main 函数调用)是进入函数代码的入口。程序控制权会转移到被调函数。函数代码随后执行,在完成后将控制权交还给 main 或其他主调函数。

为模型生成代码时,代码生成器会定义一组入口函数,您可以调用这些函数来执行生成的代码。您可以从外部代码或生成的主函数的修改版调用生成的函数。

代码生成报告的“代码接口报告”部分会列出代码生成器为模型生成的入口函数。有关详细信息,请参阅 Analyze Generated Data Code Interface Report

生成的入口函数的类型

代码生成器为下列类型的模型函数生成入口函数。

模型函数的类型模型源函数名称默认的生成函数名称描述
导出函数(需要 Embedded Coder®ExportedFunction:slIdentifier,其中 slIdentifier 是模型中函数调用 Inport 模块的名称function-call-inport-block-namesignal-label(如果指定)对于导出函数模型,即为子系统的导出函数。
初始化函数Initializemodel_initialize

模型的初始化代码。在应用程序代码的开始,调用函数一次。请不要使用此函数重置实时模型数据结构体 (rtM)。

分区函数Partition:slIdentifier,其中 slIdentifier 是从模型中的模块显式创建的一个分区并显示在 Simulink® 调度编辑器中(例如 P1),或是“并行执行”对话框中的一个任务名称model_stepn,其中 n 基于模型采样周期唯一标识生成的函数对于模型分区,输出并更新代码。模型配置参数单一输出/更新函数处于选中状态(默认值)。
分区更新函数PartitionUpdate:slIdentifier,其中 slIdentifier 是从模型中的模块显式创建的一个分区并显示在 Simulink® 调度编辑器中(例如 P1),或是“并行执行”对话框中的一个任务名称model_outputnmodel_updaten,其中 n 基于模型采样周期唯一标识生成的函数对于模型分区,使用分别的函数输出和更新代码。模型配置参数单一输出/更新函数处于未选中状态。
周期性多任务函数Periodic:slIdentifier,其中 slIdentifier 是一个注解,对应于多任务模型的一个周期性或连续速率的采样时间周期(例如,D1)model_stepn,其中 n 基于模型采样周期唯一标识生成的函数对于为多任务配置的一个基于速率的模型中的模块,输出和更新代码。代码生成器为每个采样周期生成一个函数。模型配置参数单一输出/更新函数处于选中状态(默认值)。要了解有关采样时间信息的更多内容,请参阅指定采样时间
周期性多任务更新函数PeriodicUpdate:slIdentifier,其中 slIdentifier 是一个注解,对应于多任务模型的一个周期性或连续速率的采样时间周期(例如,D1)model_outputnmodel_updaten,其中 n 基于模型采样周期唯一标识生成的函数对于为多任务配置的一个基于速率的模型中的模块,分别在单独的函数中输出和更新代码。代码生成器为每个采样周期生成输出和更新函数。模型配置参数单一输出/更新函数处于未选中状态。要了解有关采样时间信息的更多内容,请参阅指定采样时间
周期性单任务函数Periodicmodel_step对于为单任务配置的基于速率的模型中的模块,输出和更新代码。模型配置参数单一输出/更新函数处于选中状态(默认值)。
周期性单任务更新函数PeriodicUpdatemodel_outputmodel_update对于为单任务配置的基于速率的模型中的模块,分别在单独的函数中输出和更新代码。模型配置参数单一输出/更新函数处于未选中状态。
重置函数Reset:slIdentifier,其中 slIdentifier 是模型中重置函数的名称model_reset-function-name

如果模型包含 Reset Function 模块,则重置生成的代码。要重置条件或状态,请从应用程序代码中调用函数。

Simulink FunctionSimulink Function:slIdentifier,其中 slIdentifier 是模型中 Simulink Function 模块的名称对于全局 Simulink Function 模块,为 function-name;对于限定作用域的 Simulink Function 模块,为 model_function-name对于导出函数模型,是 Simulink Function 模块的导出函数。
终止函数Terminatemodel_terminate

用于关闭系统的代码。对于基于 ERT 的模型,您可以通过清除模型配置参数需要终止函数(默认设置)来隐藏此函数的生成。

如果您有 Embedded Coder 软件,为了便于集成外部代码和生成的代码并符合代码标准和规范,您可以配置代码生成器如何从模型或子系统生成函数接口。

配置入口函数的可重用性

默认情况下,顶层模型生成不可重用或不可重入的代码。入口函数有一个 void-void 接口。代码通过直接访问驻留在共享内存中的全局数据结构体来与其他代码通信。

如果您的应用程序需要可重用的多实例入口函数代码,您可以配置代码生成器使用唯一数据来调用每个函数(实例)。在这种情况下,代码是可重入的。

您可以使用模型配置参数代码接口打包(组件) 和相关参数来配置入口函数是否可重用。您选择的参数设置取决于系统目标文件的配置选择、编程语言和参量接口等因素。

单实例 C 入口函数的默认配置

默认情况下,对于基于 GRT 和基于 ERT 的系统目标文件,代码生成器生成单实例 C 入口函数。生成的代码:

  • 创建不带参量的执行函数 (void-void)。

  • 为模型数据结构体静态分配内存(在编译时)。

配置单实例入口函数代码的默认模型配置参数设置为:

生成可重用的多实例 C 入口函数

您可以配置代码生成器,为基于 GRT 或基于 ERT 的系统目标文件生成可重用的 C 入口函数。但是,代码生成器默认生成的各函数接口有所不同。假设模型配置参数语言设置为 C代码接口打包(组件) 设置为可重用函数,代码生成器为每个系统目标文件场景生成以下入口函数代码。

系统目标文件接口
基于 GRT
  • 可重用、可重入的多实例 C 入口函数。

  • 将模型根级 Inport 模块和 Outport 模块的值打包到实时模型数据结构体中。按引用将该结构体作为参量传递给执行函数。

  • 在运行时为模型实例的数据动态分配内存。通过调用函数(如 malloc)来分配内存。

基于 ERT
  • 可重用、可重入的多实例 C 入口函数。

  • 将每个模型根级 Inport 模块和 Outport 模块的值作为单独的参量传递给执行函数。

  • 为模型数据结构体静态分配内存。

如果您使用的是基于 ERT 的系统目标文件,并希望生成可重用、可重入的多实例 C 入口函数,请考虑:

  • 使用动态内存分配来初始化模型数据结构体。选择使用动态内存分配进行模型初始化

    注意

    如果您对可重用的 C 函数接口使用动态内存分配,则对 rt_VALIDATE_MEMORY 宏的调用会出现在生成的代码中。默认情况下,此函数定义为空宏,不执行任何操作。要添加分配失败的处理,请为 rt_VALIDATE_MEMORY 定义一个自定义宏。

  • 将模型根级 Inport 模块的值打包到一个结构体中,将根级 Outport 模块的值打包到另一个结构体中,并按引用将这些结构体作为参量传递给执行函数。将根级 I/O 传递方式设置为结构体引用

  • 将模型根级 Inport 模块和 Outport 模块的值打包到实时模型数据结构体中,并按引用将该结构体作为参量传递给执行函数。将根级 I/O 传递方式设置为模型数据结构体的一部分

配置模型引用入口函数的可重用性

默认情况下,模型引用生成可重用且可重入的代码。代码生成器使用唯一数据调用每个引用模型函数。

您可以使用模型配置参数 代码接口打包(子组件) 配置引用模型入口函数是否可重用。

默认情况下,不可重用的模型引用生成的代码将根级 I/O 数据作为函数参量传递给入口函数。如果您使用的是基于 ERT 的系统目标文件,请考虑通过将根级 I/O 数据作为全局变量传递来消除函数参量。将模型配置参数将根级 I/O 实现为设置为全局变量

选择配置生成的 C 函数接口的方法

为了便于集成外部代码和生成的代码并符合代码标准和规范,您可以使用代码映射编辑器或代码映射 API 来配置代码生成器如何从模型或子系统生成函数接口。

对于配置了服务接口的模型,您可以配置:

  • 函数名称

  • 表示为 Simulink Function 模块的子组件中的函数和组件模型中的函数的函数参量

  • 内存段

配置更多信息
模型中函数类别(初始化/终止、执行和共享实用工具)的默认命名规则Configure Default Code Generation for Functions
单个入口函数的名称(覆盖默认命名规则)为单个 C 入口函数配置名称
基本速率单步入口函数的单步函数接口(函数名称、返回值和参量 C 类型限定符、名称和顺序),以交互方式配置为单个单步函数配置名称和参量
Simulink Function 和 Function Caller 模块的函数接口(函数名称、返回值和参量 C 类型限定符、名称和顺序),以交互方式配置Configure C Entry-Point Function Interfaces for Simulink Function and Function Caller Blocks

您可以使用软件在环 (SIL) 测试来验证为自定义入口函数生成的代码。使用您的生成代码创建一个 SIL 模块。然后,将该 SIL 模块集成到一个模型中,以验证生成代码提供与原始模型或非虚拟子系统相同的结果。有关详细信息,请参阅 选择 SIL 或 PIL 方法

为函数类别配置默认代码生成设置

通过为整个模型中的函数类别指定默认配置,减少为 C 代码生成而准备模型的工作量。例如,您可以配置函数命名规则和函数代码在内存段中的位置。应用默认配置可以节省时间并降低在代码中引入错误的风险,尤其是对于具有大量函数的模型。

代码生成器为下列类别的模型函数生成入口函数:

函数类别描述
初始化/终止用于初始化和关闭系统的函数
执行用于启动执行和重置的函数
共享实用工具共享工具函数代码

通过使用代码映射编辑器 - C 或代码映射 API 函数 setFunctionDefault,为函数配置默认代码映射。使用这些接口,您可以将函数类别与模型的 Embedded Coder 字典中定义的函数自定义模板相关联。

如果您的应用程序要求您配置内存中入口函数的位置(例如,用于针对特定硬件优化生成代码),您可以将默认内存段应用于模型中的一个函数类别。在代码映射编辑器中,将函数类别映射到定义为使用特定内存段的函数自定义模板。请参阅Create Function Customization Template

如果函数自定义模板不存在,您可以使用 Embedded Coder 字典创建一个(请参阅Define Service Interfaces, Storage Classes, Memory Sections, and Function Templates for Software Architecture)。

有关如何为函数类别设置默认配置的示例,请参阅Configure Default C Code Generation for Categories of Data Elements and Functions

为单个 C 入口函数配置名称

为了使您的生成的 C 代码符合代码标准和规范,或更轻松地将该代码与外部代码集成,您可以配置单个入口函数的名称。例如,您可以将为一个模型生成的初始化函数命名为 myInitFunc

如果您的模型满足下列至少一个条件,请考虑单独配置函数的名称:

  • 使用多个要求唯一命名的函数。

  • 使用很少的函数。

  • 具有函数类别的默认配置,并且您需要覆盖特定函数的配置。

通过使用代码映射编辑器或代码映射 API 函数 setFunction,为单个单步函数配置函数名称。

要了解详细信息,请参阅:

为单个单步函数配置名称和参量

为了使您的生成的 C 代码符合代码标准和规范,或更轻松地将代码与外部代码集成,您可以配置为 Simulink 周期函数生成的各个单步函数的名称和参量。您可以自定义单步函数的以下方面:

  • 函数名称

  • 参量名称

  • 参量的顺序

  • 返回值和参量数据限定符

  • 参量的缓冲优化

如果您的模型满足下列至少一个条件,请考虑单独配置单步函数的名称和参量:

  • 是周期性单任务模型,且代码生成器为其生成一个单步函数。

  • Execution 函数类别具有默认配置,并且您需要覆盖特定单步函数的配置。

通过使用代码映射编辑器或代码映射 API 函数 setFunction,为各个单步函数配置代码映射。

要了解详细信息,请参阅:

以编程方式配置 C 入口函数的代码生成设置

要为 C 代码生成自动配置模型函数,请使用代码映射的编程接口。例如,当创建自定义模块库或应用程序测试环境的一部分时,可使用编程接口来自动化函数配置。

这些函数的典型用途包括:

  • 创建一个函数接口。

  • 修改一个现有函数接口。

  • 基于模型的默认配置信息创建一个函数接口。

  • 将该模型函数接口重置为默认 ERT 函数配置。

有关如何以编程方式配置 C 入口函数的代码生成设置的示例,请参阅Configure Default Data and Function Code Generation Programmatically。此示例说明如何为函数类别和单个函数配置默认设置。

要了解有关使用编程接口自定义生成的 C 入口函数的更多信息,请参阅:

如何与生成的入口函数对接

  1. 为模型生成代码后,使用代码视图查看生成的入口函数,以及表示外部输入和输出端口的变量(如果适用)。

  2. #include 语句添加到外部代码中,这些语句包括声明模型入口函数的生成的头文件。

  3. 添加一条 #include 语句以包含生成的文件 rtwtypes.h。此文件提供类型定义、#define 语句和枚举。

  4. 初始化目标特定的数据结构体和硬件,如 ADC 或 DAC。

  5. 如果适用,为可重用模型的每个实例初始化数据。

  6. 如果适用,将输入数据写入表示模型 Inport 模块的生成变量。

  7. 调用生成的入口函数或设置 rt_OneStep 函数的使用。

  8. 如果适用,从表示模型 Outport 模块的生成变量中读取数据。

有关详细信息,请参阅Deploy Applications to Target Hardware

C 函数接口自定义限制

生成的 C 函数接口的自定义有以下限制:

  • 您必须选择模型配置参数单一输出/更新函数

  • 支持多速率模型,但您必须为单任务配置模型。

  • 您必须配置根级输入端口和输出端口以使用 Default 存储类。

  • 如果您选择自定义函数接口,您必须提供自己的自定义 main 程序。您无法使用 MathWorks® 提供的静态 rt_main.c 来配置函数接口。指定非默认的函数接口配置会导致生成的代码与默认静态 rt_main.c 不匹配。

  • 代码生成器会删除模型根输入端口的数据结构体,除非由不可重用函数实现的子系统使用一个或更多个输入端口的值。

  • 代码生成器会删除模型的根输出端口的数据结构体,除非您启用 MAT 文件记录或者一个或更多个输出端口的采样时间不是基本速率(包括恒定速率)。

  • 如果您复制子系统模块以在新模型或同一模型中创建模块,则原始子系统模块的函数接口信息不会复制到新子系统模块中。

  • 如果您有 Stateflow®,则对于使用模型根输入端口值或调用使用模型根输入端口值的子系统的 Stateflow 图,请执行以下操作之一来生成代码:

    • 在 Stateflow 图中,清除初始化时执行(进入)图复选框。

    • 将 Stateflow 函数设置为不可重用的函数。

    • 在根输入端口后立即插入 Simulink® Signal Conversion 模块。在 Signal Conversion 模块参数对话框中,选择从 ''模块简化'' 优化中排除此模块

  • 如果模型根输入端口值连接到 Simscape™ 转换模块,请在根输入端口和 Simscape 转换模块之间插入 Simulink Signal Conversion 模块。在 Signal Conversion 模块参数对话框中,选择从 ''模块简化'' 优化中排除此模块

  • 当编译配置有函数接口的引用模型时,不要使用虚拟总线作为引用模型的输入或输出。请改用非虚拟总线。

  • 如果 C 函数接口不是默认值,则忽略模型配置参数为代码生成按值传递固定大小的标量根输入的值。有关详细信息,请参阅Pass fixed-size scalar root inputs by value for code generation

另请参阅

| | |

主题