当前位置: 首页 > news >正文

汽车功能安全-软件集成和验证(Software Integration Verification)【验证方法用例导出方法输出物】10

文章目录

  • 1 软件集成验证方法
  • 2 用例导出方法
  • 3 测试用例完整性度量标准
    • 3.1 函数覆盖率 (Function Coverage)
    • 3.2 调用覆盖率 (Function Call Coverage / Call Pair Coverage - 更准确的理解)
  • 4 验证环境要求
  • 5 工作产品-输出物

1 软件集成验证方法

表10 软件集成验证方法
在这里插入图片描述
备注:

  • a 架构层面的软件要求是基于要求测试的基础。
  • b 在软件集成验证环境中,故障注入测试是指为10.4.3所述目的而将故障引入软件,特别是测试与安全机制相关的软硬件接口的正确性。包括为测试安全机制(例如,通过破坏软件接口)而进行的任意故障注入。故障注入也可以用来验证其无干扰情况。
  • c 确保满足受到有足够容差和平均和最大处理器性能、最小或最大执行时间、存储使用情况(例如,堆栈区运行内存、程序和数据的只读内存)等特性的硬件架构设计影响的需求,确定通信线路的带宽(例如,数据总线)。
  • d 只有在目标环境上执行软件单元测试、或目标处理器的仿真器充分支持资源使用测试时,才能正确执行资源使用评估的某些方面。
  • e 这种方法需要一个能够仿真软件组件功能的模型。在这里,以同样的方式仿真模型和代码,并对彼此的结果进行比较。
  • f 静态分析是一个集合名词,包括架构分析、资源消耗分析和搜索源代码文本或与已知故障相匹配的模式的模型或符合建模或编码准则,如果尚未在单元级别验证。
  • g 基于抽象解释的静态分析是扩展静态分析的一个集合名词,包括通过添加语义信息(通过语义信息可以检查是否违反了定义的规则,如数据类型问题、未初始化变量)来扩展编译器分析树,控制流图生成和数据流分析(例如,获取与竞态条件和死锁、指针误用相关的故障)或甚至是元编译和抽象代码或模型解释,如果尚未在单元级别验证。
  1. 基于需求的测试 (Requirement-based Testing)

    • 专业定义: 这是一种结构化、系统化的测试方法,测试用例完全来源于分配给软件组件的所有相关需求规范(包括功能需求和安全需求)。其目标是验证每个需求是否在集成软件级别得到了正确实现。测试设计要确保覆盖所有需求(语句覆盖),并针对每个需求选择最有可能发现缺陷的测试输入。
    • 通俗解释: 就像是拿着集成软件的“功能清单”(需求规格书),逐条去检验软件是否都做到了清单上写的要求。比如,清单上说“当车速超过120km/h时要发出超速报警”,测试就模拟车速超过120km/h的情况,看软件是否真的让报警器响了。
    • 汽车行业示例: 对发动机控制模块(ECM)中的“自动启停”集成功能进行测试。
      • 需求: “当车速降为0公里/小时(满足其他条件如电池电量充足、空调需求不大、刹车踏板踩下等),发动机应在300毫秒内自动熄火。”
      • 测试: 在HIL(硬件在环)测试台上模拟车辆停稳(车速为0)、满足所有启停条件,验证软件发出的熄火指令是否正确、及时,并在仪表盘上显示启停激活图标。
  2. 接口测试 (Interface Testing)

    • 专业定义: 旨在验证软件组件之间以及软件与底层硬件(或其他外部实体)之间所有定义的输入/输出接口(API、函数调用、数据交换、硬件寄存器访问等)的行为是否符合接口规范。关注点是数据传递的正确性(类型、范围、值)、时序、错误处理以及边界条件。
    • 通俗解释: 检查软件模块之间“对话”有没有问题。就像检查不同部门的人交接工作(数据和指令)时,是不是传对了信息、听懂了对方的话、遇到不清楚的情况知道怎么处理(报错)。要特意检查那些“不多不少刚刚好”或者“超出正常范围”的边缘数据有没有可能导致混乱。
    • 汽车行业示例: 测试ADAS系统中的摄像头感知软件模块与目标识别软件模块之间的接口。
      • 接口规范: 摄像头模块以20ms周期输出包含车辆位置、置信度、速度的结构化数据数组。
      • 测试:
        • 传递正常有效数据,验证目标识别模块是否能正确接收、解析和使用这些数据。
        • 故意传递无效数据(如置信度为负值、速度超出最大范围、数据数组长度为0),验证识别模块是否进行正确的错误检查、拒绝该帧数据并上报错误码。
        • 测试数据延迟或丢失时(模拟通信问题),接口如何处理(如超时机制、使用上一次有效值)。
  3. 故障注入测试 (Fault Injection Testing)

    • 专业定义: 一种在系统(软件或软硬件结合)中故意引入错误或异常状况(故障)的测试方法。目的是评估软件的错误检测机制(safety mechanisms)、容错能力以及故障发生后系统的行为是否符合安全目标(如进入安全状态)。注入的故障类型包括数据错误(值翻转、超出范围、NaN)、消息丢失/重复/延迟、资源错误(内存损坏、栈溢出)、硬件信号失效等。
    • 通俗解释: “捣乱”测试!故意在软件正常运行时搞点破坏,比如把正确的车速偷偷改成999(现实中不可能的值),或者假装某个传感器突然信号中断,看看软件能否及时发现这个“谎言”或问题,并按照预设的安全方案行动(比如关掉某些功能、提示驾驶员、安全停车),而不是彻底崩溃或导致危险。
    • 汽车行业示例: 测试电子稳定控制系统(ESC)集成软件的鲁棒性。
      • 注入故障: 在车辆转弯测试时,向转向角传感器信号注入一个突然的错误偏移(模拟传感器卡滞/失效)。
      • 预期安全行为: 软件内置的故障诊断机制(DTC)应检测到传感器信号无效或不可信。
      • 安全目标验证: 系统应检测到故障,可能采取降级模式(如关闭主动侧滑控制,仅保留基本ABS功能),点亮故障灯通知驾驶员,并确保车辆不会因这个故障失去基本方向控制能力。
  4. 资源使用测试 (Resource Usage Testing)

    • 专业定义: 验证集成软件在运行时对目标硬件资源的消耗是否在设计预期的限制范围内。核心资源包括:执行时间(CPU负载), 内存占用(RAM/Rom)堆栈(stack) 使用,以及(如果适用)总线/网络带宽。确保在定义的极端工况和最坏情况执行路径(WCET)下,资源消耗不超过硬件平台的能力(如CPU主频、内存大小),以避免性能瓶颈、时序错乱、任务错过截止时间(deadline miss)甚至系统崩溃。
    • 通俗解释: 测试软件“干活”会不会“累坏”电脑(ECU)。看看软件运行起来后,用电脑CPU(处理器)忙不忙(会不会卡顿)、内存(临时记笔记的地方)够不够用、堆栈(临时工作区)挤不挤、信号传递(总线)堵不堵。重点检查在软件最忙、任务最多、要求最高的情况下,电脑资源会不会不够用。
    • 汽车行业示例: 测试智能座舱集成信息娱乐系统(IVI)。
      • 测试场景: 同时执行高强度任务:播放高分辨率电影(用GPU)、进行实时导航路线规划(CPU密集型)、通过蓝牙和蜂窝网络传输数据、响应多个触摸屏交互、处理多路摄像头视频流(环视)。
      • 测量指标:
        • CPU核心负载是否超过安全阈值(如始终 < 80% 或 90%,具体由目标平台决定)。
        • 动态内存(RAM)分配峰值是否小于可用内存(预留安全裕量)。
        • 任务的最差执行时间(WCET)是否小于其设定的调度周期/截止时间。
        • 堆栈使用峰值是否小于分配大小。
      • 结果: 确保在最恶劣但可能的使用场景下,系统不因资源耗尽而冻结、重启或出现严重延迟。
  5. 在模型和代码之间背对背对比测试 (Back-to-Back Test between Model and Code)

    • 专业定义: 这种测试方法特别适用于基于模型的开发(Model-Based Development, MBD)。其核心是比较从设计模型(如Simulink/Stateflow模型)生成的参考行为(通常通过模型在环仿真MiL产生)与最终目标代码在目标处理器或指令集模拟器上执行的实际行为是否一致。相同的输入数据会被馈送给模型仿真和运行在目标环境上的代码,比较两者的输出是否存在差异。目的是验证代码生成或手写代码的过程没有引入功能偏差。
    • 通俗解释: 就像拿建筑师做的模型效果图(设计模型仿真)和建好的真实房子(生成的代码在目标硬件跑)做对比。用同样的条件(输入)测试“模型效果图会怎么反应”(仿真输出)和“真房子会怎么反应”(代码输出),看两者行为是不是一模一样。这是验证自动生成代码(或手写实现)有没有“歪楼”,有没有偏离原始设计意图。
    • 汽车行业示例: 验证混合动力控制单元(HCU)的电机扭矩协调算法代码。
      • 输入: 一组覆盖各种工况(如纯电驱动、加速请求、再生制动)的测试向量(驾驶员需求、电池SOC、车速、变速箱档位等)。
      • MiL仿真: 将测试向量输入HCU的Simulink控制模型,记录模型计算出的期望发动机和电机扭矩指令。
      • 目标代码执行(如PIL/SIL): 将相同的测试向量输入由该模型自动生成的C代码(运行在目标处理器模拟环境或开发板上),记录代码计算出的实际扭矩指令。
      • 对比: 逐条比较MiL仿真的“期望扭矩”和PIL/SIL执行得到的“实际扭矩”,要求数值差异在允许的容差范围内(考虑到浮点计算精度差异等)。任何超差的偏差都需要仔细分析是代码生成问题、编译优化问题还是实现错误。
  6. 控制流和数据流的验证 (Control Flow and Data Flow Verification)

    • 专业定义: 这是一种静态分析技术(通常在代码层面进行,无需执行)。控制流验证检查代码的潜在执行路径是否符合逻辑和结构化编程原则(例如,每个函数都有返回路径、没有无法到达的代码、循环有明确的退出条件)。数据流验证则跟踪数据(变量)在整个程序中的“一生”:在哪里被定义(赋值)、在哪里被使用(读取)、是否在使用前已定义、定义后是否在无读取的情况下被重新定义(无效定义)、是否存在未初始化使用风险等。旨在发现可能导致未定义行为、崩溃或逻辑错误的程序结构和数据依赖问题。
    • 通俗解释: 就像拿着软件的“路线图”和“物品交接清单”检查有没有错误路线或交接失误。
      • 控制流: 检查有没有“此路不通”的死胡同代码(永远执行不到),或者有没有本该返回的路却走丢了(函数没返回值),或者循环有没有出口(不会死循环)。
      • 数据流: 跟踪每个“箱子”(变量)里的“物品”(值):箱子是哪次装进去的(赋值)?在搬动(读取使用)之前是不是忘了装东西(未初始化)?或者箱子里的东西再也没人用了(无用赋值)?有没有明明箱子是空的(值未知)却要取东西出来用(未定义值使用)?
    • 汽车行业示例:
      • 控制流问题: 验证引擎管理软件的代码。
        • 错误示例: 一个用于处理特殊故障模式的函数中,缺少对break;语句,导致switch语句中意外“穿越”执行了后续的不相关代码。
        • 工具发现: 静态分析工具报告“非结构化控制流:switch case 中缺少break可能导致非预期执行”。
      • 数据流问题: 验证车窗控制软件。
        • 错误示例: 在车窗位置计算函数中,从传感器读取的原始计数值rawCount在转换为position前,代码存在多条路径,其中一条路径可能导致在没有给position赋值的情况下,就直接使用了position来决定是否停止电机(使用未定义的值)。
        • 工具发现: 静态分析工具报告“变量 ‘position’ 可能在使用前未定义”。
  7. 静态代码分析 (Static Code Analysis)

    • 专业定义: 通过自动化工具在不实际执行代码的前提下,扫描源代码(或编译后的中间形式),基于预定义的规则集、编码规范(如MISRA C/C++, AUTOSAR C++14)和代码模式检查,发现潜在的缺陷、违反编码标准的情况和安全漏洞。SCA涵盖范围很广,包括语法错误、语义错误(控制流/数据流问题)、不安全语言结构(如指针误用)、标准合规性、可维护性问题(复制粘贴代码)等。这是开发早期发现缺陷的有效手段。
    • 通俗解释: 用“代码扫描仪”(工具)自动检查软件程序的“语法”和“书写规范”。它不会运行软件,而是像编辑用词典和语法书在检查作文:有没有错别字(语法错误)?句式结构对不对(代码结构问题)?有没有用到危险的词语表达(不安全代码)?符不符合规定的格式要求(如MISRA/AUTOSAR编码规范)?有没有抄来抄去(代码重复)?
    • 汽车行业示例: 对车身控制模块(BCM)软件的C代码进行合规检查。
      • 工具: 使用商用静态分析工具(如LDRA, Klocwork, Coverity, Polyspace)。
      • 规则集: 严格执行MISRA C:2012(汽车行业强推)和公司内部安全准则。
      • 发现问题:
        • 违反MISRA Rule 10.3:整数计算时的隐式类型提升可能导致溢出风险(如signed int8 + unsigned int32)。
        • 违反MISRA Rule 11.4:指针转换为其他类型(除 void * 外)而没有强制转换(虽然是隐式允许但规则禁止,增加风险)。
        • 数组索引越界风险(即使未发生,工具通过流分析识别边界检查缺失)。
        • 使用了被弃用或不安全的标准库函数(如 gets)。
  8. 基于抽象解释的静态分析 (Static Analysis based on Abstract Interpretation)

    • 专业解释: 静态代码分析的一种高级形式,利用抽象解释理论。它将程序变量在运行时可能的实际值域(可能是无限集合)映射/抽象为更简单的、有限的数学抽象域(例如,数值区间[最小,最大]、符号常量、布尔值)。分析工具在代码的抽象语义(而非真实语义)上执行逻辑推理,遍历所有可能的程序路径,计算出所有关键程序点在抽象域上的状态(例如,变量X在程序点P处的值总是在[0, 255]区间内)。这种方法特别擅长发现运行时错误(如算术溢出、除零、数组越界、非法指针解引用)和证明关键安全属性(如关键变量永远不会超过安全阈值),并能证明某些错误是“绝对不可能发生”的。它通常比常规静态分析误报率更低,但计算复杂度高。
    • 通俗解释: 这是静态代码分析的“数学家版”。它不关心每个变量具体是多少,而是关心它们“大概在什么范围之内”(比如,某个传感器的值肯定在0到5伏之间)。分析工具假装运行代码,但处理的是这些“大概范围”而不是具体数字,看看在逻辑上会不会出现“越界”(比如把电压值加个1000,明显超过5伏,那就报错)、除以零或者访问非法内存地址的风险。它能绝对证明在某些情况下某种危险肯定不会出现(比如证明刹车压力传感器值总是在安全范围内)。
    • 汽车行业示例: 证明安全关键的气囊控制算法不存在除零错误。
      • 代码片段: pressure_scaled = raw_pressure_value / calibration_factor;
      • 工具与抽象域: 使用Polyspace(基于抽象解释的商业工具),变量calibration_factor通过追踪其定义和赋值路径(通常是来自不可变存储的配置值),在抽象解释中被证明其值域在抽象域中是[1.0, 5.0]的固定区间(永远非零)。
      • 结果证明: 工具通过静态分析遍历所有可能的控制流路径后,可证明在除法操作之前,分母calibration_factor的值永远不可能为0。因此,这一除法操作在所有可能的运行情况下都是安全的,不会导致除零导致的控制单元崩溃。分析报告可附在安全案例中作为“永远不会发生除零错误”的证据。

