4. 接口分类与边界定义
在 Stateflow 模型的数据字典与接口治理中,最容易出问题的不是“有没有接口”,而是“接口被归到了错误的类别”。一旦分类错位,后续的命名规范、数据类型校验、代码生成配置、变更影响分析都会跟着错。本节要解决的核心问题是:把模型中实际存在的五类接口——输入输出接口、参数接口、信号接口、总线接口、函数调用接口——按治理边界清晰区分,并给出可落地的判定依据。
五类接口的治理边界
先明确一个前提:这里的“接口”指 Stateflow 图表、Simulink 子系统或模型边界上,与外部发生数据或控制交互的端口与调用点。五类接口的治理边界可以这样理解:
- 输入输出接口:模型或图表边界上的标量/数组数据端口,承担单向数据传递。治理重点是方向、数据类型、维度、采样时间与初始值。
- 参数接口:在仿真或代码生成前确定、运行期不改变的量,如增益、阈值、查表断点。治理重点是常量性、可调性(tunable)、存储类与标定方式。
- 信号接口:带语义与刷新机制的信号,如事件、消息、控制使能。治理重点是信号名、刷新周期、事件触发条件与优先级。
- 总线接口:由多个信号按固定结构聚合而成的复合接口。治理重点是总线对象定义、元素顺序、嵌套深度与版本兼容。
- 函数调用接口:通过函数调用触发的接口,如 Simulink Function、导出函数、外部 C 函数调用。治理重点是调用签名、参数传递方式、重入性与执行顺序。
这五类接口在治理上不是并列关系,而是存在“数据—参数—信号—总线—调用”的递进关系:数据端口是最小单元,参数是运行期不变的端口,信号是带时序语义的端口,总线是端口的结构化聚合,函数调用则是控制流层面的接口。理解这个递进关系,是避免分类错位的关键。
分类错位的典型后果
把参数当成信号,会导致代码生成时该常量被分配为全局变量,增加 RAM 占用并破坏可标定性;把信号当成参数,会导致运行期无法刷新,控制逻辑失效。把总线接口拆成多个独立输入输出端口,会破坏结构语义,使接口数量膨胀、变更影响面难以追踪。把函数调用接口当作普通数据端口,会丢失调用时序与重入性约束,在并发调用场景下产生竞态。
因此,分类不是命名问题,而是治理边界问题。每一类接口对应一组独立的校验规则、变更流程与责任人。
可落地的接口分类判定表
下面给出一份可直接用于模型评审的接口分类判定表。表中“判定问题”按顺序回答,第一个“是”即确定类别;“治理动作”是该类别必须执行的检查项。
| 判定顺序 | 判定问题 | 接口类别 | 治理动作 |
|---|---|---|---|
| 1 | 是否由函数调用触发,而非数据流驱动? | 函数调用接口 | 声明调用签名、参数传递方式、重入性;登记调用方与被调用方 |
| 2 | 是否由多个信号按固定结构聚合而成? | 总线接口 | 集中定义总线对象;锁定元素顺序;建立版本兼容矩阵 |
| 3 | 是否在仿真步进中需要改变取值? | 信号接口 | 声明刷新周期与触发条件;校验周期与图表执行周期一致 |
| 4 | 是否在运行期保持不变,仅用于标定或配置? | 参数接口 | 标记 tunable;指定存储类;登记标定范围与默认值 |
| 5 | 以上均否,仅为单向数据传递? | 输入输出接口 | 声明方向、数据类型、维度、采样时间、初始值 |
示例:一个电机控制图表的接口分类
假设有一个 Stateflow 图表负责电机使能与转速闭环,其边界上存在以下对象,按上表逐一判定:
EnableCmd:布尔量,由外部调度周期写入,运行期可变 → 信号接口,刷新周期 10 ms。SpeedRef:标定量,运行期不变,需在线标定 → 参数接口,标记 tunable,存储类ExportedGlobal。MotorBus:包含Speed、Current、Temp三个元素 → 总线接口,总线对象集中定义,元素顺序锁定。GetSpeed():由外部 C 函数调用获取当前转速 → 函数调用接口,声明返回值类型与重入性。PwmDuty:输出到执行器的占空比,单向数据传递 → 输入输出接口,声明初始值 0、数据类型uint16。
这个示例说明:同一个图表边界上可以同时存在五类接口,治理时必须逐类登记、逐类校验,不能混为一谈。
完成分类后,每一类接口都应进入对应的治理台账:输入输出接口登记方向与类型,参数接口登记可调性与存储类,信号接口登记刷新周期与触发条件,总线接口登记结构版本,函数调用接口登记签名与重入性。这样,接口边界才真正可查、可审、可追溯。