3. 量产代码生成配置基础
在 Stateflow 量产代码生成工程中,模型能否生成可编译、可集成、可上车的 C 代码,并不取决于 Stateflow 图本身画得多完整,而取决于模型配置参数(Configuration Parameters)这一层“工程契约”是否设置正确。可以把配置参数理解为模型与目标硬件、编译器、集成工程之间的接口声明:它决定了生成什么形态的代码、面向什么处理器、使用什么数据类型、如何组织文件、如何与手写代码对接。本节围绕四个相互关联的核心对象展开:模型配置参数、代码生成目标(Code Generation Objectives)、系统目标文件(System Target File, STF)与硬件配置(Hardware Implementation)。
一、四层配置对象的关系
这四者不是并列的四个设置页,而是层层收敛的关系。代码生成目标回答“我要生成什么样的代码”,例如 ROM 效率优先、RAM 效率优先、执行效率优先、可追溯性优先;系统目标文件回答“用哪套代码生成器与运行时框架”,例如 ert.tlc(Embedded Coder)、grt.tlc(通用实时目标);硬件配置回答“代码跑在什么器件上”,包括处理器厂商、类型、字节序、字长、整数除法舍入方式等;模型配置参数则是承载上述所有选择的容器,并进一步约束求解器、数据类型、代码风格与文件打包方式。四层关系可用下图表示。
二、模型配置参数:先定求解器与代码形态
打开模型后进入 Modeling > Model Settings,或使用命令行 Simulink.ConfigSet 与 set_param 批量设置。对 Stateflow 量产代码而言,最关键的几组参数如下。
求解器(Solver):量产嵌入式代码通常选择固定步长(Fixed-step)、离散(Discrete)求解器,步长与任务周期一致。例如 10 ms 任务周期,则 Solver = Fixed-step、Fixed-step size = 0.01、Solver = discrete (no continuous states)。若模型含连续状态,则需评估是否引入积分误差,量产中一般避免在 Stateflow 控制逻辑里混入连续动态。
代码生成系统目标:在 Code Generation > System target file 中选择 ert.tlc。选择后会自动启用 Embedded Coder 的代码风格选项,如函数原型控制、文件分离、可复用子系统函数等。
语言与数据类型:Language = C;Code interface packaging 建议选 Reusable function 或 Nonreusable function,取决于该模型是否被多次实例化。若模型需要多实例,必须选可复用并配合 Model reference。
文件打包:Code Generation > Code Packaging 中,Generate source code only 适合集成到已有工程;Generate makefile 适合独立编译验证。量产集成通常选前者,由集成方提供 Makefile。
三、代码生成目标:把“效率”变成可勾选项
Embedded Coder 提供 Code Generation > Objectives 页面,可勾选优先级并生成建议配置。常见目标与对应参数变化如下表。
| 代码生成目标 | 典型参数变化 | 量产适用场景 |
|---|---|---|
| 执行效率优先 | 开启 Inline invariant signals、Inline parameters,关闭调试信息 | 高实时性控制回路 |
| ROM 效率优先 | 启用 Reuse block outputs、共享工具函数、压缩查找表 | Flash 资源紧张的 ECU |
| RAM 效率优先 | 减少全局状态、复用缓冲区、启用 Optimize block IO storage | RAM 受限的 MCU |
| 可追溯性优先 | 保留注释、开启 Traceability、生成 HTML 报告 | 功能安全与审计 |
注意:目标勾选只是“建议”,最终仍需人工核对,因为某些目标会互相冲突,例如执行效率与可追溯性往往不能同时最大化。
四、硬件配置:决定数据类型的物理边界
硬件配置位于 Hardware Implementation > Device vendor / Device type。选择具体器件后,工具会自动填充字长与字节序。若使用自定义 MCU,需手动设置:
Number of bits: char = 8, short = 16, int = 16, long = 32(以 16 位 MCU 为例)Byte ordering = Little Endian或Big EndianSigned integer division rounds to = Zero或FloorShift right on signed data = Arithmetic或Logical
这些设置直接影响 Stateflow 中 int、uint16 等类型的实际位宽,以及除法、移位运算的生成结果。若硬件配置与编译器实际行为不一致,会出现仿真与实车行为偏差,这是量产调试中常见的隐蔽问题。
sizeof(int)、负数除法与右移结果。五、配置落地示例
以下为某 32 位车规 MCU 上 Stateflow 控制模型的配置片段,可作为起点参考:
% 系统目标文件与语言
set_param('MyCtrlModel','SystemTargetFile','ert.tlc');
set_param('MyCtrlModel','TargetLang','C');
% 求解器:固定步长 10 ms
set_param('MyCtrlModel','SolverType','Fixed-step');
set_param('MyCtrlModel','Solver','FixedStepDiscrete');
set_param('MyCtrlModel','FixedStep','0.01');
% 硬件配置
set_param('MyCtrlModel','ProdHWDeviceType','ARM Compatible->ARM Cortex-M');
set_param('MyCtrlModel','ProdEndianess','LittleEndian');
set_param('MyCtrlModel','ProdIntDivRoundTo','Zero');
set_param('MyCtrlModel','ProdShiftRightIntArith','on');
% 代码打包
set_param('MyCtrlModel','GenerateMakefile','off');
set_param('MyCtrlModel','GenerateComments','on');
set_param('MyCtrlModel','MatFileLogging','off');
配置完成后,建议执行一次 slbuild('MyCtrlModel') 或按 Ctrl+B,检查生成的 MyCtrlModel.c/.h、MyCtrlModel_data.c 与 rtwtypes.h 是否符合预期。重点核对:函数原型是否与集成接口一致、数据类型是否与硬件配置匹配、是否生成了不需要的调试代码。只有这四层配置全部对齐,Stateflow 的量产代码生成才具备可重复、可集成的工程基础。