十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

UDS 0x28服务测试用例设计:从格式验证到通信行为确认

UDS 0x28服务测试用例设计:从格式验证到通信行为确认 收到一条需求ECU 需要支持 0x28 服务CommunicationControl请设计测试用例。这是诊断测试里非常常见的任务但很多测试工程师的第一反应是把 ISO 14229 里的请求、响应表格抄一遍写出一条“发送 02 28 03 01期望收到 02 68 03”的用例然后任务就算完成了。但这条用例真的能证明 0x28 服务实现正确吗不能。它只能证明诊断仪和 ECU 之间完成了一次“报文格式正确”的交互证明不了 ECU 是否真的把应用报文关掉了也证明不了通信行为能否在预期的时间点恢复更证明不了关闭通信后对 DTC、网络管理、其他诊断服务产生的连带影响。0x28 服务测的不是“请求和响应能对上”而是“通信行为真的被改变了吗”。这篇文章我们从协议原理、需求拆解、正常/异常用例、组合场景、自动化执行和工程化沉淀几个维度把 0x28 服务的用例设计完整走一遍。读完以后你可以根据手头的需求文档直接产出一套可追溯、可回归、可自动化的 0x28 测试用例集。1. 0x28 服务的协议本质与应用场景先明确概念。0x28 服务全称是 CommunicationControl中文叫“通信控制”是 UDSISO 14229-1协议族里用于控制 ECU 通信行为的服务。它解决的核心问题是在不改变线束、不重新上电、不刷写软件的前提下诊断仪或测试设备可以通过一条诊断请求让 ECU 动态打开或关闭某一类报文的接收和发送。这个能力看上去简单实际应用场景非常多产线下线检测时需要让 ECU 进入静默模式避免干扰产线上的其他测试。软件刷写前需要关闭应用报文减少总线负载或避免 ECU 在刷写过程中执行非预期动作。台架调试时需要单独关闭某一路 CAN 报文观察其他节点行为。整车网络问题排查时需要临时隔离某一个 ECU验证网络拓扑变化。0x28 的请求格式比较简单SID 0x28 Sub-function 控制类型 CommunicationType 通信类型其中 Sub-function 是“控制动作”CommunicationType 是“控制对象”。ISO 14229-1 中常见的子功能定义如下Sub-function含义0x00enableRxAndTx开启接收和发送0x01enableRxAndDisableTx开启接收关闭发送0x02disableRxAndEnableTx关闭接收开启发送0x03disableRxAndTx关闭接收和发送0x04enableRxAndDisableTx with enhanced address info0x05disableRxAndEnableTx with enhanced address infoCommunicationType 是一个字节按位定义控制对象。常见定义如下Bit含义0 (0x01)Application应用报文1 (0x02)Diagnostic诊断报文2 (0x04)Network Management网络管理报文注意这些 bit 可以组合例如0x05表示同时控制“应用报文 网络管理报文”。另外不同主机厂的项目规范可能会裁剪这个字节的可用组合这也是后面用例设计时一定要查阅需求文档的原因。肯定响应的格式是SID 0x40 0x68 Sub-function例如请求28 03 01 响应68 03如果请求无法执行ECU 会返回否定响应7F 28 NRC常见的 NRC 包括0x13、0x22、0x31、0x33、0x7E等后面会详细展开。到这里我们对 0x28 的协议层已经有了一个完整图像。接下来要讨论的问题是为什么很多用例设计会漏测漏在哪里。2. 0x28 服务用例设计的常见误区我见过很多 0x28 相关测试用例问题非常集中。先总结成五个误区你可以对号入座。2.1 误区一格式通了就算测完典型的低质量用例是这样的步骤 1发送 28 03 01 预期收到 68 03这条用例只验证了请求和响应格式。它没有验证应用报文到底停了没有停的是发送还是接收停了之后怎么恢复恢复后应用报文是否按原来的周期继续发送真正的 0x28 测试预期结果一定要落到“总线上的实际报文行为”。比如预期ECU 发送 0x68 03 响应 预期在收到响应后的 100ms 内总线上不再出现 ECU 的应用报文 ID 0x1A0 预期执行恢复请求后应用报文 ID 0x1A0 恢复发送周期为 20ms。只有这样的用例才能证明 ECU 的行为符合需求。2.2 误区二不区分物理寻址和功能寻址诊断请求可以走物理寻址也可以走功能寻址。0x28 服务在两种寻址方式下ECU 的处理逻辑可能完全不同。例如某 ECU 在需求里明确规定“0x28 仅支持物理寻址功能寻址时返回否定响应”那么测试用例必须有物理寻址请求期待正常响应。功能寻址请求期待否定响应并且要明确 NRC 值。如果只测物理寻址功能寻址这条逻辑就没有覆盖到。2.3 误区三忽略 sub-function 和 communicationType 的合法组合前面提到Protocol 里定义了0x00~0x05的子功能0x01/0x02/0x04的 communicationType 可以组合。但 ECU 实现往往只支持需求文档里列出的组合。举个例子需求只支持0x03 控制应用报文但测试用例却把0x00~0x05全部列了一遍认为所有组合都应该返回肯定响应。这就属于不看需求只抄协议。反过来如果需求里明确支持0x00开启收发和0x03关闭收发用例却没有覆盖0x00恢复那同样漏测。2.4 误区四不验证恢复机制0x28 关闭通信之后必须有恢复手段。常见的恢复条件包括执行0x28 0x00 0x01重新开启应用报文的收发。ECU 执行0x11重启。诊断会话切换。进入特定状态例如编程会话。很多用例只测“关闭”不测“恢复”结果在台架或实车上执行完关闭操作后ECU 一直处于静默状态测试系统误以为 ECU 故障。恢复用例比关闭用例更重要因为恢复失败意味着 ECU 直接“失联”。2.5 误区五不考虑对 DTC 和网络管理的影响关闭应用报文后ECU 可能因为缺少正常通信而报 DTC或者网络管理报文停止导致其他节点认为该节点“缺席”。这些结果并不一定是缺陷如果需求文档里明确写了“关闭通信期间需要禁止 DTC 置位”但 ECU 实际置位了那你设计用例时如果没有 DTC 维度就发现不了这个问题。这一节的结论很明确0x28 用例设计的核心维度是“行为、交互、恢复”。接下来我们看怎么从需求文档里把这三个维度的测试点拆出来。3. 从需求文档中拆解 0x28 测试点的方法拿到需求文档之后不要急着写用例。先按照下面五个问题去拆解拆完以后测试点就自然出来了。3.1 问题一支持范围是什么先确认需求里写了什么支持的服务子功能有哪些支持的 communicationType 有哪些支持物理寻址还是功能寻址在哪个诊断会话下支持这些信息可以从“诊断需求表”或“诊断规范”里找到。如果需求文档没写就需要找诊断负责人确认而不是自己猜。3.2 问题二控制对象是什么明确 0x28 控制的是应用报文、诊断报文还是网络管理报文。这个字段会直接影响测试时观察哪一类报文。3.3 问题三前置条件是什么执行 0x28 之前ECU 需要处于什么状态是否需要在扩展会话是否需要安全解锁是否需要车辆处于某种工况这些前置条件必须写进用例里否则用例不可复现。3.4 问题四恢复条件是什么需求文档里必须写清楚恢复机制通过 0x28 0x00 恢复通过 ECU 重启恢复通过会话切换恢复恢复时间有没有要求3.5 问题五DTC 和事件行为是什么关闭通信后ECU 是否应该禁止 DTC 置位是否应该记录诊断事件这些也要拆出来。下面用一个假设的需求条目来做一次完整拆解。注意这是一个示例实际项目以你的需求文档为准。假设需求条目如下ECU 在扩展会话且安全解锁状态下接收到物理寻址的 0x28 服务 sub-function 0x03communicationType 0x01 时 应停止发送应用报文并返回肯定响应。 ECU 通过 0x11 重启后应恢复应用报文发送。 在默认会话下收到该请求应返回 NRC 0x22。 该服务不支持功能寻址。拆解成测试点的结果如下需求属性需求内容对应测试点前置会话扩展会话默认会话下测试 0x28预期 0x22安全等级需要安全解锁未解锁状态下发送预期 0x33寻址方式仅物理寻址功能寻址发送预期否定响应控制动作0x03 disableRxAndTx验证应用报文停止发送和接收控制对象0x01 Application关闭后应用报文不再出现肯定响应返回 0x68 0x03验证 SID 和 sub-function恢复机制ECU 重启后恢复执行 0x11验证应用报文恢复发送这样拆完以后一条需求可以映射出至少十几条测试用例。接下来的两个章节就是把这些测试点组织成正常场景用例和异常场景用例。4. 0x28 服务正常场景用例设计正常场景用例的定位是建立“请求-行为-恢复”的基线。也就是说在合法前提条件下ECU 应该正确完成通信控制。先给一套推荐用例编号规范TC_028_N_xxxNormal正常场景。TC_028_I_xxxInvalid非法参数预期否定响应。TC_028_B_xxxBoundary边界值。TC_028_C_xxxCombination组合场景。下面是一组核心正常场景用例覆盖了最常见的 sub-function 和 communicationType 组合。用例编号前置条件测试步骤预期结果TC_028_N_001扩展会话安全解锁发送 28 00 01收到 68 00应用报文正常收发TC_028_N_002扩展会话安全解锁发送 28 01 01收到 68 01应用报文接收正常、发送停止TC_028_N_003扩展会话安全解锁发送 28 02 01收到 68 02应用报文发送正常、接收停止TC_028_N_004扩展会话安全解锁发送 28 03 01收到 68 03应用报文收发停止TC_028_N_005扩展会话安全解锁先发送 28 03 01再发送 28 00 01恢复后应用报文恢复收发TC_028_N_006默认会话发送 28 00 02按需求返回肯定响应或 NRC 0x22以项目规范为准TC_028_N_007扩展会话安全解锁发送 28 03 05控制对象为应用报文 网络管理报文时两类报文均停止TC_028_N_008扩展会话安全解锁连续发送 28 03 01 两次第二次请求同样返回肯定响应行为保持停止状态注意几点第一每条用例的“预期结果”不能只写响应帧。表里的 “应用报文恢复收发” 这类描述执行时需要通过总线工具观察实际报文比如过滤0x1A0这个 ID 的周期报文。第二TC_028_N_006这类用例如果需求文档里没有明确默认会话的行为就不要拍脑袋写预期。正确做法是在用例里标注“待需求确认”。第三如果 0x28 支持多个 communicationType 组合那么正常用例还要覆盖组合值。例如0x01 | 0x02 0x03表示同时控制应用报文和诊断报文这时候预期结果要分别验证两类报文的状态。下面把TC_028_N_004和TC_028_N_005展开成详细步骤因为这两条用例最能体现“行为验证”的思路。TC_028_N_004详细步骤确认 ECU 处于扩展会话并已完成安全解锁。在总线上确认能够收到 ECU 周期性发送的应用报文 ID0x1A0。发送诊断请求28 03 01。等待并接收 ECU 的诊断响应。记录响应帧断言 SID 为0x68sub-function 为0x03。在响应后的 500ms 内持续监听总线上0x1A0报文断言不再收到该报文。TC_028_N_005详细步骤先执行TC_028_N_004确认应用报文已停止。发送诊断请求28 00 01。等待并接收 ECU 的诊断响应。记录响应帧断言 SID 为0x68sub-function 为0x00。在响应后的 500ms 内持续监听总线上0x1A0报文断言该报文恢复发送且发送周期符合需求定义。正常场景用例的重点是“可观察”。如果你写的预期结果里没有总线报文行为那这条用例的测试强度就还差一层。5. 0x28 服务异常与边界用例设计异常用例的目标是验证 ECU 的防御能力请求不合法时ECU 能不能正确拒绝返回的 NRC 是否符合协议和项目规范。0x28 服务最常见的异常场景集中在以下五个维度。5.1 无效 sub-function如果把0x06、0xFF这类协议保留值或未支持值作为 sub-function 发送ECU 应该返回否定响应。常见的期望 NRC 是0x7ESubFunctionNotSupported或0x31RequestOutOfRange具体以项目规范为准。5.2 无效 communicationTypecommunicationType 的保留 bit 被置为 1例如发送28 03 80ECU 需要判断该值无效返回否定响应。这里要特别关注有些 ECU 只校验0x01/0x02/0x04这几个 bit其他 bit 忽略有些 ECU 则严格校验全字节。设计用例前必须查看需求文档对 communicationType 校验范围的定义。5.3 前置条件不满足这是异常用例里最容易被忽略的一类。默认会话下发送 0x28如果需求要求扩展会话才能执行则预期 NRC0x22。未解锁状态下发送需要安全等级的 0x28预期 NRC0x33。如果需求对寻址方式有限制功能寻址发送时也要有明确的否定响应预期。5.4 报文长度错误0x28 请求的长度是 3 个字节SID sub-function communicationType。如果发送28 03 // 缺少 communicationType 28 03 01 FF // 多出一个字节ECU 应该返回0x13IncorrectMessageLengthOrInvalidFormat。注意某些 ECU 在收到“SID 正确但长度错误”的请求时会执行长度校验并返回0x13也有 ECU 先判断 sub-function再判断长度返回的 NRC 可能不同。所以长度错误用例的预期 NRC 需要结合实际实现确认。5.5 重复请求与顺序异常重复请求不一定都是正常场景。比如ECU 当前已经处于“应用报文关闭”状态再次发送28 03 01有些 ECU 会幂等地返回肯定响应有些则会返回0x22。这就是一个典型的需求不明确点应该列为待确认用例。再比如先发送28 01 01禁止发送不发送任何恢复请求直接切换会话。切换后 ECU 是保持原状态还是恢复默认通信状态这类用例必须在整车或台架上实际验证不能靠猜。下面是一组常用的异常用例表用例编号前置条件测试步骤预期 NRCTC_028_I_001扩展会话安全解锁发送 28 06 010x7E 或 0x31TC_028_I_002扩展会话安全解锁发送 28 FF 010x7E 或 0x31TC_028_I_003扩展会话安全解锁发送 28 03 800x31TC_028_I_004默认会话发送 28 03 01若需求要求扩展会话0x22TC_028_I_005扩展会话未解锁发送 28 03 01若需求要求安全等级0x33TC_028_I_006扩展会话安全解锁发送 28 030x13TC_028_I_007扩展会话安全解锁发送 28 03 01 FF0x13TC_028_B_001扩展会话安全解锁发送 28 03 00communicationType 无效值0x31有一类边界用例特别值得写communicationType 0x00。ISO 14229 里0x00一般不是合法控制对象但不同 OEM 的裁剪可能不同。这种“协议没明确、规范可能变”的边界值用例里一定要保留并在评审时和诊断工程师确认最终预期。6. 0x28 服务与其他诊断服务的组合场景用例0x28 在真实项目里不会孤立运行它总是和会话控制、安全访问、ECU 重启、DTC 设置等服务组合出现。组合场景用例是故障排查价值最高的用例也是最能体现测试深度的部分。6.1 0x28 与 0x10 会话控制组合典型场景ECU 在扩展会话下执行28 03 01应用报文停发。测试直接切换到编程会话检查应用报文是否仍然停发。再从编程会话切回扩展会话检查 0x28 的通信控制状态是否保持。这类用例验证的是会话切换对 0x28 状态的影响。不同 ECU 的处理策略不同有的切换会话会清除通信控制状态有的则保持原状态。6.2 0x28 与 0x27 安全访问组合如果 0x28 需要安全等级未解锁时发送28 03 01预期0x33。执行 0x27 解锁后发送28 03 01预期成功。解锁后等待 SecurityAccess 超时锁定再发送28 03 01预期返回0x33。6.3 0x28 与 0x11 ECU 重启组合这是最常用的恢复手段必须覆盖执行28 03 01应用报文停发。执行11 01ECU 重启。重启后检查应用报文是否恢复发送。这里有一个容易被忽略的细节重启后0x28 的“关闭状态”是否被清除如果 ECU 重启后依然保持关闭状态那说明 ECU 把通信控制状态保存到了非易失存储行为是否符合需求需要和开发确认。6.4 0x28 与 0x85 DTC 设置组合关闭应用报文后ECU 可能因为缺少内部通信或外部报文而置位 DTC。组合用例应验证需求允许置 DTC则确认 DTC 状态置位。需求禁止置 DTC则确认 DTC 状态未改变。这类用例在实车测试中尤其重要因为 DTC 误置位会直接影响售后诊断。6.5 0x28 与 0x22 数据读取组合如果 communicationType 只关闭了应用报文诊断报文应该仍然可用。组合用例可以验证执行28 03 01后发送22 F1 90读取数据确认 ECU 仍然响应。如果 communicationType 同时包含了0x02则执行22 F1 90时预期无响应或行为变化。6.6 0x28 与网络管理组合当 communicationType 包含0x04网络管理时0x28 会关闭网络管理报文。这时候整车网络里的其他节点会认为该 ECU 掉线可能触发网络管理相关的 DTC。组合用例应验证关闭网络管理报文后其他节点是否在预期时间内检测到该节点缺席。恢复网络管理报文后网络是否恢复正常状态。这一组组合场景核心要点是“时序”。每条用例都要清楚写出先执行什么、等待多久、再执行什么。7. 0x28 服务测试环境搭建与自动化示例设计完用例之后就要考虑执行。0x28 服务测试离不开总线工具。这里以 CANoe / CAPL 和 python-can 为例给出可落地的自动化示例。7.1 环境准备硬件支持 CAN 的接口卡例如 Vector、PCAN、ValueCAN 等。软件CANoe / CANalyzer或 Python 3 python-can。总线数据库需要包含测试对象的报文 ID、周期、信号定义。诊断数据库如果使用诊断功能建议提前导入 CDD/ODX。测试对象ECU 或台架确保 CAN 通道、终端电阻、波特率正确。这里给出一个约定测试 ECU 的诊断请求 ID 为0x7E0响应 ID 为0x7E8应用报文 ID 为0x1A0波特率 500kbps。实际项目请按真实 DBC 和诊断数据库修改。7.2 CAPL 示例发送 0x28 请求并验证响应下面是一个简化版 CAPL 测试用例。它的逻辑是发送28 03 01等待响应判断 SID 和 sub-function并检查应用报文是否停止。// CAPL 示例0x28 服务发送与响应验证 variables { const int DIAG_REQ_ID 0x7E0; const int DIAG_RES_ID 0x7E8; const int APP_MSG_ID 0x1A0; message DIAG_REQ_ID reqMsg; message DIAG_RES_ID resMsg; int appMsgReceived 0; } // 发送 0x28 请求sub-function0x03, communicationType0x01 void SendCommunicationControlRequest() { reqMsg.byte(0) 0x03; // PCI单帧数据长度 3 reqMsg.byte(1) 0x28; // SIDCommunicationControl reqMsg.byte(2) 0x03; // sub-functiondisableRxAndTx reqMsg.byte(3) 0x01; // communicationTypeApplication output(reqMsg); } // 统计应用报文是否出现 on message APP_MSG_ID { appMsgReceived 1; } testcase TC_028_N_004_CAPL() { appMsgReceived 0; SendCommunicationControlRequest(); // 等待诊断响应 if (testWaitForMessage(DIAG_RES_ID, 1000)) { if (resMsg.byte(1)
返回列表