从 Simulink 模型中生成 C 代码
使用 Embedded Coder® 产品生成针对在快速原型构建板、嵌入式处理器或微处理器上部署而优化的 C 或 C++ 代码。如果您刚开始使用 Embedded Coder 或您的应用程序代码自定义要求很少,则您可以使用图形工具和默认代码配置设置来快速生成生产质量的代码。如果您需要生成用于与现有外部代码集成的自定义代码,或者要满足代码指导原则和标准,则可以使用工具来配置代码生成器以满足对接、代码外观、打包和优化方面的要求。
就像使用 Quick Start 工具准备用于代码生成的模型一样,生成和查看用于部署到嵌入式系统的代码可以很简单。然后,使用可从 Simulink Editor 访问的代码工具,您可以配置代码接口、启动代码生成以及查看生成的代码。
前提条件
要完成本教程,您必须具有以下产品:
· MATLAB®
· MATLAB Coder™
· Simulink®
· Simulink Coder
· Embedded Coder
示例模型
本教程使用示例模型 rtwdemo_roll 和 rtwdemo_roll_harness。这两个模型已经过仿真验证。
打开模型 rtwdemo_roll。

此模型实现一种基本的横滚轴自动驾驶算法,用于控制飞机的副翼位置。

此模型代表飞机的更大控制系统中的一个组件。通过 HDG_Mode 信号,控制系统将模型置于两种操作模式之一:滚转姿态保持或航向保持。RollAngleReference 和 HeadingMode 子系统计算支持其中一种操作模式的滚转姿态设置值。然后,BasicRollMode 子系统(一个 PID 控制器)根据适当的设置值和指示测量的滚转姿态和更改速率的反馈来计算副翼位置命令。该模型设计为以 40 Hz 运行。
本教程使用模型 rtwdemo_roll_harness 来测试 rtwdemo_roll。
您将学习如何:
1. 使用 Embedded Coder Quick Start 生成代码。
2. 配置数据接口。
3. 将模型参数配置为全局变量,用于在运行时进行调优。
4. 比较模型仿真和生成的代码结果以了解数值等效性。
5. 部署生成的代码。
要开始本教程,请参阅使用 Embedded Coder Quick Start 生成代码。
使用 Embedded Coder Quick Start 生成代码
(步骤 1/5) 从 Simulink 模型中生成 C 代码
从 Simulink 模型中生成 C 代码中所述的模型 rtwdemo_roll 表示用于飞机的自动驾驶控制系统。您使用 Embedded Coder® Quick Start 为嵌入式代码生成准备 rtwdemo_roll,该模型根据您的目标和应用程序选择基本代码生成设置。
打开模型 rtwdemo_roll。

将模型的一个副本保存到 MATLAB 搜索路径上的一个可写位置。
打开 Quick Start 工具。在 Simulink® Editor 中,选择 Code > C/C++ Code > Embedded Coder Quick Start。
逐步执行 Quick Start 工具的各个步骤。每个步骤都会询问有关您要生成的代码的问题。对于本教程,请使用已选择的默认值。该工具根据模型验证您的选择,并显示生成代码所需的参数更改。

在 Generate Code 步骤中,点击 Next 应用建议的更改并从 rtwdemo_roll 生成代码。
点击 Finish 关闭工具。
该工具使模型处于 Simulink Editor 代码方式下。在此方式下,您可以配置代码生成自定义,然后在模型旁边的代码视图中检查结果是否正确。

