ARTICLE DETAIL

资讯详情

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

UDS 0x3E服务测试用例设计:从需求到执行

UDS 0x3E服务测试用例设计:从需求到执行 网络诊断测试中0x3E服务TesterPresent是最容易被低估的服务之一。很多测试人员把它当作“周期性发个心跳报文”直到刷写失败、会话回退、总线上出现大量意外响应后才意识到0x3E服务用例设计需要从需求出发而不是从工具面板出发。这篇文章围绕UDS诊断协议中0x3E会话保持服务的需求拆解、用例设计、执行验证和常见问题排查展开适合诊断测试工程师、ECU嵌入式软件工程师以及刚接触UDS测试的入门人员。读完你可以直接拿走一套可复用的0x3E用例设计清单也能理解为什么这个“简单服务”在刷写、安全访问和会话切换场景里如此关键。1. 先理解0x3E服务在诊断链路中的位置1.1 为什么需要TesterPresentUDSUnified Diagnostic Services统一诊断服务是ISO 14229定义的一套诊断服务规范。ECU在诊断过程中并不总是停留在默认会话很多标定、刷写、安全访问操作必须在非默认会话中执行。为了防止ECU长期停留在编程会话或扩展会话又为了防止测试仪断电、通讯异常时ECU一直占用诊断资源ISO 14229规定ECU在非默认会话中启动一个S3Server超时定时器。0x3E服务就是用来重置S3Server定时器的。Tester周期性地发送TesterPresent请求ECU收到后认为诊断连接仍然存在继续停留在当前会话如果超过S3Server时间没有收到任何TesterPresent请求ECU自动回到默认会话。这个机制决定了0x3E服务不是“发不发都能跑”的辅助功能而是诊断会话状态机里的心跳信号。很多测试人员只验证“发了0x3E有没有响应”忽略了最关键的行为会话是否因为0x3E而保持以及停止发送后是否在指定时间回退到默认会话。这两点才是需求背后真正要保护的产品行为。1.2 0x3E请求格式、响应格式和NRC0x3E服务请求报文固定为2字节字段字节数示例值说明SID10x3E服务标识Sub-function10x00 / 0x01 / 0x80子功能参数正响应的SID是请求SID加0x40即0x3E 0x40 0x7E。响应内容通常会回显子功能值请求02 3E 01 正响应03 7E 01 00如果ECU认为请求不合法会返回负响应格式为SID加0x40的补码即0x7F然后回显请求SID和NRC请求02 3E 02 负响应03 7F 3E 120x3E服务常见的NRC如下NRC含义典型触发条件0x11服务不支持ECU未配置0x3E服务或SID错误0x12子功能不支持Sub-function不在ECU支持列表中0x13报文长度错误或格式无效请求长度不是2字节在AUTOSAR架构中0x3E由Dcm模块的DcmDslProtocol族处理。Dcm模块内部维护S3Server定时器收到TesterPresent请求后重置定时器超过S3Server时间则触发会话状态机回到默认会话。这意味着0x3E的行为与ECU的会话状态机强相关测试用例必须把“会话状态”作为前置条件和预期的一部分。1.3 抑制正响应位与功能寻址的常见约定0x3E的子功能参数有一个特殊位即bit7的suppressPosRspMsgIndicationBit。按ISO 14229-1通用规则bit7为1时抑制正响应bit7为0时发送正响应。实际项目中OEM诊断规范往往进一步简化为0x00常用于周期心跳ECU不返回正响应用于降低总线负载。0x01常用于链路验证ECU必须返回正响应。0x80按ISO 14229-1通用抑制位实现的等效形式也用于周期心跳。这里要特别提醒不同OEM对0x00和0x01的定义并不完全一致。有的ECU按标准把0x00定义为“需要响应”把0x80定义为“抑制响应”。设计用例前必须先读ECU的诊断规范或AUTOSAR Dcm配置确认支持哪些子功能值以及各自的响应行为。下面所有用例都以“0x00抑制正响应、0x01返回正响应”的常见OEM约定为例实际项目中按需求文档调整即可。功能寻址场景下TesterPresent通常使用抑制正响应的子功能。因为功能寻址会被多个ECU同时接收如果每个ECU都返回正响应总线上会瞬间出现大量响应帧造成仲裁冲突和响应风暴。因此功能寻址加0x00是0x3E测试里的经典组合。2. 从需求文档拆解0x3E服务测试要点2.1 一份典型需求里会写什么0x3E相关的需求通常不会只有一句话。一个完整的诊断需求会包含服务ID0x3E。支持的子功能列表例如支持0x00和0x01。各子功能的响应行为是否需要返回正响应。S3Server超时时间例如5000ms。支持的诊断会话默认会话、编程会话、扩展会话是否都支持。支持的寻址方式物理寻址、功能寻址。与其他服务的配合要求切换会话后是否仍需要发送安全访问失败后是否受影响。测试人员最容易犯的错误是只把“SID、子功能、响应”抄进用例遗漏会话和寻址维度。结果就是用例只有两条发0x3E 00、发0x3E 01根本覆盖不到ECU真实使用场景。2.2 把需求拆成功能矩阵建议把0x3E需求先转成一张功能矩阵横向是“会话、寻址、子功能、响应行为、超时”纵向是不同组合。例如会话寻址子功能是否响应S3Server影响优先级默认会话物理寻址0x00否无超时动作P2默认会话物理寻址0x01是无超时动作P2扩展会话物理寻址0x00否重置S3ServerP1扩展会话物理寻址0x01是重置S3ServerP1编程会话物理寻址0x00否重置S3ServerP1编程会话功能寻址0x00否重置S3ServerP1编程会话功能寻址0x01视规范可能不应答P2这张矩阵是后续用例设计的主干。每个组合至少派生一条正常用例再根据优先级派生异常用例。2.3 确定优先级和风险矩阵出来后需要标记优先级。0x3E用例优先级判断原则是看“这个组合是否直接影响诊断主流程”。刷写流程中的编程会话保活、扩展会话下的周期心跳、超时回退到默认会话属于P1一旦出问题会直接影响产线刷写、售后诊断和安全访问。默认会话下单纯验证正响应属于P2因为默认会话没有会话回退风险验证的是ECU是否实现了协议。非法子功能和长度异常属于P2或P3主要用于健壮性检查不影响核心流程。优先级决定执行顺序。在测试时间有限时先跑P1组合再跑P2P3可以做成自动化回归用例。3. 测试环境准备工具链、参数和最小请求库3.1 工具链选择0x3E测试可以用CANoe、CANalyzer、PCAN加脚本甚至直接用诊断仪。不同工具适合不同阶段工具适用场景优点注意点CANoe自动化测试、CAPL脚本、总线数据分析工程能力最完整可模拟节点成本高需要授权PCAN python-can脚本化快速验证轻量、可脚本化需要自己处理CAN和ISO-TP诊断仪手动功能验证配置简单不适合周期发送和批量回归学习环境推荐PCAN或USB-CAN卡配合python-can代码量小能快速验证0x3E请求和响应。生产环境推荐CANoe或自研自动化测试平台重点在于测试用例可回归、日志可追溯。3.2 关键参数确认S3Server、会话ID和寻址ID动手写用例前必须从需求或ECU诊断规范中确认以下参数参数示例值确认方法S3Server超时时间5000ms诊断规范或Dcm配置支持的子功能0x00、0x01诊断规范或CDD文件物理请求CAN ID0x7E0诊断调查表物理响应CAN ID0x7E8诊断调查表功能请求CAN ID0x7DF诊断调查表支持的会话列表0x01、0x02、0x030x10服务需求各子功能是否需要响应0x00不响应0x01响应诊断规范这些参数中S3Server最容易被忽略。有的ECU把S3Server配置成3000ms有的配置成10000ms如果测试脚本固定用1000ms周期发送那结果只能说明脚本没问题不能判断ECU的边界行为是否正确。3.3 构造最小请求响应库在正式设计用例前先准备一组最小请求报文方便手动验证和脚本引用02 3E 00 // TesterPresent抑制正响应 02 3E 01 // TesterPresent请求正响应 02 3E 02 // 非法子功能示例 03 3E 01 00 // 长度错误示例3字节请求 01 3E // 长度错误示例1字节请求对应正常预期02 3E 00 // 无正响应 02 3E 01 // 正响应 03 7E 01 00 02 3E 02 // 负响应 03 7F 3E 12 03 3E 01 00 // 负响应 03 7F 3E 13 01 3E // 负响应 03 7F 3E 13严格来说负响应NRC以ECU实现为准如果ECU对长度错误返回0x13之外的值以实际实现和诊断规范为准。4. 正常路径用例设计会话保持与正响应4.1 周期发送0x3E保持会话这是0x3E最核心的用例。前置条件是把ECU切换到扩展会话或编程会话然后按固定周期发送TesterPresent请求持续一定时间观察ECU是否一直停留在当前会话。典型的用例设计如下用例编号前置条件操作步骤预期结果优先级TP3E_N01扩展会话以1000ms周期发送0x3E 00持续60s无正响应但ECU始终留在扩展会话P1TP3E_N02编程会话以1000ms周期发送0x3E 00持续60s无正响应但ECU始终留在编程会话P1TP3E_N03扩展会话以500ms周期发送0x3E 01持续60s每次都有正响应0x7E 01会话保持P1周期选择需要参考S3Server。最常用的经验值是S3Server/5到S3Server/2比如S3Server为5000ms时TesterPresent周期取1000ms比较稳妥。周期过长会制造超时回退风险周期过短会增加总线负载。执行这一组用例时也要记录实际报文时间戳确认发送间隔没有因为总线繁忙而被拉大。4.2 子功能0x01正响应校验0x01用于链路验证ECU收到后必须返回正响应。测试点包括响应SID、响应长度、子功能回显。预期响应请求02 3E 01 正响应03 7E 01 00用例设计用例编号前置条件操作步骤预期结果优先级TP3E_N04默认会话发送0x3E 01收到0x7E 01正响应响应时间满足诊断规范P2TP3E_N05扩展会话发送0x3E 01收到0x7E 01正响应会话保持P1TP3E_N06编程会话发送0x3E 01收到0x7E 01正响应会话保持P1响应时间也是断言点。诊断规范通常要求ECU在50ms或100ms内返回正响应具体以项目需求为准。脚本中应增加响应超时断言而不是只判断“最终收到了”。4.3 功能寻址下不回响应的校验功能寻址会同时唤醒多个ECU如果每个ECU都响应0x7E总线上会出现大量响应帧。因此功能寻址的TesterPresent通常使用抑制正响应的0x00子功能。用例编号前置条件操作步骤预期结果优先级TP3E_N07扩展会话以功能寻址CAN ID发送0x3E 00总线上无0x7E响应所有ECU保持当前会话P1TP3E_N08编程会话以功能寻址CAN ID发送0x3E 00总线上无0x7E响应所有ECU保持编程会话P1这个用例容易踩坑如果ECU配置错误或测试脚本误用了0x01子功能会出现多个ECU同时响应导致总线错误。执行时要在CAN trace里检查0x7E响应帧是否出现。4.4 超时回落到默认会话停止发送TesterPresent后ECU必须在一定时间内回到默认会话。这是0x3E用例里最容易被漏掉、也最能发现时序问题的场景。用例编号前置条件操作步骤预期结果优先级TP3E_N09扩展会话停止发送0x3E等待超过S3Server如6000msECU回到默认会话可被0x10服务查询会话确认P1TP3E_N10编程会话停止发送0x3E等待超过S3ServerECU回到默认会话后续刷写请求返回条件错误NRC或会话错误P1验证回落是否发生最直接的方法是发送0x10 01读取当前会话看是0x01默认会话还是0x02/0x03。也可以在回落前执行一个只允许默认会话执行的服务来反向验证。S3Server超时边界本身还要单独测见第5章的边界用例。5. 异常路径用例设计输入、参数和边界5.1 非法子功能NRC 0x12ECU必须拒绝不支持的子功能。例如规范只支持0x00和0x01发送0x02、0x03、0x7F时ECU应返回负响应0x7F 3E 12。用例编号前置条件操作步骤预期结果优先级TP3E_E01扩展会话发送0x3E 02负响应0x7F 3E 12会话保持P2TP3E_E02扩展会话发送0x3E 7F负响应0x7F 3E 12会话保持P2TP3E_E03扩展会话发送0x3E FF负响应0x7F 3E 12会话保持P3需要注意发送非法子功能后S3Server是否被重置取决于ECU实现。有些ECU在解析服务时就重置定时器有些则在功能校验通过后才重置。这个行为要写入预期否则后续用例会产生歧义。5.2 报文长度错误NRC 0x130x3E请求固定长度为2字节。长度不对时ECU应返回0x13错误。用例编号前置条件操作步骤预期结果优先级TP3E_E04扩展会话发送01 3E长度1字节负响应0x7F 3E 13P2TP3E_E05扩展会话发送03 3E 01 00长度3字节负响应0x7F 3E 13P2TP3E_E06扩展会话发送02 3ESID后无子功能负响应0x7F 3E 13P3长度错误用例看起来简单但在CAN TP传输中多字节请求可能涉及连续帧和流控制。如果ECU的Dcm对ISO-TP层多帧解析有问题这个用例能提前暴露问题。5.3 不支持SIDNRC 0x11虽然0x3E基本是所有ECU都实现的服务但健壮性测试里仍然可以验证错误SID的行为。用例编号前置条件操作步骤预期结果优先级TP3E_E07扩展会话发送02 3F 00负响应0x7F 3F 11P3TP3E_E08扩展会话发送02 3D 01负响应0x7F 3D 11P3这个用例在真实ECU上要小心有些ECU对未支持SID的负响应不一定只回0x11也可能回0x31或其他NRC以诊断规范为准。5.4 边界时间抖动和跨超时点S3Server超时是时间敏感逻辑正常路径只验证“超时后会回落”还不够还需要覆盖临界时间点。用例编号前置条件操作步骤预期结果优先级TP3E_E09扩展会话S3Server5000ms在4990ms时发送0x3E 00会话保持不回默认会话P1TP3E_E10扩展会话S3Server5000ms在5010ms时发送0x3E 00如果已到超时ECU可能已回默认会话P1TP3E_E11扩展会话以1500ms周期发送0x3E 00持续30s出现随机抖动但周期始终小于S3Server会话保持P2临界时间用例需要精确控制发送时刻最好用脚本实现。手动操作很难卡准4990ms和5010ms这两个点。6. 跨服务交互用例设计刷写、安全访问和会话切换6.1 不同诊断会话下的0x3E支持0x3E必须在默认会话、扩展会话、编程会话中都可用并且行为一致。设计用例时把同一个请求分别放到三个会话下执行。用例编号前置条件操作步骤预期结果优先级TP3E_I01默认会话发送0x3E 01正响应0x7E 01P2TP3E_I02扩展会话发送0x3E 01正响应0x7E 01P1TP3E_I03编程会话发送0x3E 01正响应0x7E 01P1如果某个会话下0x3E不响应或返回NRC 0x12说明Dcm配置存在缺陷。这个用例往往能很快定位刷写失败问题。6.2 与0x10、0x27、0x28的时序配合0x3E不是独立服务它必须与0x10会话切换、0x27安全访问、0x28通信控制配合使用。推荐设计以下交互用例用例编号前置条件操作步骤预期结果优先级TP3E_I04默认会话0x10 02进入扩展会话后持续发送0x3E 01会话保持扩展会话正响应正常P1TP3E_I05扩展会话0x27安全访问成功后持续发送0x3E 00安全状态不被重置或按规范失效P1TP3E_I06扩展会话0x28 03关闭应用通信后持续发送0x3E 01正响应正常会话保持P1TP3E_I07默认会话0x10 03进入编程会话后以1000ms周期发送0x3E 00编程会话保持可继续刷写P1安全访问和0x3E的交互需要特别关注。安全状态可能与会话状态绑定一旦会话回退到默认会话安全解锁状态会被清除导致后续0x31例程控制或0x34请求写入失败。6.3 刷写流程中的保活验证刷写是0x3E最重要的真实场景。刷写过程中测试仪必须持续发送TesterPresent否则ECU从编程会话回退到默认会话刷写流程直接失败。刷写保活用例设计用例编号前置条件操作步骤预期结果优先级TP3E_I08编程会话在0x36数据传输过程中周期发送0x3E 00数据传输不被打断0x36正响应正常P1TP3E_I09编程会话在0x31例程擦除过程中停止发送0x3E超过S3ServerECU回默认会话例程结果可能异常P1TP3E_I10编程会话在刷写长耗时步骤中以500ms周期发送0x3E 00整个刷写流程完成ECU进入编程会话P1刷写用例通常不单独验证0x3E而是把它作为刷写流程的一个组成部分。测试报告中要重点记录“TesterPresent是否在长耗时步骤中持续发送”很多刷写失败问题就出在这里。7. 用CAPL和Python执行用例并留痕7.1 CAPL脚本周期发送0x3ECANoe环境下CAPL脚本可以精确控制发送周期和响应判断。下面是一个最小示例用于周期发送0x3E 00并检查总线上是否出现响应帧。/* 周期发送TesterPresent 0x3E 00抑制正响应 */ variables { msTimer tSendTP; int sendCount 0; } on start { setTimerCyclic(tSendTP, 1000); // 1s周期 } on timer tSendTP { message 0x7E0 msg; msg.dlc 8; msg.byte(0) 0x02; // Single Frame, 数据长度2 msg.byte(1) 0x3E; // SID msg.byte(2) 0x00; // Sub-function msg.byte(3) 0xAA; msg.byte(4) 0xAA; msg.byte(5) 0xAA; msg.byte(6) 0xAA; msg.byte(7) 0xAA; output(msg); sendCount; }这段脚本只负责发送。生产环境中应配合诊断服务接口或CDD文件直接用diagRequest发送这样响应关联和报文解析会更可靠。如果需要验证正响应可以增加一个CAN接收消息处理on message 0x7E8 { if (this.byte(1) 0x7E this.byte(2) 0x01) { // 收到TesterPresent正响应 write(TP response OK); } else if (this.byte(1) 0x7F this.byte(2) 0x3E) { write(TP negative response, NRC0x%02x, this.byte(3)); } }这段代码的核心价值在于把发送和响应判断放在同一脚本中避免用肉眼翻trace。7.2 Python脚本验证超时和NRC没有CANoe环境时可以使用python-can和isotp库做快速验证。先安装依赖pip install python-can isotp下面示例演示发送0x3E 01并等待正响应import time import can import isotp bus can.interface.Bus(channelcan0, bustypesocketcan) # 按ECU实际CAN ID配置 tp isotp.CanStack( bus, rxid0x7E8, txid0x7E0, params{stmin: 0, blocksize: 0} ) # 发送 0x3E 01 tp.send(bytes([0x3E, 0x01])) response tp.recv(timeout1) if response is not None: print(fResponse: {response.hex()}) else: print(No response)验证超时回落时可以切换会话后停止发送隔一段时间再读取当前会话# 进入扩展会话 tp.send(bytes([0x10, 0x02])) print(fSession after entry: {tp.recv(timeout1).hex()}) # 停止发送TesterPresent等待超过S3Server time.sleep(6) # 读取当前会话 tp.send(bytes([0x10, 0x01])) resp tp.recv(timeout1) print(fSession after timeout: {resp.hex()})如果复位后响应显示会话为0x01说明ECU已经回落到默认会话。脚本只是示例实际使用的CAN设备、通道名、CAN ID需要根据现场环境调整。7.3 测试记录与通过标准每次执行0x3E用例至少记录以下信息请求报文和CAN ID。响应报文或NRC。响应时间。发送间隔和实际时间戳。当前诊断会话。总线负载和错误帧。通过标准建议按需求定义例如0x3E 01必须在100ms内收到正响应。0x3E 00在功能寻址下不得出现任何正响应。停止发送后超过S3Server不超过100ms内回到默认会话。周期发送小于S3Server时会话全程保持。这些标准要写进用例不能只在报告里写“PASS”。8. 基于TestBuddy思路建模批量生成0x3E用例8.1 TestBuddy这类工具的定位TestBuddy是一类测试用例生成工具核心思路是把测试需求转成状态机、判定表或输入事件模型再自动穷举路径生成用例。它能减少手工用例的遗漏适合诊断服务这类状态强相关、输入组合多、回归频繁的场景。0x3E服务非常适合用建模方式生成用例因为它的行为可以抽象成“会话状态 输入事件 预期输出”的转移模型。手工设计时往往只会覆盖最常见的组合建模工具则会把每个状态和每个输入的交叉点都枚举出来。8.2 会话状态机建模把0x3E测试模型定义成四个状态和三个输入事件。状态状态说明Default默认会话Extended扩展会话Programming编程会话SecurityUnlocked扩展会话且安全访问已解锁输入事件事件说明TP_00发送0x3E 00TP_01发送0x3E 01TP_02发送0x3E 02TimeoutS3Server超时状态转移表的一部分当前状态事件预期输出下一状态DefaultTP_00无正响应DefaultDefaultTP_01正响应0x7E 01DefaultExtendedTP_00无正响应ExtendedExtendedTP_01正响应0x7E 01ExtendedExtendedTP_02负响应0x7F 3E 12ExtendedExtendedTimeout无响应DefaultProgrammingTP_00无正响应ProgrammingProgrammingTimeout无响应DefaultSecurityUnlockedTP_00无正响应安全状态保持SecurityUnlockedSecurityUnlockedTimeout无响应安全状态清除Default模型生成后工具会自动合并相同条件和冲突预期生成覆盖这些转移路径的测试用例。每一行转移至少生成一条正向用例每个“错误事件”生成一条异常用例。8.3 从模型导出用例和人工补充点自动生成的用例覆盖了状态和事件的笛卡尔积但仍需要人工补充几类场景边界时间点模型里只有Timeout事件没有4000ms、4990ms、5010ms这些时间值需要人工补充。总线层面模型不感知功能寻址和物理寻址差异需要人工增加寻址维度。连续交互模型只处理单次事件0x3E首次发送、停止、再恢复这类时序需要人工补充。刷写流程模型无法表达0x36和0x3E的持续配合需要人工增加集成用例。因此正确做法是用TestBuddy生成基础状态机用例再用人工用例覆盖时间边界和系统集成场景两者结合才能形成完整0x3E测试集。9. 常见问题排查9.1 收不到0x3E正响应现象发送02 3E 01后总线上看不到0x7E响应。排查顺序确认请求CAN ID是否正确。物理寻址请求ID必须与ECU诊断规范一致。确认发送的是完整2字节请求CAN报文层的DLC是否被填充了多余字节且PCI长度错误。确认子功能是否受ECU支持如果ECU只支持0x000x01会返回0x12。确认ECU当前会话状态。有些ECU在特定会话下可能抑制正响应。抓取CAN trace确认ECU是否发出负响应如7F 3E 13。现象可能原因检查方式处理建议无任何响应请求CAN ID错误核对诊断规范修改CAN ID无响应且日志有TP超时使用功能寻址且子功能为0x00检查请求ID改用物理寻址或0x01负响应0x12子功能不支持核对Dcm配置使用支持的子功能负响应0x13请求长度错误检查PCI字节修正报文长度9.2 会话保持不住周期性回到默认会话现象发送0x3E时ECU会话正常一停止就回到默认会话或者明明在周期发送会话还是回退了。排查顺序检查S3Server值。如果S3Server只有1000ms而发送周期是1500msECU就会超时回退。检查发送周期是否有抖动。总线繁忙时实际发送间隔可能远大于配置值。检查TesterPresent请求是否被ECU成功接收。抑制正响应的0x00没有反馈需要用trace确认请求帧确实到达ECU。检查是否在错误的总线上发送比如ECU在CAN2而测试仪在CAN1。检查是否误使用了功能寻址但功能寻址被ECU配置为不处理0x
返回列表