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 size | Fixed-step / 0.001 | 决定代码执行周期 |
| 目标 | System target file | ert.tlc | 启用 Embedded Coder |
| 语言 | Language | C | 生成 C 代码 |
| 接口 | Code interface packaging | Reusable function | 生成可复用函数接口 |
| 优化 | Default parameter behavior | Inline | 参数内联,减少 RAM 占用 |
| 硬件 | Device vendor / type | ARM / Cortex-M | 匹配目标处理器 |
代码生成报告是验证配置是否正确的第一手资料。报告通常包含:模型摘要、配置摘要、生成的代码文件列表、接口函数说明、以及代码度量(如函数数量、代码行数、RAM/ROM 估算)。阅读报告时,重点看三处:一是“Code Interface Report”中的入口函数和步进函数是否符合预期;二是“Static Memory”中的 RAM 估算是否超出目标芯片容量;三是“Traceability Report”中模型模块与生成代码的对应关系,便于后续调试。
从图中可以看出,代码生成不是单点操作,而是“模型—配置—代码—编译—硬件—报告”的闭环。任何一环配置不当,都会在报告或编译阶段暴露出来。例如,若目标硬件 RAM 只有 128 KB,而报告显示静态内存占用 160 KB,就必须回头调整参数内联策略或数据类型,而不是强行编译。
config_blink.m 中集中设置 set_param,这样换一台机器或换一个目标时,只需修改脚本中的硬件参数,而不必逐项点击对话框。
完成第一个工程后,建议做一次最小验证:把生成的 blink.c 与 ert_main.c 加入目标工程,编译下载,观察 LED 是否按 1 秒周期闪烁。若闪烁周期不符,优先检查模型步长与目标定时器配置是否一致;若编译报错,优先检查交叉编译器路径与目标芯片型号是否匹配。通过这个闭环,才算真正完成了代码生成环境的搭建。