☰
UDS 0x3E服务测试用例设计:从需求拆解到CANoe自动化
2026/10/15 1:01:08 网站建设 项目流程

在实际诊断测试项目中,0x3E服务(TesterPresent,测试仪在线保持)常被认为是UDS协议里最容易实现的服务:请求格式固定、响应逻辑简单、平时跑功能时几乎不会报错。但真正进入用例设计阶段时,很多人会卡住——周期怎么测?抑制响应位要测哪些场景?S3Server超时算谁的职责?如果需求里只写了“支持0x3E服务”,测试用例到底该从哪下手?

本文以“根据需求设计0x3E服务测试用例”为主线,先回顾0x3E服务在ISO 14229中的报文细节和S3Server会话保活机制,再给出从需求条目拆解到用例设计的完整方法,并提供一套覆盖正常、异常、边界、会话状态机、组合场景的0x3E用例模板。最后补充基于CANoe的CAPL自动化实现思路和常见问题排查清单。

内容面向车载诊断测试工程师、嵌入式ECU开发人员和刚接触UDS协议栈的新手。后面所有用例都可以直接复制到自己的用例管理系统或Excel模板中,再根据项目实际诊断规范做调整。

1. 0x3E服务是什么,为什么需要认真设计用例

1.1 从一个“保活”需求说起

在UDS(Unified Diagnostic Services,统一诊断服务)诊断体系中,ECU通常会维护一个会话定时器S3Server。只要ECU处于非默认会话(例如扩展诊断会话、编程会话),必须在规定时间窗口内收到来自诊断仪的任意诊断请求,否则ECU会认为诊断仪已离线,自动从当前会话退出,回到默认会话。

这样一来,诊断仪在长时间执行刷写、标定或数据采集时,就必须周期性地发送一个“我还在线”的信号来重置S3Server定时器,这个信号就是0x3E服务。

0x3E服务的作用可以概括为一句话:在不执行其他诊断功能时,保持诊断仪与ECU之间的会话连接。

1.2 0x3E服务在ISO 14229中的定义

ISO 14229-1中,0x3E服务被定义为TesterPresent,属于UDS应用层服务。它不携带数据参数,只包含一个子功能字节。客户端发送0x3E请求后,服务端根据子功能决定是否回复。

从功能上看,0x3E服务本身不读取ECU数据,也不修改任何参数,因此逻辑看起来很简单。但正是因为它简单,很多测试设计人员会低估它的测试价值:凡是涉及到会话状态切换、超时定时器、最小响应时间、总线负载的测试,最终都会回归到0x3E服务是否正确工作。

1.3 为什么0x3E服务的用例设计容易被低估

0x3E服务的用例设计之所以需要单独梳理,主要有三个原因:

第一,它与ECU的会话状态机强耦合。0x3E能否被正确响应,取决于当前会话、子功能支持表以及ECU的会话定时器配置。

第二,它存在“抑制肯定响应”这一特殊机制。0x80子功能表示服务端不应发送肯定响应,但否定响应不受抑制。不少测试人员会把“无响应”误判为“未收到0x7E就是失败”,忽略了抑制响应位的语义。

第三,它最容易在自动化测试中产生误报。因为0x3E请求通常周期性地出现在总线上,测试脚本如果过滤条件不严,很容易把周期保活报文当成其他服务的前置响应进行错误关联。

因此,即使0x3E服务代码量很少,在诊断测试中仍值得专门设计一套覆盖正常、异常、边界、状态迁移和组合场景的用例集合。

2. 0x3E服务核心原理回顾

在动手设计用例之前,先快速回顾0x3E服务的报文格式、子功能定义、S3Server超时机制和否定响应规则。这部分是所有用例预期结果的依据。

2.1 请求报文格式

0x3E请求格式如下:

字节名称值说明
Byte 0SID0x3ETesterPresent服务ID
Byte 1子功能0x00 或 0x800x00表示需肯定响应;0x80表示抑制肯定响应

请求长度为2字节。超过2字节或只有1字节,都属于格式错误。

2.2 响应报文格式

当子功能为0x00且服务执行成功时,ECU返回肯定响应:

请求:3E 00 响应:7E 00

当子功能为0x80时,服务端抑制肯定响应,总线上不应出现0x7E 0x80:

请求:3E 80 响应:无