在 Code Mapping Editor 中的 Entry-Point Functions 选项卡上,您可以看到代码生成器生成的各个入口函数。您可以从外部代码或您修改的生成主函数的版本调用这些生成的函数。如果需要,您可以更改函数的名称。对于基于速率的模型的基本速率单步函数和导出函数模型的单步函数,您可以自定义函数名称和参数。
生成的代码出现在两个主文件中:rtwdemo_roll.c 和 rtwdemo_roll.h。在您的 MATLAB® 当前文件夹中,rtwdemo_roll_ert_rtw 文件夹包含这些主文件。
在您的当前文件夹中,代码生成器会创建 slprj 文件夹。此文件夹包含 rtwtypes.h 文件,该文件定义生成的代码默认使用的标准数据类型。通常,此同级文件夹包含可以或必须在多个模型之间共享的生成文件。
您从模型中生成的代码包含从应用程序代码调用的入口函数。对于基于速率的模型,这些函数包括初始化函数、执行函数以及可选的终止和重置函数。这些函数通过您控制的数据接口与应用程序代码交换数据。
在 Code Mapping Editor 中的 Entry-Point Functions 选项卡上,查看代码生成器为模型生成的入口函数的列表。使用此视图有选择地为每个函数指定一个函数自定义模板(代码定义)和名称。对于本教程,代码生成器使用自定义模板和入口函数名称的默认(附带)设置。代码生成器会为初始化函数 rtwdemo_roll_initialize 和执行(单步)函数 rtwdemo_roll_step 命名。这两个入口函数都有一个 void-void 接口(它们不传递任何参数)。这些函数通过共享数据结构体访问数据。此类数据的示例包括函数与应用程序代码交换的系统级输入和输出。

要在生成的代码中查看这些入口函数,请执行下列操作:

在 Simulink Editor 代码方式右侧的代码视图窗格中,找到搜索栏。
在搜索栏中,键入 rtwdemo_roll_step。要在生成的代码文件中查找单步函数名称的每个实例,请点击搜索建议。
使用右侧的箭头步进每个实例,包括 rtwdemo_roll.c 中的单步函数定义和 rtwdemo_roll.h 中的声明。单步函数有一个 void-void 接口,它不传递任何参数。您还可以通过左上角的文件菜单查看每个文件中的搜索命中数。

重复这些搜索步骤,以在生成的代码中找到初始化函数 rtwdemo_roll_initialize。
接下来,为代码生成配置数据接口并查看生成的代码。
将模型参数配置为全局变量以在运行时调整
(步骤 3/5) 从 Simulink 模型中生成 C 代码
·
·
·
·
·
默认情况下,代码生成优化可避免存储不参与入口函数接口的模型参数和大多数信号。要使参数可调和相关信号可访问,请通过显式配置方式来标识它们。
在模型 rtwdemo_roll 的 BasicRollMode 子系统中,将 PID 控制参数配置为在代码中显示为可调整其值的全局变量。
1. 打开 BasicRollMode 子系统。

2. 在 Model Data Editor 中,选择 Parameters 选项卡。
3. 在筛选器字段中,键入 IntGain。Model Data Editor 会显示一个与 Gain 参数对应的行以及一个与工作区变量对应的行。

4. 在 Source 列中,点击 IntGain。Gain 模块在模型图中高亮显示。
5. 在 Name 列中,点击模型工作区变量 intGain。
6. 将模型工作区变量转换为参数对象。在 Storage Class 列中选择 “Convert to parameter object”。Storage Class 设置更改为 “Model default”,表示该参数对象阻止代码生成优化消除变量的存储。使用此设置时,该对象会将在 Code Mapping Editor 中指定的存储类用作 Local parameters 类别的数据默认值。
7. 保存模型并重新生成代码。
最小化代码生成报告窗口,以便在本教程中的后面部分进行浏览。
8. 在代码视图中:
o 搜索 intGain。
o 在 rtwdemo_roll.c 中,将光标放在高亮代码 P.intGain 中 P 上方的省略号菜单上。在模型编辑器中,请注意代码视图会高亮显示与生成的代码对应的模块。

o 要在 rtwdemo_roll_data.c 中查看 intGain 的参数对象定义,请点击对话框中的定义代码。
您从模型生成的代码会将参数对象存储在内存中。由于您在 Code Mapping Editor 中将 Local parameters 类别的默认存储类设置保留为 “Default”,因此代码生成器会确定存储格式,例如确定为结构体的字段。
接下来,使用测试框架模型和软件在环 (SIL) 仿真来比较模型仿真和生成代码的结果。