总结:

ISO26262要求软件集成验证采用多样化的方法(如下图所示),因为它们各自擅长发现不同类型的缺陷:

  • 动态测试(执行代码): 基于需求测试、接口测试、故障注入测试、资源使用测试、背对背测试。这些方法通过运行代码并检查输出/行为来验证功能。
  • 静态分析(不执行代码): 控制流/数据流验证、静态代码分析(常规SCA和基于抽象解释的SCA)。这些方法通过检查代码结构和内容来发现潜在问题和违反规范的情况。

将所有这些方法结合起来,能为集成后的软件建立强大的功能和安全信心,满足汽车行业严格的ASIL等级要求。

2 用例导出方法

为了能够给软件集成验证方法(按照10.4.2选择的)定义恰当的测试用例,应使用表11所列的方法。
表11 软件集成验证用例的得出方法
在这里插入图片描述
备注:

  • a 可基于划分输入输出来识别等价类,为每个等价类选择一个有代表性的测试值。
  • b 该方法用于接口、接近边界的值、与边界交叉的值及超出范围的值。
  • c 错误猜测测试可以根据通过“经验教训”过程和专家判断收集的数据进行。
    【上述用例导出方法见之前文章】:
    汽车功能安全-软件单元验证 (Software Unit Verification)【用例导出方法、输出物】8

