4. 为静态分析准备Stateflow模型
Polyspace对Stateflow的分析结果,很大程度上不取决于分析引擎本身,而取决于模型在进入分析前被"塑造成什么样子"。同一份Stateflow逻辑,如果求解器配置、代码生成目标、属性检查器选项和建模规范不同,Polyspace可能给出完全不同的告警集合:有的告警是真实缺陷,有的则是配置不当引入的噪声。本节围绕四类准备工作展开——模型配置参数、代码生成目标设置、Stateflow属性检查器关键选项,以及影响分析结果的建模规范。
一、模型配置参数:先让模型"可被分析"
Polyspace分析Stateflow时,实际处理的是由模型生成的代码或中间表示,因此求解器与仿真配置会直接影响分析输入。需要重点确认的参数包括:
- 求解器类型与步长:Stateflow中的连续状态或与Simulink连续模块耦合时,求解器选择会影响生成代码中的积分与时间推进逻辑。若模型本身是纯离散逻辑,应显式设置为固定步长离散求解器,避免Polyspace在分析中引入不必要的浮点积分路径。
- 固定步长大小:步长决定了生成代码中采样周期的常量值。步长设置过小可能使某些计数器或时间判断在分析中被判定为"永不满足"或"溢出风险",需要在分析前与实际部署周期对齐。
- 采样时间与任务周期:Stateflow图表若继承采样时间,需确认其与Simulink模型的周期一致;若图表显式指定采样时间,应检查是否与目标ECU任务周期匹配。
- 数据类型与目标字长:模型配置中的硬件实现参数(如char、short、int、long的位宽)必须与目标编译器一致,否则Polyspace按默认字长分析时,整型溢出、移位、类型转换类告警会与实际不符。
一个常见做法是:在分析前用Simulink.BlockDiagram.getChecksum或配置集比对,确认分析所用配置与代码生成配置一致。若不一致,Polyspace的结论不能直接用于代码质量判定。
二、代码生成目标设置:让分析对象与交付物一致
Polyspace分析的是生成代码,因此代码生成目标设置决定了"分析什么"。关键设置包括:
- 系统目标文件:选择
ert.tlc(Embedded Coder)还是grt.tlc(通用实时目标),会显著改变生成代码的结构。嵌入式目标通常生成更紧凑、更接近手写代码的形式,更适合做MISRA等规范检查。 - 语言标准:C99与C90在声明位置、复合字面量等方面不同,Polyspace的解析器需与目标语言标准一致,否则会出现语法层面的误报。
- 代码风格与标识符:是否启用可复用子系统代码、是否内联参数、标识符命名规则,都会影响Polyspace对函数边界和变量作用域的判定。
- 浮点与整型运算:是否允许浮点、是否使用定点,直接决定分析中数值范围推导的路径。
三、Stateflow属性检查器中的关键选项
Stateflow属性检查器(Model Advisor中的Stateflow Checks或图表属性中的诊断设置)是控制Stateflow语义严格程度的核心。对Polyspace分析影响最大的选项包括:
- 状态动作中的变量初始化:若允许未初始化即使用,Polyspace会报"未初始化变量"告警;若强制初始化,则需在建模时补齐,否则分析无法通过。
- 转移冲突与默认转移:属性检查器可检测互斥转移、默认转移缺失等问题。这些在Polyspace中可能表现为不可达代码或死逻辑告警。
- 循环与递归限制:Stateflow中的循环上限、递归调用限制会影响Polyspace对最坏执行路径的推导。若设置过宽,可能掩盖真实的栈溢出风险。
- 数据类型传播:是否允许隐式类型转换、是否强制显式类型,直接影响Polyspace对类型不匹配、精度损失的判定。
- 数组越界与索引检查:属性检查器中的数组范围检查若关闭,Polyspace可能无法识别越界访问,导致漏报。
实际操作中,建议在Model Advisor中运行"Stateflow Check"相关检查项,将结果与Polyspace告警做交叉比对:属性检查器报出的问题,往往正是Polyspace告警的根因。
四、影响分析结果的建模规范
建模规范不是"风格问题",而是直接决定Polyspace能否给出有效结论的前提。以下规范对分析结果影响最直接:
- 避免在Stateflow中使用未定义行为:如除零、有符号整型溢出、移位超过位宽。这些在Polyspace中会被明确标记,但若建模时已存在,分析只能报告而不能修复。
- 显式声明数据类型与范围:为每个数据对象指定类型、上下限,Polyspace才能进行精确的范围分析。未指定范围时,分析会退化为保守估计,产生大量误报。
- 保持状态机结构清晰:避免过深的层次嵌套和大量并行状态,否则Polyspace的状态空间爆炸会导致分析超时或结果不完整。
- 统一命名与作用域:局部变量、输出、参数的作用域应明确,避免同名变量在不同层级中含义不同,导致Polyspace误判数据流。
- 避免动态类型与隐式转换:Stateflow中若大量依赖隐式类型转换,Polyspace的类型推导会变得不稳定,告警可信度下降。
下面这张图概括了从模型配置到Polyspace分析结果的完整准备链路,以及四类准备工作各自影响的分析维度。
从图中可以看出,四类准备工作并非孤立:模型配置参数决定分析输入的"物理属性",代码生成目标决定分析对象的"代码形态",属性检查器选项决定语义严格程度,建模规范决定分析能否收敛到有意义的结论。任何一环缺失,都会使Polyspace的告警集合偏离真实质量状况。
五、一份可执行的分析前检查清单
将上述内容整理为一份可直接使用的检查清单,建议在每次提交Polyspace分析前逐项确认:
| 检查项 | 确认内容 | 不满足时的风险 |
|---|---|---|
| 求解器与步长 | 离散模型使用固定步长,步长与ECU任务周期一致 | 浮点积分路径引入误报,时间判断失真 |
| 硬件字长 | char/short/int/long位宽与目标编译器一致 | 整型溢出、移位类告警与实际不符 |
| 代码生成目标 | 使用ert.tlc,语言标准与目标一致 | 代码结构与交付物不一致,规范检查失效 |
| 属性检查器 | 变量初始化、转移冲突、类型传播选项已确认 | 未初始化、不可达逻辑漏报 |
| 数据范围 | 关键数据对象已指定上下限 | 范围分析退化为保守估计,误报激增 |
| 状态机层次 | 嵌套深度与并行状态数量在可控范围 | 状态空间爆炸,分析超时或结果不完整 |
| 配置集冻结 | 分析配置与代码生成配置一致且已记录 | 告警不可复现,无法做基线比对 |