汽车功能安全-软件单元验证 (Software Unit Verification)【定义、目的、要求建议】6
文章目录
- 1 软件单元验证 (Software Unit Verification)
- 2 ISO 26262-6对单元验证的实施要求和建议
- 2.1 要求和建议
- 2.2 通俗易懂的解释与总结
- 2.3 示例
- 2.3.1 场景1:电动助力转向系统 (EPS)
- 2.3.2 场景2:自动紧急制动系统 (AEB)
- 2.3.3 示例模型验证
- 2.4 核心要点总结
1 软件单元验证 (Software Unit Verification)
通过评审、分析和测试等验证措施来验证软件单元设计和所实现的软件单元。
- 专业定义: 在ISO 26262框架下,软件单元验证是针对汽车软件中可识别的最小结构(如函数、类、模块)进行的一系列活动,旨在确保这些单元本身的设计和实现是正确、安全、符合要求且无多余内容。
- 通俗解释: 就像造汽车零件(比如一个活塞环或一个ECU里的微芯片控制程序)需要出厂前的质检一样,软件单元验证就是对构成汽车控制软件的一个个“小零件”进行严格的“出厂检验”。这个检验不是等到整台车(整个软件)都装好了才做,而是在每个“零件”刚生产出来就立刻检查,确保它们本身是靠谱的、符合图纸(需求)、没有瑕疵或者多余的东西。
- 目的:
该子阶段的目的是:
-
- 提供证据,证明软件单元设计符合分配的软件需求并适合于实现;
- 详细解释: 这个目的的核心是检查软件单元的软件需求详细实现。
- “符合分配的软件需求”:检查这个单元的设计是否精确地涵盖了它应该实现的所有功能?比如需求要求它能监测车速并在超过100km/h时发出警告,设计里有没有体现这个逻辑?
- “适合于实现”:检查这个设计在技术上是否真的能做得出来?设计得是不是足够清晰、没有歧义?有没有考虑效率和资源限制(如芯片处理能力、内存占用)?设计会不会太复杂,导致后面程序员写代码非常容易出错?
- 通俗类比解释: 检查这个软件“零件”的设计图是否正确?它应该干的事情,图上都画清楚了吗?画的图是不是太天马行空,工厂(程序员)根本做不出来?或者画的图太模糊,让不同工人理解不一样?
- 示例:
- 需求: 轮速信号采集单元需求 - “轮速传感器输入滤波后,每10ms采集一次信号。”
- 设计检查 (验证):
- 符合需求: 设计文档里是否描述了轮速传感器接口、输入滤波算法(如均值/中值滤波)、10ms定时采集的机制?
- 适合于实现: 设计的滤波算法复杂度是否在所选微控制器能负担的范围内?10ms的采集周期是否能在系统调度中稳定实现?设计的接口定义是否清晰(电压范围、数据类型)?如果设计过于复杂(例如用了超出MCU计算能力的实时滤波算法),就需要修改设计。
-
- 验证符合7.4.10和7.4.11要求的面向安全的分析所定义的安全措施是否正确实现;
- 详细解释: ISO 26262标准要求在之前的步骤(安全需求规范、架构设计)进行安全分析(如FMEA, FTA),识别出可能导致危险的软件故障模式(例如:函数计算错误返回危险值、条件判断错误导致动作误触发)。然后会定义针对这些故障的安全措施(Safety Mechanisms - SM),比如:
- 范围检查(检查输入/输出值是否在合理范围内)
- 冗余计算(相同逻辑用不同算法算两次,比较结果)
- 看门狗监控(监测程序是否卡死)
- 程序流监控(检查函数执行顺序是否正确)
- 校验和(检测内存数据是否被意外篡改)
- 安全库函数(避免使用标准库里不安全的功能,如非边界检查的数组访问)。
- 这个目的就是检查:这些计划好的安全措施(“保险丝”、“备用泵”、“报警器”)是否真真切切地在这个软件单元本身的代码里实现出来了?实现得对不对?
- 通俗类比解释: 汽车零件上如果设计了防错、保险措施(比如刹车片上的磨损报警金属片,防止你磨到极限都不知道),在出厂质检时,就要检查这个报警片是不是真的装上了、装的位置对不对、材料是不是能导电?
- 示例:
- 安全分析结论: 如果油门踏板位置传感器信号处理函数内部计算错误,可能导致输出一个100%油门的危险值。
- 定义的安全措施 (SM): 在该函数内部实施“输入范围检查”和“输出范围检查”。输入值应在0-5V(对应0%-100%油门开度)之间,输出值也应在0%-100%范围内。
- 验证 (检查代码实现): 代码审计或单元测试检查这个信号处理函数中:
- 有没有读取传感器输入电压值的代码?
- 有没有检查这个电压是否在0V到5V之间的代码?如果有电压超出,怎么处理?(比如输出默认安全值0,或者报错)
- 计算后输出油门开度百分比时,有没有检查输出是否在0%-100%之间的代码?如果超出怎么处理?(强制钳制到边界值)
- 这些检查代码本身逻辑是否正确?
-
- 提供证据,证明所实现的软件单元符合单元设计,并满足所分配的具有所要求ASIL等级的软件需求;
- 详细解释: 这个目的的核心是检查做好的“软件单元”本身的质量。
- “符合单元设计”:程序员最终写出来的代码,真的实现了前面检查过的那个软件需求详细实现吗?有没有偷工减料?有没有画蛇添足?
- “满足所分配的软件需求”:通过测试等方法证明,这个写好的“软件单元”,确实能完成它被分派的功能任务。
- “具有所要求ASIL等级的软件需求”:这个软件单元要求达到什么样的安全等级(A-D)?验证的方法和严格程度需要和这个等级匹配。越高的安全等级(比如D级),验证就要做得越多(比如更全面的测试、更严格的代码审查)。
- 通俗类比解释: 检查生产好的零件是否严格按设计图纸制造的?拿这个零件去测试(比如装在发动机试验台上跑),它能不能达到设计要求(比如提升多少马力)?对这个零件的检验标准是否够严,得看它装在车上哪个关键位置(普通零件抽检就行,刹车零件就得100%检甚至更复杂的检验)。
- 示例:
- ASIL等级: 车门锁控制单元中的“车门锁闭锁命令生成函数”,分配了ASIL B的需求。
- 设计: 该函数应接收车速(>5km/h时闭锁)和驾驶员锁门按键按下信号,输出闭锁命令。
- 验证 (单元测试):
- 测试1 (符合需求):车速=0km/h, 按键按下 -> 应无闭锁输出。(测试满足ASIL B需求中的安全锁定条件)
- 测试2 (符合需求):车速=10km/h, 按键按下 -> 应有闭锁输出。
- 测试3 (符合需求):车速=10km/h, 按键未按下 -> 应无闭锁输出。(防止误动作)
- 测试4 (符合设计):使用代码覆盖率工具(如LDRA, VectorCAST)检查测试用例是否执行了设计文档描述的逻辑分支(如车速判断、按键判断),达到ASIL B要求的覆盖率指标(如100%语句覆盖,决策覆盖)。
- 测试5 (错误注入,针对ASIL):人为注入一个故障(如让车速传感器信号线暂时断开),检查安全机制(如信号失效默认处理逻辑 - 假设车速为0)是否生效,阻止意外闭锁。这是验证故障容错能力。
-
- 提供充分证据,证明软件单元既不包含非所需功能,也不包含与功能安全相关的非所需特性
- 详细解释: 这是软件安全的特殊要求。
- “非所需功能” (Unintended Functionality):软件单元做了它完全不应该做的事情,在需求或设计里没有定义的额外功能。例如:一个只负责读取温度的代码,偷偷去修改了刹车参数。
- “与功能安全相关的非所需特性” (Non-required Functionality that impacts Safety):软件单元具有在需求或设计里没有定义的额外能力(比如一个隐藏的调试接口、一个未使用的计算变量),虽然这个能力本身不是功能,但一旦被外部利用或者异常触发,可能干扰或破坏需要满足功能安全要求的功能。
- 通俗类比解释: 检查这个零件里没有藏着后门、多余的功能开关或者不相关的危险材料!比如,一个控制音响音量的零件,里面绝对不能有能暗中控制刹车的线路;一个零件上如果有没焊上的调试接口(比如串口),这个接口如果暴露出来,被人插上电脑乱发指令,会不会让刹车失灵?那就很危险,也要避免。
- 示例:
- 非所需功能: 在车身控制模块BCM的灯光控制单元代码里,发现存在控制雨刷的逻辑。这个逻辑完全没有被BCM的需求提及,是多余的、未计划的且可能存在意外激活的风险。
- 非所需特性 (影响安全):
- 一个负责计算发动机扭矩的单元里,包含一个未启用且设计文档未提及的、能通过诊断指令秘密开启的“超增压模式”。虽然没开启,但指令接口存在,可能被恶意利用。
- 单元代码中残留了大量开发测试用的
#ifdef DEBUG
开关和对应的调试代码。其中某些调试代码如果被激活(即使意外编译),可能绕过安全机制或输出诊断信息到不安全的总线上。 - 代码中定义了全局变量
volatile int secret_key;
,但没有任何使用它的代码路径。这个变量可能被外部攻击者篡改,用作缓冲区溢出攻击的一部分,间接影响安全关键功能。
- 如何验证: 严格进行代码审查(特别是第三方代码),静态代码分析(工具检查未使用的变量、函数、潜在危险的API调用),检查编译配置(确保Debug代码被排除),安全审计(寻找隐藏接口和调试遗留)。
总结:
软件单元验证就像是给汽车软件的每一个微小“智能零件”做的一次全面“出厂前体检 + 安全检查”。其核心目的就是确保:
- 设计靠谱且可实现: 零件图纸(设计)正确且能制作。
- 安全措施到位: 图纸要求的“保险丝”、“警报器”(安全措施)真的装好且装对了。
- 成品合格且达标: 生产出的零件(代码)按图纸制造,功能正确,并通过了相应安全等级(ASIL)要求的严格测试。
- 纯净无污染: 零件里没有任何不该有的功能、后门、危险开关或多余且可能惹祸的“零件”。
只有确保这些“零件”个个都高质量、安全、纯净,由它们组装起来的整个汽车控制系统(整车软件)才更有可能是可靠、安全的。ISO 26262认为,在软件单元级别及早发现和修复问题,是构建高功能安全等级汽车软件最为有效和基础的手段。
2 ISO 26262-6对单元验证的实施要求和建议
2.1 要求和建议
ISO 26262-9原文:如果软件单元是与安全相关的,则应符合本子章条的要求。
- 解释: 这个条款的核心非常明确。它规定,汽车软件中任何一个独立的“单元”(可以理解为一个功能模块、一个类、一个函数、一个小的算法块等),只要这个单元的功能涉及到车辆安全(即如果不正确工作可能导致事故或人员伤害),那么在验证(确认这个单元是否正确实现了需求且没有缺陷)这个单元时,必须严格遵守 ISO 26262中讨论软件单元验证的具体章节,如 ISO 26262-9里规定的,所有验证方法和要求。安全相关的单元需要更严格、更全面的测试。
-
原文:注1:根据ISO 26262-1,“安全相关元素”是指单元实现安全需求,或未满足单元和其他单元共存(参见ISO 26262-9:2018第6章)的标准。
- 解释: 这里明确说明了什么样的软件单元属于“与安全相关的”。
- 情况1:实现安全需求 (主要情况):这个软件单元直接负责执行一个或多个“安全需求”。安全需求是为了防止或减轻特定危害(如意外加速、制动失效)而设定的功能或性能要求。例如,一个控制刹车压力的软件模块。
- 情况2:未满足共存标准 (潜在情况):这个软件单元本身可能不直接实现安全需求,但它必须符合与其他(安全相关或非安全相关)单元“共存”的标准。这里的“共存标准”是指:
- 独立性:一个单元的功能失效不应该轻易导致另一个(尤其是安全相关的)单元失效(避免级联失效)。
- 无干扰性:一个单元的正常运行(例如占用大量CPU资源)不能干扰其他(尤其是安全相关的)单元及时、正确地执行其功能(避免资源争夺)。
- 失效后状态定义:如果这个单元自身失效了,不能导致整个系统进入不可控的危险状态。
- 通俗关键点: 即使某个模块看起来“普通”(如一个内存管理模块或通信模块),如果它崩溃了会导致旁边的关键安全模块(如气囊控制器)也失效或无法正常工作,那么它也必须被视为“安全相关”的,因为它对整体安全构成了间接威胁。
- 解释: 这里明确说明了什么样的软件单元属于“与安全相关的”。
-
原文注2:本章要求涉及安全相关软件单元;其他软件标准(参见ISO 26262-2:2018, 5.4.5.1)可用于其他软件单元的验证。
- 解释: 强调了ISO 26262中关于软件单元验证的严格规则只强制适用于安全相关单元。对于软件中不涉及安全功能的部分(例如娱乐系统的界面动画、收音机调谐、非关键的温度显示模块等),在验证时可以不遵循ISO 26262-6的全部严苛要求。
- 替代标准: 这些非安全相关的单元可以采用更通用、要求相对低一些的软件验证标准或实践(比如A-SPICE的特定级别要求、公司内部的编码规范检查、基本的功能测试等)。ISO 26262-2的5.4.5.1节通常会指引采用行业内认可的合适标准(如A-SPICE)或公司自身定义的合格标准。
- 通俗关键点: 不同重要性的东西,检查的严格程度不同。安全核心部件要像防弹衣一样层层把关测试,收音机UI出个小Bug可能只需简单检查。
-
原文注3:对于基于模型的软件开发,实现模型的相应部件也是验证计划的对象。根据所选软件的开发过程,验证对象可以是来自该模型的代码,可以是模型本身,也可以两者都是。
- 解释: 现代汽车软件开发中,广泛使用模型(在工具如Simulink/Stateflow中建立的图形化或形式化描述)来设计软件的行为逻辑。
- “实现模型的相应部件”: 指模型中那些最终会对应生成实际代码的部分(比如某个子系统、状态机或算法函数)。
- “也是验证计划的对象”: 在MBD流程中,不能只验证最终生成的代码。模型本身(或其关键部分)也必须作为独立的验证对象,纳入验证计划进行充分检查。
- 验证对象的灵活性:
来自该模型的代码
: 有些流程选择主要验证最终自动生成的或手动调整后的代码(这是最接近最终运行形态的)。模型本身
: 有些流程选择直接在模型层面进行非常深入的验证(如形式化验证、仿真测试、模型审查),并且认为只要模型正确,生成的代码也正确(依赖于可靠的工具链)。两者都是
: 最严格的流程要求对模型本身(作为设计源头)和从该模型生成的代码(作为最终实现)都进行验证。这是最全面但成本最高的方法,适用于ASIL D等级或核心安全功能。
- 通俗关键点: 如果你是用模型设计软件的(相当于画了详细的建筑图纸和电路图):
- 你不能只等盖好房子(生成代码)才检查。图纸(模型)本身就要认真校对、模拟测试。
- 至于盖好后的检查(代码验证),可以灵活:可以只检查房子(代码),或只相信检查合格的图纸(模型),也可以图纸和房子都检查(双保险)。
- 解释: 现代汽车软件开发中,广泛使用模型(在工具如Simulink/Stateflow中建立的图形化或形式化描述)来设计软件的行为逻辑。
2.2 通俗易懂的解释与总结
想象一下汽车的软件是由成千上万个小小的“智能部件”(软件单元)组成的。
-
核心规矩:关键部件,严上加严!
- 规则: 如果一个智能部件(软件单元)负责安全大事(比如管刹车、防碰撞、控安全气囊),那么检查它的时候必须用最严格、最全面的“安检流程”(ISO 26262-6子章条的要求)!
- 为啥? 因为这些部件要是出点毛病,车就可能失控、撞车,要人命!马虎不得!
-
啥算“关键部件”(安全相关)?
- 直接负责安全: 这个部件本身干的活就是保障安全的。例:
- 刹车压力控制器:它直接决定踩刹车时有多大劲儿能停下来。
- 气囊触发器:它要在撞车瞬间准确判断该不该炸开气囊。
- 可能拖后腿/帮倒忙的: 这个部件本身不是管安全的,但如果它坏了或者乱来(比如疯狂刷屏显示歌词,占光CPU算力;或者传递错误数据),搞得旁边真正管安全的部件(比如上面说的刹车或气囊控制器)也不能好好干活甚至瘫痪,那它也得算“关键部件”!例:
- 通信管理模块:它负责不同部件间传消息。如果它挂了,刹车指令可能发不到刹车控制器那里去,这就拖了安全的后腿!
- 中央处理器任务调度模块:它负责分配CPU时间。如果它失控,把CPU都给了娱乐大屏放动画,导致刹车控制模块没得到计算时间,那就坏事了!
- 直接负责安全: 这个部件本身干的活就是保障安全的。例:
-
普通部件?可以宽松点!
- 规则: 那些不管安全的部件(比如车内大屏的UI动画控制模块、调频收音机搜台模块、氛围灯变色逻辑模块),检查的时候不用按上面那份顶级严苛的安全规范(ISO 26262-6)来。
- 怎么做? 可以用公司自己成熟的软件检查流程(比如代码规范扫描、一般功能测试),或者参考业内比较通用的质量标准(如A-SPICE),保证功能正常、不出大问题就行。毕竟这些部件出Bug一般不会直接导致车祸。
-
特殊开发方式:从图纸就开始查!
- 背景: 工程师现在经常先在电脑上用图形工具(比如Simulink)画出软件的“设计图纸”(模型),再让工具自动生成或微调成最终运行的程序(代码)。
- 规矩: 对用这种方式开发的关键安全部件,光检查生成的程序(代码)还不够!这个设计过程本身(那些图形图纸 - 模型)也必须列入安全检查计划!
- 检查什么?三种选择:
- 选择1:只查程序(代码) - 相当于只检查盖好的房子。这是最直接接触实物的方式,但可能发现不了设计思路的根本错误。
- 选择2:只查图纸(模型) - 相信只要设计图纸经过超级仔细的验证(仿真、模型级测试、形式化验证),盖出来的房子就不会有问题。前提是盖房工具必须非常靠谱。这能更早发现问题。
- 选择3:图纸和程序都查(双保险) - 图纸验证确保思路正确,程序验证确保实现完美。这需要投入最多资源,但安全等级最高!常用在最核心的救命部件上(如ASIL D功能)。
2.3 示例
2.3.1 场景1:电动助力转向系统 (EPS)
- 关键安全相关软件单元 (必须严格验证):
转向扭矩计算模块
:它根据方向盘转角和车速算出应该给方向盘多大的助力。这个模块错了,要么助力太大太灵敏(危险),要么太小掰不动方向盘(危险)。故障诊断模块
:监测电机、传感器是否异常。如果这个模块失效,发现不了严重故障可能导致突然丧失转向助力。电机控制信号生成模块
:直接控制转向电机的转动方向和力量。- 潜在安全相关单元 (需评估是否满足共存标准):
与主控制模块通信的底层驱动
:如果这个通信模块挂了,或者发送错误指令,可能导致主控模块无法控制电机。结论:需要按安全相关验证!非关键的状态显示模块
(比如显示转向模式“舒适/运动”):这个模块即使彻底失效,理论上不影响安全驾驶(驾驶员仍能转动方向盘,只是可能不知道当前模式)。结论:可以用非安全相关的普通标准验证。
2.3.2 场景2:自动紧急制动系统 (AEB)
- 关键安全相关软件单元 (必须严格验证):
目标识别与追踪算法模块
:识别前方车辆/行人并计算碰撞风险。碰撞时间/碰撞距离预测模块
(TTC/TTB):计算多久后会撞上。制动决策逻辑模块
:判断是否以及何时需要紧急制动。制动执行指令生成模块
:向制动系统发出准确的增压指令。传感器融合模块
:综合处理来自雷达、摄像头的数据。
- 潜在安全相关单元 (需评估是否满足共存标准):
目标列表管理模块
:管理所有被追踪到的目标。如果它失效导致关键目标信息丢失,决策模块就会犯错。结论:需要按安全相关验证!系统状态记录(日志)模块
:用于后续分析。它本身故障不影响实时决策和执行。结论:可以用非安全相关普通标准验证。
2.3.3 示例模型验证
- 刹车压力控制模块 (MBD):
- 模型本身验证 (选择注2或选择注3的一部分):
- 在Simulink中对该模型进行覆盖性充分的仿真测试:模拟各种车速、踏板深度、ABS/ESC介入、故障条件等,看模型计算的压力指令是否正确。
- 进行模型形式化验证:使用工具检查模型逻辑是否存在死锁、溢出、除以零等根本性问题。
- 代码生成配置检查:确保模型设置能生成安全可靠的代码。
- 生成代码验证 (选择注1或选择注3的一部分):
- 对最终生成的C代码进行静态分析 (检查编码规范、潜在缺陷)。
- 进行代码级单元测试 (与模型测试类似,但基于源代码)。
- 进行代码结构覆盖率测试 (语句覆盖、分支覆盖等 - ISO 26262要求)。
- 结论: 对于ASIL D的制动系统,很可能采用选择注3:模型和代码都要严格验证。
- 模型本身验证 (选择注2或选择注3的一部分):
2.4 核心要点总结
- 安全相关 = 严查 (ISO 26262-6)!
- 安全相关判定: 要么管安全本身,要么乱搞会害到管安全的兄弟部件。
- 非安全相关 = 常规查就行。
- 模型开发: 关键安全功能的设计模型图 (框图/流程图) 也得认真验!怎么验?取决于公司流程:单独查图、单独查代码、或者图代码一起查(最保险)!
简单说:人命关天的软件模块,就要用最顶级的安检;不影响安全的软件模块,普通安检就行了。如果用模型设计,图纸也得仔细审,不能光看盖好的房子!这就是ISO 26262为保障我们行车安全在软件层面定下的铁律。