3 测试用例完整性度量标准

为了评估测试的完整性并确信没有非预期的功能,应确定测试用例在软件架构层面对要求的覆盖率。如果必要,应指定附加的测试用例或者提供理由。

  • 应验证作为生产发布(按照ISO 26262-2:2018, 6.4.13)一部分的嵌入式软件包含了全部已定义的函数,且仅包含不损害软件安全要求符合性的未定义函数。
    示例:未定义的函数包括用于调试或检测的代码。
    注:如果可确保这些未定义的函数不被执行,这是一种符合要求的可接受的方法。否则就要参见ISO 26262-8:2018,,第8章做变更将这些代码移除。
  • 按照ISO26262-4.4,该子章条适用于ASIL A、B、C 和 D等级:为了评估测试用例的完整性并确信没有非预期的功能,应按照表12列出的度量对结构覆盖率进行测定。如果认为结构覆盖率不充分,应定义额外的测试用例或提供可接受的理由。
    示例:结构覆盖率分析可以显示基于需求的测试用例的不足、要求的缺陷、无作用码、无效代码或非预期的功能。
    表12 软件架构层的结构覆盖率度量
    在这里插入图片描述
    a 方法1a是指软件中已执行的软件子程序或函数的百分比(定义见IEC 61508-7:2010,C.5.8)。
    b 方法1b是指软件中已执行的软件子程序或关于这些子程序或函数每次实现调用的函数的百分比。
    注 通过实现适当的软件集成和测试策略提供证据。

