1. 交付指南总览

在基于模型的设计(Model-Based Design,MBD)体系中,Stateflow 并不是一个孤立的“画状态图工具”,而是嵌入在 Simulink 模型内部、用于描述离散事件驱动逻辑、模式切换与状态调度的执行语义载体。理解它的工程定位,是后续所有建模规范、代码生成配置与交付验收工作的前提。

从软件架构视角看,一个典型的嵌入式控制模型通常由三部分构成:连续或离散的数据流算法(由 Simulink 框图承担)、控制逻辑与模式管理(由 Stateflow 状态机承担)、以及接口与调度层(由 Function-Call、触发子系统等承担)。Stateflow 的核心价值在于:它把“在什么条件下、从哪个模式、切换到哪个模式、执行什么动作”这类难以用纯框图清晰表达的判断逻辑,用状态、转移、条件与动作的语义精确固化下来,并最终通过 Embedded Coder 生成可追溯、可验证的 C 代码。

因此,Stateflow 在项目中的定位可以概括为三句话:它是模式与事件逻辑的唯一权威描述;它是生成代码中状态变量与调度分支的直接来源;它是需求—模型—代码—测试之间可追溯链条的关键节点。任何绕过 Stateflow、在 Simulink 中用大量 Switch 与 Memory 模块“拼”出来的状态逻辑,都会在可读性、可验证性和代码效率上付出代价。

Stateflow 工程交付全流程与角色—交付物映射 ① 需求与接口 状态/事件/信号清单 ② 架构与状态划分 层次/并行/互斥 ③ Stateflow建模 状态/转移/动作 ④ 模型验证 MIL/SIL 测试 ⑤ 代码生成 C代码/标定 交付物 需求规格书 接口定义表 交付物 状态机架构图 状态转移表 交付物 .slx 模型文件 建模规范检查报告 交付物 测试用例集 覆盖率报告 交付物 生成C代码 代码追溯矩阵 角色分工 系统工程师 需求分解·接口定义·状态划分 建模工程师 Stateflow建模·规范自检 验证工程师 测试设计·MIL/SIL·覆盖率 集成/代码工程师 代码生成·集成·追溯核对 关键质量门(Gate) G1 建模规范检查通过 命名/层次/默认转移/无死状态 G2 需求覆盖率达标 状态/转移覆盖率 ≥ 目标值 G3 代码追溯完整 需求↔状态↔代码双向可追溯 流程自左向右推进;交付物与角色按列对齐;质量门为阶段放行判据

工程交付全流程的五个阶段

上图给出了从需求到代码的完整链路。需要强调的是,这条链路不是“一次性瀑布”,而是带反馈的迭代闭环:验证阶段发现的转移遗漏或状态爆炸,会反向驱动架构与建模的修改。下面逐段说明每个阶段真正要产出的东西。

阶段一:需求与接口。这一阶段的核心不是写文档,而是把“系统在哪些模式下工作、模式之间因何切换、切换时输出什么”抽取成可建模的要素。具体做法是建立三张清单:状态清单(如 Idle、Init、Run、Fault、Shutdown)、事件清单(如 StartCmd、Timeout、FaultDetected)、信号清单(输入/输出/参数,含数据类型、量纲、初值)。例如一个电机控制器的状态清单可定义为:Init→Ready→Run→Fault→Recovery,事件包括 Enable、Disable、OverCurrent、RecoverCmd。接口定义必须明确每个信号的来源与去向,避免建模时出现“悬空输入”。

阶段二:架构与状态划分。这是最容易被低估、却最影响后期维护的一步。划分原则是:互斥行为放同一层,独立行为用并行(Parallel)状态。例如“运行模式管理”与“故障监控”在逻辑上相互独立,应做成两个并行状态,而不是塞进一个巨大的互斥状态机。层次深度建议控制在 3~4 层以内,超过则考虑拆分为独立 Stateflow 图表或引用子系统。此阶段应产出状态机架构图与状态转移表,作为建模的直接输入。

阶段三:Stateflow 建模。建模时需遵循几条硬性约定:每个状态必须有明确的 entry/exit/during 动作分工;默认转移必须显式指定,避免上电后处于未定义状态;转移条件中禁止出现副作用赋值;使用 after(n, tick) 或 temporalCount 表达时间逻辑时,必须确认采样周期与 tick 定义一致。一个典型的转移写法如下:

// 状态 Run 到 Fault 的转移条件
[OverCurrent == true] / {
    FaultCode = 0x01;
    MotorEnable = false;
}
// 状态 Fault 到 Recovery 的转移条件
[after(50, msec) && RecoverCmd == true]

这段示例中,OverCurrent 是布尔输入,FaultCode 与 MotorEnable 是输出,after(50, msec) 表示在 Fault 状态持续 50 ms 后且收到恢复命令才转移。注意:msec 必须与模型基础采样率匹配,否则时间语义会出错。

阶段四:模型验证。验证分两层:模型在环(MIL)验证逻辑正确性,软件在环(SIL)验证生成代码与模型行为一致。测试用例应覆盖:每个状态的进入与退出、每条转移的触发与不触发、边界条件(如超时恰好等于阈值)、以及非法转移的防护。覆盖率指标重点关注状态覆盖率与转移覆盖率,通常要求达到 100% 状态覆盖、转移覆盖不低于项目约定阈值(如 95%)。若存在无法覆盖的转移,必须在报告中说明原因并标记为“设计冗余”或“防御性分支”。

阶段五:代码生成与集成。使用 Embedded Coder 生成代码时,需配置:状态变量存储类型(如 uint8 枚举)、函数封装方式(单文件或多文件)、以及是否生成标定接口。生成后必须核对代码追溯矩阵:每条需求对应哪些状态、每个状态对应哪些代码行。集成阶段常见问题是状态变量命名冲突或采样周期不一致,需在代码审查中重点检查。

角色分工与交付物清单

角色分工不是行政划分,而是责任边界。系统工程师负责“定义正确的问题”,建模工程师负责“正确地实现”,验证工程师负责“证明实现正确”,集成工程师负责“让它在目标环境跑起来”。四者之间通过交付物交接,而非口头约定。

角色 核心职责 关键交付物 交接对象
系统工程师 需求分解、接口定义、状态划分 需求规格书、接口定义表、状态转移表 建模工程师
建模工程师 Stateflow 建模、规范自检 .slx 模型、建模规范检查报告 验证工程师
验证工程师 测试设计、MIL/SIL、覆盖率分析 测试用例集、覆盖率报告、缺陷记录 建模/集成工程师
集成/代码工程师 代码生成、集成、追溯核对 生成 C 代码、代码追溯矩阵、集成说明 项目配置管理
实践提示:交付物清单应在项目启动时冻结版本号与命名规则。例如模型文件命名建议采用 项目_模块_功能_版本.slx,测试用例编号与需求编号保持可映射关系(如 REQ-001 对应 TC-001-01)。这样在后期变更时,追溯成本会显著降低。
常见误区:把 Stateflow 当成“画流程图”的工具,用状态节点表达顺序步骤而非真实模式。判断标准很简单:如果两个节点之间不存在“持续停留并等待事件”的语义,那它就不该是状态,而应写成转移上的条件动作或 Simulink 中的使能子系统。

最后需要建立的一个认知是:Stateflow 交付质量不取决于图有多漂亮,而取决于状态语义是否唯一、转移条件是否完备、时间行为是否可预测、追溯链条是否闭合。这四点贯穿上述五个阶段,也是后续每一章展开具体规范与操作时反复回到的基准。