2. 代码生成环境搭建与工程配置

Embedded Coder 的代码生成不是“点一下按钮”就结束的动作,它依赖一条完整的工具链:MATLAB/Simulink 负责模型与算法,Embedded Coder 负责把模型翻译成面向嵌入式目标的 C/C++ 代码,编译器负责把代码编译成目标可执行文件,而目标硬件则决定代码的存储布局、数据类型和运行约束。本章围绕这条工具链,讲清安装、编译器与目标硬件配置、第一个代码生成工程的创建,以及模型配置参数集与代码生成报告的阅读方法。

一、安装与版本匹配

安装时最容易踩的坑不是“装没装”,而是“版本是否匹配”。MATLAB、Simulink、Embedded Coder 必须来自同一 Release,例如 R2023b 的 MATLAB 只能搭配 R2023b 的 Embedded Coder。此外,代码生成还依赖若干支持包:用于编译的 Simulink Coder Support Package、用于特定芯片的硬件支持包(如 TI C2000、STM32、NXP S32K 等),以及用于验证的 Embedded Coder Support Package for Embedded Coder Verification。安装完成后,可用以下命令确认环境是否就绪:

ver('embeddedcoder')          % 查看 Embedded Coder 版本
mex -setup C                  % 配置 C 编译器
mex -setup C++                % 配置 C++ 编译器
coder.checkGpuInstall         % 若涉及 GPU 代码生成时使用

如果 mex -setup 找不到编译器,说明系统未安装受支持的编译器,或 MATLAB 未识别到它。Windows 上常用 Microsoft Visual C++,Linux 上常用 GCC,嵌入式目标则常使用交叉编译器(如 arm-none-eabi-gcc、ti-cgt-arm)。

二、编译器与目标硬件配置

编译器配置的核心是让 MATLAB 知道“用哪个编译器、编译什么目标”。对于主机端验证,配置本机编译器即可;对于嵌入式目标,需要配置交叉编译器和目标硬件参数。以 STM32 为例,典型配置包括:目标处理器架构(Cortex-M4)、字节序(小端)、字长(32 位)、浮点单元(FPU 是否启用)、堆栈大小、以及链接脚本中定义的 Flash/RAM 地址范围。这些参数会直接影响生成代码中的 typedef、数据对齐和内存分配。

目标硬件配置通常通过硬件支持包提供的 hardware 对象完成,例如:

hw = coder.hardware('STM32F4xx');
hw.Processor = 'STM32F407';
hw.ClockFrequency = 168e6;   % 168 MHz
hw.StackSize = 4096;         % 4 KB

配置完成后,建议先用一个最小模型做“编译—下载—运行”闭环验证,确认工具链通畅,再进入正式工程。

三、创建第一个代码生成工程

创建工程时,推荐使用 Simulink 的“模型 + 配置集”方式,而不是把参数散落在模型里。一个可复现的最小工程通常包含:一个 Simulink 模型(如 blink.slx)、一个配置集脚本(如 config_blink.m)、一个目标硬件描述文件,以及一个用于构建的脚本。模型本身可以很简单,例如一个周期为 1 秒的方波驱动 LED,但配置必须完整。

在模型配置中,关键参数包括:求解器类型(定步长 Fixed-step)、步长(如 0.001 秒)、系统目标文件(ert.tlc 用于 Embedded Coder)、语言(C)、以及代码生成报告选项。配置完成后,使用 slbuild 或 rtwbuild 触发代码生成:

slbuild('blink');
% 或
rtwbuild('blink');

生成结束后,会在工作目录下产生 blink_ert_rtw 文件夹,其中包含 blink.c、blink.h、blink_data.c、ert_main.c 等文件。这些文件就是后续集成到目标工程的基础。

四、模型配置参数集与代码生成报告

模型配置参数集(Configuration Set)是代码生成的“控制面板”,它决定了生成代码的形态。常用参数可分为四类:求解器与步长、代码生成目标与语言、优化与接口、以及硬件实现。下表给出一个面向嵌入式目标的典型配置示例:

参数类别参数名示例值作用
求解器Solver / Fixed-step sizeFixed-step / 0.001决定代码执行周期
目标System target fileert.tlc启用 Embedded Coder
语言LanguageC生成 C 代码
接口Code interface packagingReusable function生成可复用函数接口
优化Default parameter behaviorInline参数内联,减少 RAM 占用
硬件Device vendor / typeARM / Cortex-M匹配目标处理器

代码生成报告是验证配置是否正确的第一手资料。报告通常包含:模型摘要、配置摘要、生成的代码文件列表、接口函数说明、以及代码度量(如函数数量、代码行数、RAM/ROM 估算)。阅读报告时,重点看三处:一是“Code Interface Report”中的入口函数和步进函数是否符合预期;二是“Static Memory”中的 RAM 估算是否超出目标芯片容量;三是“Traceability Report”中模型模块与生成代码的对应关系,便于后续调试。

Embedded Coder 代码生成工具链与配置关系 MATLAB / Simulink 模型 blink.slx 算法与信号定义 求解器:Fixed-step Embedded Coder 系统目标文件 ert.tlc 配置集 config_blink.m 代码优化与接口打包 生成 C 代码 blink.c / blink.h blink_data.c ert_main.c 编译器 / 交叉编译器 mex -setup C arm-none-eabi-gcc 目标硬件 STM32F407 Flash / RAM / FPU 代码生成报告(Code Generation Report) Code Interface Report · Static Memory · Traceability Report 检查入口函数、RAM/ROM 估算、模型与代码对应关系 模型是源头 配置决定形态

从图中可以看出,代码生成不是单点操作,而是“模型—配置—代码—编译—硬件—报告”的闭环。任何一环配置不当,都会在报告或编译阶段暴露出来。例如,若目标硬件 RAM 只有 128 KB,而报告显示静态内存占用 160 KB,就必须回头调整参数内联策略或数据类型,而不是强行编译。

建议把配置集写成脚本并纳入版本管理,例如 config_blink.m 中集中设置 set_param,这样换一台机器或换一个目标时,只需修改脚本中的硬件参数,而不必逐项点击对话框。
不要忽略“代码生成报告”中的警告信息。常见警告如“参数未内联”“数据类型不匹配”“未使用的变量”等,往往对应着 RAM 浪费或运行时错误,应在集成前处理。

完成第一个工程后,建议做一次最小验证:把生成的 blink.c 与 ert_main.c 加入目标工程,编译下载,观察 LED 是否按 1 秒周期闪烁。若闪烁周期不符,优先检查模型步长与目标定时器配置是否一致;若编译报错,优先检查交叉编译器路径与目标芯片型号是否匹配。通过这个闭环,才算真正完成了代码生成环境的搭建。