3.1 函数覆盖率 (Function Coverage)

  1. 定义:

    • 衡量在软件集成验证执行过程中,被测试软件项 (Software Item, 通常是编译/链接后的一个可执行模块或库) 中所有已定义的、可达的函数入口点 (Function Entry Points) 被实际调用 (执行进入) 到的百分比。
    • 核心:确保集成后的软件中存在的每个函数实体(无论是模块内部的,还是对外提供的接口 API) 在测试期间至少被触发执行过一次。它不关注函数内部逻辑是否被充分执行,只关注入口是否被“踩到”。
  2. 作用:

    • 识别“死代码” (Dead Code): 暴露那些在软件设计中被定义,但在软件项的实际运行时环境下 (根据当前的集成状态和执行路径) 永远不会被调用或访问的函数。死代码通常是冗余、错误的来源 (如未被正确更新或删除的旧函数),并可能被恶意利用。
    • 验证基本接口可达性: 确认软件项对外提供的接口函数或内部模块间要求调用的函数,在集成环境中至少有一个触发路径存在。这是接口连接性的最基本保障。
    • 满足 ISO 26262 基本要求: ISO 26262 Part 6 (表 7 和 表 8) 将 100% 的函数覆盖率指定为 ASIL A 到 ASIL D 所有等级在 软件单元测试 中的必要目标,并且强调在 软件集成验证 中也推荐达到 100% 的函数覆盖率(尤其是在无法在单元级别达到时,或者测试单元级集成时)。这是功能安全验证的门槛标准。
    • 建立进一步测试的基础: 只有当一个函数被执行了,其内部逻辑 (如分支、语句、条件) 才可能有被执行覆盖的机会。因此,100% 的函数覆盖率是实现更高级别覆盖率目标 (如语句、分支、MC/DC) 的先决条件。它为更深入的测试提供了起点。
  3. 实施过程:

    • 步骤 1: 代码编译 & 插桩 (Instrumentation):
      • 使用支持覆盖率分析的编译器、链接器和覆盖率工具。
      • 在编译、链接过程中,工具会在每个函数入口处自动插入特殊的、不可见的探针 (Probes) 或标记。插桩不改变程序功能。
    • 步骤 2: 测试用例设计 & 执行:
      • 设计和执行软件集成验证用例。这些用例应模拟软件在目标环境或测试环境中的预期行为,触发来自其他组件、消息、中断、周期任务等输入。
      • 使用插桩后的可执行文件运行这些测试用例。
    • 步骤 3: 数据收集:
      • 在测试执行期间(实时或结束后),覆盖率工具收集探针的触发信息。
      • 确定哪些函数的入口点被执行过,哪些没有。
    • 步骤 4: 覆盖率计算 & 分析:
      • 工具计算函数覆盖率:(被执行过的函数数量 / 总可执行函数数量) * 100%
      • 关键活动: 分析未覆盖的函数列表:
        • 遗漏的测试: 是否因为缺少了能够触发该函数的测试场景或输入组合?
        • 死代码确认: 该函数是否在任何合理的场景下都不会被调用?结合设计文档进行确认。
        • 环境依赖缺失: 函数是否依赖于某个外部信号、消息或硬件事件(可能未在测试环境完全模拟)?
        • 链接/配置问题: 函数是否没有被正确链接到最终的可执行映像中?
    • 步骤 5: 优化迭代:
      • 针对未覆盖的函数:
        • 如果是遗漏的测试,补充设计测试用例并重新执行。
        • 如果确认是死代码(经过设计评审确认无用途),且符合配置管理流程,则安全地移除该代码。
        • 如果存在环境依赖问题,增强测试环境或使用仿真手段。
      • 重新执行相关测试,收集数据,直到达到目标覆盖率 (ISO 26262 通常要求 100%)。
    • 步骤 6: 记录 & 证据生成:
      • 详细记录覆盖率数据、分析过程、确认的死代码、补充的测试用例及其执行结果。这是功能安全认证的关键证据。
  4. 实例:

    • 场景: 一个简单的车身控制器软件项,包含以下函数:
      • void ControlHeadlights(bool switchOn); (外部接口,控制大灯)
      • void ControlWipers(int speedLevel); (外部接口,控制雨刮器)
      • internal void CheckBatteryStatus(); (内部函数,检查电池状态)
      • internal void UpdateAmbientLightSensor(); (内部函数,更新环境光传感器值)
      • obsolete void OldDiagnosticRoutine(); (遗留诊断函数,已不再被调用)
    • 测试:
      • 测试用例 1: 发送 Headlights On 信号,验证大灯亮 → 覆盖 ControlHeadlights(true)
      • 测试用例 2: 发送 Wipers Medium 信号,验证雨刮器中速运行 → 覆盖 ControlWipers(2)
      • 测试用例 3: 模拟电池电压低事件 → 覆盖 CheckBatteryStatus() (假设事件处理中调用了它)
    • 函数覆盖率分析结果:
      • 覆盖的函数: ControlHeadlights, ControlWipers, CheckBatteryStatus
      • 未覆盖的函数: UpdateAmbientLightSensor, OldDiagnosticRoutine
      • 函数覆盖率 = 3/5 = 60%
    • 分析 & 后续:
      • UpdateAmbientLightSensor 未覆盖: 发现测试用例缺失,应补充模拟环境光变化或特定更新周期的测试。
      • OldDiagnosticRoutine 未覆盖: 设计评审确认该函数已废弃且无调用路径 → 认定为死代码。遵循变更流程将其从源代码中安全移除。
      • 移除死代码后,总可执行函数为 4 个。补充环境光更新的测试用例并执行后,UpdateAmbientLightSensor 被覆盖,函数覆盖率 → 100%。