注意,0x80子功能只是抑制“肯定”响应,并不抑制“否定”响应。如果0x3E请求本身不合法,即使子功能为0x80,ECU也必须发送否定响应。这一点在ISO 14229-1中有明确说明。

2.3 子功能与抑制响应位

子功能字节的最高位是抑制肯定响应标志位(suppressPosRspMsgIndicationBit),bit6-0是真正的子功能编号。

  • 0x3E 00:bit7=0,不抑制肯定响应,子功能为0x00。
  • 0x3E 80:bit7=1,抑制肯定响应,子功能为0x00。

也就是说,0x3E其实只有一个实际子功能编号0x00,但它有两种请求形式:需要响应和不需要响应。

理解这一点非常关键。在需求文档中,通常会看到两条需求:

  • “支持子功能0x00,返回肯定响应。”
  • “支持请求子功能0x80,抑制肯定响应。”

这两条实际上是同一个子功能在抑制标志位上的两种表现,用例设计时既要分开验证,也要保证两者不冲突。

2.4 S3Server会话超时机制

S3Server的值通常根据OEM规范定义,常见默认值为5000ms。ECU处于非默认会话时,S3Server定时器被启动;每收到一个诊断请求,定时器重置;如果定时器超时,ECU回到默认会话。

0x3E服务的核心价值就在这里:它通过周期性发送请求,不断重置S3Server定时器,从而让ECU保持在当前会话。

这里还有一个容易混淆的点:S3Server定时器是所有诊断请求都会重置,还是只有0x3E能重置?实际上,ISO 14229规定,在非默认会话中,任何诊断请求都会重置S3Server定时器,0x3E只是其中最常用、最轻量的一种保活手段。因此用例设计时,可以考虑“发送其他诊断服务也能保活”这一场景,但不一定作为0x3E服务的强制需求。

2.5 0x3E服务相关的否定响应码

0x3E服务可能返回的否定响应码主要有:

NRC含义触发条件
0x12子功能不支持子功能编号不为0x00时
0x13报文长度或格式错误请求长度不为2字节
0x22条件不满足ECU当前状态不允许执行该服务
0x7E服务不支持ECU完全未实现0x3E服务(少见)

在大多数ECU中,0x3E服务在所有会话下都支持,因此0x22和0x7E的触发场景需要依据具体ECU诊断规范。设计用例前,先查当前项目诊断规格书中0x3E的支持会话表和支持子功能表。

3. 从需求到用例的设计思路

3.1 需求条目的层级拆分

测试用例不能直接从一个模糊的“支持0x3E服务”需求跳出来,应该先做需求拆分。一个完整的需求描述通常包含:

  • 服务ID
  • 支持的会话范围(默认、扩展、编程)
  • 支持的子功能
  • 肯定响应行为
  • 否定响应行为
  • 与其他服务/状态的交互约束
  • 时序/周期要求

举个例子,假设原始需求是:

ECU应支持TesterPresent服务,用于在非默认会话中保持诊断会话连接。

按上面维度拆解后,可以得到至少6条可测试需求:

需求ID需求描述
REQ-3E-001在默认会话下,ECU应响应0x3E 0x00请求,返回0x7E 0x00
REQ-3E-002在扩展会话下,ECU应响应0x3E 0x00请求,返回0x7E 0x00
REQ-3E-003在编程会话下,ECU应响应0x3E 0x00请求,返回0x7E 0x00
REQ-3E-004当收到0x3E 0x80请求时,ECU应抑制肯定响应,不发送0x7E 0x80
REQ-3E-005当收到不支持的子功能时,ECU应返回NRC 0x12
REQ-3E-006在非默认会话下,周期发送0x3E请求应保持当前会话不超时

只有完成这样的拆解,后续用例设计才有明确依据。

3.2 用例设计方法选择

针对0x3E服务,最适合的方法组合是等价类划分、边界值分析和状态迁移测试。

等价类划分用于子功能字段:有效等价类是0x00、0x80;无效等价类是除0x00和0x80之外的所有值。注意0x80的高位置1后子功能编号仍然是0x00,因此不能简单地把0x80归为“无效”。

边界值分析用于时间周期:围绕S3Server超时时间设计发送周期,例如S3Server=5000ms时,可以选择周期为3000ms、4800ms、5000ms、5200ms、6000ms。周期明显小于超时时间时,会话应保持;周期大于超时时间时,会话应退出。