3.2 调用覆盖率 (Function Call Coverage / Call Pair Coverage - 更准确的理解)

  1. 定义 (基于通用实践):

    • 衡量在软件集成验证执行过程中,软件项内定义的函数调用关系 (Function Call Sites / Call Pairs) 被实际执行(即该调用指令被执行,并且成功跳转到目标函数)的百分比。
    • 核心:不仅关注函数 是否被调用了 (函数覆盖率解决),更关注函数之间的特定调用路径或所有定义的调用点 是否被实际触发过。它验证的是设计预期的模块间或函数间的动态交互 (Dynamic Interaction)控制流转移 (Control Flow Transfer) 是否发生。
    • 也可以理解为一种针对接口函数的"使用完整性",验证设计规定应该调用某接口函数的代码位置是否真的发生了调用。
  2. 作用:

    • 验证接口实现完整性: 确保那些在集成架构中 应该 调用其他模块接口或内部函数的代码位置(调用点 Call Sites),在实际运行时 确实 发起了调用。例如,设计文档要求模块 A 的函数 X 在特定条件下必须调用模块 B 的接口 Y。
    • 发现控制流缺陷: 暴露逻辑错误,如错误的条件判断导致遗漏了必要的函数调用(遗漏调用),或者在不应该的情况下多出了意外的调用(多余调用)。
    • 提升集成可靠性: 确保模块间的交互路径都经过了测试。例如,验证一个任务在不同优先级抢占情况下,对其他函数的调用序列是否正确。
    • 增强接口测试深度: 是函数覆盖率的深化,不仅知道函数被调用了,还知道是在哪个具体的调用点调用的,有助于理解调用发生的上下文。
    • 识别异常调用链: 有助于发现意外的间接调用或不符合设计的调用路径(例如通过函数指针或中断跳转)。
  3. 实施过程:

    • 实施流程与函数覆盖率基本相似,但插桩和收集的焦点不同。
    • 步骤 1: 代码编译 & 插桩 (Instrumentation):
      • 覆盖率工具在源代码的每个函数调用语句 (Call Statement / Invocation Site) 处(如 funcA();, obj.methodB();)以及每个函数入口点 (Entry Point) 插入探测点。
    • 步骤 2: 测试用例设计 & 执行:
      • 与函数覆盖率相同。需要设计能模拟真实交互路径的集成测试用例。
    • 步骤 3: 数据收集:
      • 工具记录两个关键信息:
        • 每个调用点是否被执行。
        • 从调用点出发的目标函数是否被成功进入。
      • (高级工具可以记录调用者和被调用者的对应关系)。
    • 步骤 4: 覆盖率计算 & 分析:
      • 工具计算调用覆盖率:(被执行过的调用点数量 / 总的调用点数量) * 100%
      • 关键分析:
        • 未覆盖的调用点: 该调用点所在的分支或条件逻辑是否在测试中未被执行?设计预期是否失效?
        • 未到达的函数入口(即使调用点执行): 极端情况,调用点执行了,但未跳转到目标函数(如指针错误、链接错误、栈溢出等致命错误中断)。
        • 意外的调用: (需要更高级分析)是否有未被记录的调用点被执行了(如间接调用)?
    • 步骤 5: 优化迭代:
      • 针对未覆盖的调用点:分析原因。通常是设计覆盖特定逻辑分支路径的测试用例缺失。补充测试用例。
      • 如果设计评审确认某个调用点在当前场景下不应再调用,可能需要修改代码移除该调用点。
      • 重新执行测试。
    • 步骤 6: 记录 & 证据生成:
      • 记录调用覆盖率数据、未覆盖调用点分析、补充的测试用例。
  4. 实例:

    • 场景: 延续车身控制器实例。添加内部交互。
      • 函数 ControlHeadlights 内部逻辑:
        void ControlHeadlights(bool switchOn) {if (switchOn) {if (IsNightTime()) {    // 调用点 1: 调用内部函数 IsNightTimeActivateLowBeam();  // 调用点 2: 调用内部函数 ActivateLowBeam (假设它打开灯)} else {ActivateDRL();      // 调用点 3: 调用内部函数 ActivateDRL (日间行车灯)}} else {DeactivateAllLights();   // 调用点 4: 调用内部函数 DeactivateAllLights}
        }
        
      • 假设 IsNightTime() 判断逻辑依赖于 UpdateAmbientLightSensor() 更新的全局变量(存在数据流依赖)。
    • 测试用例回顾:
      • 测试用例 1 (Headlights On in daylight): 触发 ControlHeadlights(true)
        • 路径:因为模拟环境是白天,IsNightTime() 返回 false → ActivateDRL() 被调用。
        • 覆盖的调用点: IsNightTime (调用点1), ActivateDRL (调用点3)。 ActivateLowBeam (调用点2) 和 DeactivateAllLights (调用点4) 未覆盖
    • 调用覆盖率分析:
      • 总调用点: 4 个 (IsNightTime, ActivateLowBeam, ActivateDRL, DeactivateAllLights)
      • 覆盖的调用点: 2 个 (IsNightTime, ActivateDRL)
      • 调用覆盖率 = 2/4 = 50%
    • 分析 & 后续:
      • ActivateLowBeam (调用点2) 未覆盖: 缺少模拟夜间环境下打开大灯的测试用例(测试用例1仅在白天打开)。
      • DeactivateAllLights (调用点4) 未覆盖: 缺少模拟关闭大灯的测试用例(测试用例1只测试了打开)。
      • 补充测试:
        • 测试用例 4:发送 Headlights Off 信号 → 目标覆盖 DeactivateAllLights
        • 测试用例 5:模拟环境切换到夜晚,发送 Headlights On 信号 → 目标覆盖 IsNightTime (再次覆盖) 和 ActivateLowBeam (新覆盖)。
      • 补充测试执行后,调用覆盖率 → 100%。
    • 额外发现: 这个分析还揭示了之前的函数覆盖率达标(ControlHeadlights, IsNightTime, ActivateDRL 都被调用了),但内部重要的控制逻辑路径(夜间开灯、关灯)并未被充分验证。调用覆盖率暴露了更深层次的测试不足。

总结与关键点:

  • 函数覆盖率: ISO 26262 强制性基础要求 (通常是100%)。确保 所有存在的函数都被激活过,主要识别死代码,验证最基本的功能可达性。
  • 调用覆盖率 (函数调用覆盖率): ISO 26262 隐含的重要要求或高级实践 (推荐达到高目标,如 >90% 或 100%)。确保 所有设计预期的函数调用点都被执行过,主要验证模块/函数间接口的实际使用和控制流的正确性,发现遗漏或错误的调用。
  • 层级: 函数覆盖率是最低层级要求。调用覆盖率是其深化,为验证接口完整性和复杂逻辑提供了更强大的工具。两者都是更高阶覆盖率(分支、MC/DC)的重要基础。
  • 实施核心:
    • 依赖专业的代码覆盖率工具进行插桩、执行监控和数据收集。
    • 分析未覆盖项的原因至关重要,决定是测试不足还是设计/代码缺陷(如死代码、遗漏调用)。
    • 补充测试或修改代码是达到覆盖率目标的必然步骤。
    • 详细记录是满足 ISO 26262 证据要求的核心。
  • 目标: 最终目的是通过提高这些结构性的覆盖率指标尽可能暴露软件中潜在的缺陷,特别是与控制流、接口连接、死代码相关的缺陷,从而显著提高集成的软件项在目标环境中的功能安全性和可靠性

在执行软件集成验证时,应将函数覆盖率和调用覆盖率(理解为函数调用覆盖率)结合起来使用,以提供不同层次的可见性和保证。它们共同为后续的软件验证(如基于需求的测试)和整体功能安全目标达成提供坚实基础。

  • 注1:通过适当的软件工具可确定结构覆盖率。
  • 注2:在基于模型的开发中,可使用类似的模型结构覆盖度量,在模型级别执行软件架构测试。

4 验证环境要求

软件集成验证的测试环境应尽可能接近目标环境。如果集成测试没有在目标环境中执行,应分析源代码和目标代码之间的差异以及测试环境和目标环境之间的差异,来定义后续测试阶段中在目标环境中的附加测试。
注1:测试环境与目标环境之间的差异可出现在源代码或目标代码中,例如,由于不同处理器的数据字和地址字的不同位宽引起的差异。
注2:根据测试范围和集成的层级,使用适当的测试环境进行软件要素测试。这些测试环境可以是用于最终集成的目标处理器,或者是用于之前集成步骤的处理器模拟器或开发系统。
注3:软件集成验证可在不同环境中执行,例如:

  • 模型在环测试;
  • 软件在环测试;
  • 处理器在环测试;
  • 硬件在环测试。

5 工作产品-输出物

  • 软件集成验证规范(用例)
  • 软件集成验证报告(细化的
http://www.dtcms.com/a/272364.html

相关文章:

  • Java入门之JDK下载和安装
  • Thrust库介绍与使用
  • 《汇编语言:基于X86处理器》第7章 整数运算(1)
  • 机器人接入AI的发展前景:从开发者视角看技术融合与生态构建
  • JavaScript中的Screen对象:你的屏幕“身份证”
  • 城市规则管理列表实现逻辑
  • 【Note】Linux Kernel 实时技术深入:详解 PREEMPT_RT 与 Xenomai
  • 【React】MQTT + useEventBus 实现MQTT长连接以及消息分发
  • 昇腾 k8s vnpu配置
  • 在Linux中,如何使用grep awk sed find?
  • 链式二叉树数据结构(递归)
  • 自动化——bat——批量复制所选的文件
  • 微服务架构的演进:迈向云原生——Java技术栈的实践之路
  • SpringBoot整合腾讯云新一代行为验证码
  • RabbitMQ 幂等性
  • Allegro PCB 手动添加元器件全流程解析
  • expect 安装入门手册
  • 【保姆级教程】基于anji-plus-captcha实现行为验证码(滑动拼图+点选文字),前后端完整代码奉上!
  • 人工智能-基础篇-28-模型上下文协议--MCP请求示例(JSON格式,客户端代码,服务端代码等示例)
  • 开源入侵防御系统——CrowdSec
  • Linux 服务器综合性能测试脚本(优化版)结构化分析
  • 若依框架去掉Redis
  • CORESET 0 and SIB1 Scheduling in a Nutshell
  • 论文阅读笔记:VI-Net: Boosting Category-level 6D Object Pose Estimation
  • RocketMQ安装(Windows环境)
  • 上线节点固定,项目进度紧张,如何合理压缩工期
  • NGINX系统基于PHP部署应用
  • 实验作业1+整理笔记截图
  • 实训八——路由器与交换机与网线
  • 栈题解——有效的括号【LeetCode】两种方法