状态迁移测试用于会话状态机:覆盖默认会话→扩展会话→默认会话、默认会话→编程会话→默认会话等路径,验证0x3E在每个状态中的响应行为。

3.3 0x3E服务的测试分层模型

在实际项目里,我会把0x3E用例分成四层:

  1. 基础功能层:验证请求响应格式、子功能支持、NRC码。
  2. 会话管理层:验证0x3E在不同诊断会话中的行为,以及S3Server超时是否按预期触发。
  3. 边界与异常层:验证报文长度错误、总线上重复发送、总线负载、抑制响应位与NRC的组合行为。
  4. 组合场景层:验证0x3E与0x10(会话切换)、0x28(通信控制)、0x85(DTC设置控制)等服务的交互。

设计完一层再进入下一层,不会漏测试点,也方便分配用例优先级。

4. 0x3E服务用例设计实战

下面进入本文最核心的部分:一套覆盖正常、异常、边界、状态迁移、组合场景的0x3E服务测试用例。

4.1 用例编号与命名规范

建议用例编号格式为:

TC_服务ID_流水号_场景标识

示例:

  • TC_3E_001_DefaultSession_Positive
  • TC_3E_002_ExtendedSession_SessionHold
  • TC_3E_005_InvalidSubFunction_NRC12

这样做的好处是:看到用例编号就知道测的是什么服务、什么场景,并且方便在自动化测试报告中直接关联日志过滤条件。

每一条用例至少包含字段:

字段说明
用例编号全局唯一
需求依据对应需求ID
前置条件诊断会话、ECU状态等
测试步骤可执行的报文级步骤
输入数据请求帧报文
预期结果响应帧/状态变化
优先级P0/P1/P2
测试类型功能/异常/边界/时序/组合

4.2 基础功能类用例

TC_3E_001 默认会话正常请求
  • 需求依据:REQ-3E-001
  • 前置条件:ECU上电,处于默认会话,总线通信正常
  • 测试步骤:
    1. 发送UDS请求 0x3E 0x00
  • 输入数据:3E 00
  • 预期结果:ECU在响应超时时间内回复7E 00,且S3Server定时器被重置(如果当前在非默认会话)
  • 优先级:P0
TC_3E_002 扩展会话正常请求
  • 需求依据:REQ-3E-002
  • 前置条件:通过10 03进入扩展诊断会话
  • 测试步骤:
    1. 发送UDS请求 0x3E 0x00
  • 输入数据:3E 00
  • 预期结果:ECU回复7E 00
  • 优先级:P0
TC_3E_003 编程会话正常请求
  • 需求依据:REQ-3E-003
  • 前置条件:通过10 02进入编程会话(部分ECU需要额外解锁)
  • 测试步骤:
    1. 发送UDS请求 0x3E 0x00
  • 输入数据:3E 00
  • 预期结果:ECU回复7E 00
  • 优先级:P0
TC_3E_004 抑制肯定响应
  • 需求依据:REQ-3E-004
  • 前置条件:ECU处于默认会话
  • 测试步骤:
    1. 发送UDS请求 0x3E 0x80
    2. 等待一个完整响应超时窗口(例如1秒)
  • 输入数据:3E 80
  • 预期结果:总线上不出现7E 80,但ECU内部应正常重置S3Server定时器
  • 优先级:P0
TC_3E_005 不支持的子功能返回NRC 0x12
  • 需求依据:REQ-3E-005
  • 前置条件:ECU处于默认会话
  • 测试步骤:
    1. 发送UDS请求 0x3E 0x01
    2. 发送UDS请求 0x3E 0x02
    3. 发送UDS请求 0x3E 0x7F
  • 输入数据:3E 01/3E 02/3E 7F
  • 预期结果:ECU对每组请求均回复7F 3E 12
  • 优先级:P0
TC_3E_006 报文长度错误返回NRC 0x13
  • 前置条件:ECU处于默认会话
  • 测试步骤:
    1. 发送长度仅为1字节的请求3E
    2. 发送长度大于2字节的请求3E 00 00
  • 输入数据:3E/3E 00 00
  • 预期结果:ECU回复7F 3E 13
  • 优先级:P1

注意,不同诊断仪、总线路由和ECU实现可能对多余字节的处理不一致。有的ECU会忽略多余字节并正常响应,有的则返回NRC 0x13。用例设计前先确认项目诊断规范中的描述,避免把规范允许的“忽略多余字节”误判为失败。

4.3 会话与超时类用例

TC_3E_007 周期发送0x3E保持扩展会话
  • 前置条件:ECU处于扩展会话,S3Server=5000ms
  • 测试步骤:
    1. 在扩展会话中,每隔3000ms发送一次3E 00
    2. 持续发送6次,每次间隔3000ms
    3. 第6次发送后,再等待3000ms
    4. 发送一次10 01(切换默认会话请求),观察ECU当前所在会话
  • 输入数据:多帧3E 00
  • 预期结果:整个过程ECU保持扩展会话,S3Server未超时;最后发送10 01后返回50 01
  • 优先级:P0
TC_3E_008 停止发送0x3E后触发S3Server超时
  • 前置条件:ECU处于扩展会话,S3Server=5000ms
  • 测试步骤:
    1. 发送一次3E 00确认当前会话正常
    2. 停止发送任何诊断请求,等待时间超过S3Server(例如6000ms)
    3. 发送一次10 03请求进入扩展会话
    4. 观察ECU响应
  • 预期结果:等待超时后,ECU已自动回到默认会话;此时发送10 03返回50 03,说明会话从默认重新进入扩展。相比未超时时直接发10 03,如果ECU本身处于扩展会话则返回NRC 0x22,这一区别可用于判断ECU是否真的发生了超时退出
  • 优先级:P0
TC_3E_009 S3Server边界时间测试
  • 前置条件:ECU处于扩展会话,S3Server=5000ms
  • 测试步骤:
    1. 以4800ms周期连续发送10次3E 00
    2. 每次发送后记录ECU响应和当前会话状态
    3. 再以5200ms周期连续发送10次3E 00
  • 输入数据:周期不同的3E 00
  • 预期结果:周期4800ms时ECU始终保持在扩展会话;周期5200ms时,某次发送后ECU会因定时器超时退出扩展会话,后续3E 00响应行为按默认会话规则执行
  • 优先级:P1

这里要特别说明:不同ECU对S3Server的计时精度、诊断仪请求处理耗时、总线调度延迟都有影响,边界值测试出现“有时超时、有时不超时”是正常的。用例结果应记录实际超时时间,作为ECU定时器精度评估依据。

TC_3E_010 0x3E 0x80同样重置S3Server定时器
  • 前置条件:ECU处于扩展会话,S3Server=5000ms
  • 测试步骤:
    1. 进入扩展会话后,每隔3000ms发送一次3E 80
    2. 持续发送6次
    3. 最后一次发送后等待3000ms
    4. 发送10 01验证当前会话
  • 预期结果:即使没有收到肯定响应,ECU的S3Server定时器仍然被3E 80请求重置,会话保持扩展状态
  • 优先级:P1

这条用例容易被遗漏。很多测试人员默认“无响应=没生效”,实际上0x3E 0x80只是不给应用层回响应,ECU内部服务照样执行,S3Server照样重置。

4.4 边界与异常类用例

TC_3E_011 子功能0xFF的处理
  • 前置条件:ECU处于默认会话
  • 测试步骤:
    1. 发送UDS请求 0x3E 0xFF
  • 输入数据:3E FF
  • 预期结果:ECU返回7F 3E 12或按项目诊断规范定义处理
  • 优先级:P2
TC_3E_012 重复发送相同请求
  • 前置条件:ECU处于默认会话
  • 测试步骤:
    1. 连续发送3E 00三次
    2. 每次等待响应后再发下一次
  • 预期结果:每次均返回7E 00,ECU无异常
  • 优先级:P1
TC_3E_013 抑制响应位与否定响应优先级
  • 前置条件:ECU处于默认会话
  • 测试步骤:
    1. 发送UDS请求 0x3E 0x81(高位置1,子功能编号为0x01)
  • 输入数据:3E 81
  • 预期结果:即便抑制响应位置1,由于子功能不支持,ECU仍应返回否定响应7F 3E 12
  • 优先级:P1

这条用例直接对应ISO 14229关于“否定响应不受抑制位控制”的规定,也是0x

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询