网络诊断 0x3E 服务用例设计:从需求拆解到 testbuddy 自动化落地
做网络诊断和 UDS 测试的同学,对 0x3E 服务应该都不陌生。这个服务负责会话切换,是整个诊断流程里被调用次数最多的服务之一。很多刚入门的测试工程师会问:0x3E 服务不就是一个切换会话的指令吗?能有多少测试点?
实际上,0x3E 会话控制服务牵扯到会话状态机、会话切换时序、P2/P2* 定时参数、非默认会话访问权限、网络异常恢复等多个维度,单靠“发一条指令看响应”这种粗放式验证,根本覆盖不了实车场景里的各种问题。这次我们就从需求拆解出发,把 0x3E 服务的测试用例完整设计一遍,再结合 testbuddy 这类用例生成和管理工具,把手工编写的用例转成可维护、可回溯的自动化用例资产。
文章内容分为三块:第一,0x3E 服务的协议逻辑和测试需求分析;第二,按功能、时序、异常、安全四个维度设计用例;第三,如何用 testbuddy 辅助生成用例、组织测试步骤,并与诊断自动化工具链打通。
1. 0x3E 服务核心能力速览
| 能力项 | 说明 |
|---|---|
| 服务名称 | Session Control,诊断会话控制 |
| SID | 0x3E |
| 子功能 | 0x01 默认会话,0x02 编程会话,0x03 扩展会话,0x04 安全扩展会话(按项目定义) |
| 主要作用 | 切换 ECU 诊断会话,控制会话超时与访问权限 |
| 响应方式 | 正响应 0x7E,负响应 0x7F |
| 关键时序 | P2、P2* 定时参数,非默认会话 S3 超时回到默认会话 |
| 测试重点 | 会话状态机、子功能有效性、切换时序、权限隔离、异常恢复 |
| 常用工具 | CANoe、CANalyzer、PCAN、迪卡侬诊断仪、testbuddy、Vector vTESTstudio |
| 是否支持自动化 | 支持,可编程实现全流程自动化验证 |
| 适合场景 | ECU 开发测试、诊断协议一致性测试、产线诊断、售后诊断流程验证 |
0x3E 服务的核心逻辑不复杂,但测试覆盖点非常多。下面按“需求拆解 -> 场景提取 -> 用例设计 -> 自动化执行”的顺序展开,读者可以把它当作一套可直接复用的测试用例设计模板。
2. 0x3E 服务协议逻辑与测试需求拆解
在设计用例之前,先确认 0x3E 服务在 UDS 协议里怎么工作。UDS(ISO 14229)定义 0x3E 服务用于客户端请求切换 ECU 的诊断会话。ECU 上电后默认进入默认会话,通过 0x3E 子功能可以切换到编程会话或扩展会话,非默认会话通常有 S3 超时时间,超过时间没有收到后续请求,ECU 会回到默认会话。
从测试需求拆解角度,0x3E 服务可以按五个层面展开:
- 功能需求:会话切换是否正确,子功能是否有效,正响应/负响应是否符合协议。
- 时序需求:S3 超时、P2/P2* 定时器、切换响应时间。
- 状态需求:默认会话、编程会话、扩展会话之间的状态迁移是否合法。
- 安全需求:非默认会话下对 0x27 安全解锁、0x22 读取、0x2E 写入等服务的访问控制是否正确。
- 异常需求:通信中断、总线休眠、非法子功能、连续切换、重复切换时的行为。
真实项目中,0x3E 服务最容易出问题的点包括:非默认会话超时后未回到默认会话、扩展会话下无法执行 0x2E 写入、编程会话切换失败、P2* 延长响应时序超过诊断仪等待时间。这些都应该作为重点用例覆盖。
结合最新热词中提到的 testbuddy 用例生成,工具层面需要考虑的是:需求条目不完整时,通过平台现有的 UDS 服务模板生成基础用例,再用迁移图或状态机补充分支场景,最后把补充用例固化到测试规范中。
3. 0x3E 服务用例设计方法
3.1 基于需求分类的用例框架
0x3E 服务用例建议按三级目录管理:
0x3E_SessionControl/ ├── 01_DefaultSession/ │ ├── TC_3E_001_默认会话下切换默认会话 │ ├── TC_3E_002_默认会话下切换扩展会话 │ └── TC_3E_003_默认会话下切换编程会话 ├── 02_ExtendedSession/ │ ├── TC_3E_010_扩展会话身份切换 │ ├── TC_3E_011_扩展会话S3超时回退 │ └── TC_3E_012_扩展会话访问0x2E写入 ├── 03_ProgrammingSession/ │ ├── TC_3E_020_编程会话身份切换 │ └── TC_3E_021_编程会话下刷写前置条件 ├── 04_AbnormalSequence/ │ ├── TC_3E_030_非法子功能 │ ├── TC_3E_031_连续切换会话 │ └── TC_3E_032_通信中断后会话状态 └── 05_SecurityAccess/ ├── TC_3E_040_扩展会话与安全解锁 └── TC_3E_041_不同会话下安全状态保留这种目录结构的好处是:用例编号清晰,后续追踪需求覆盖率和失败用例分布时可以按目录聚合统计,也可以直接在 testbuddy 里按模块导入。
3.2 用例设计要素
每个 0x3E 用例至少包含以下字段:
| 字段 | 说明 |
|---|---|
| 用例编号 | TC_3E_XXX,唯一标识 |
| 测试目的 | 说明验证的协议行为 |
| 前置条件 | ECU 上电状态、会话状态、总线条件 |
| 测试步骤 | 按顺序发送的诊断请求和等待时间 |
| 预期结果 | 正响应/负响应、状态切换、时间参数 |
| 实际结果 | 执行后自动或手动填写 |
| 判定标准 | Pass/Fail 的明确条件 |
| 关联需求 | 关联到系统需求条目 ID |
| 风险等级 | 高/中/低,决定测试优先级 |
testbuddy 之类的用例管理平台通常支持自定义字段,这组字段建议直接映射到平台的用例模板里,后续生成测试报告和追溯矩阵很方便。
3.3 状态迁移法生成用例
0x3E 服务本质是一个状态机,默认、扩展、编程三个会话之间不是任意切换都合法。各 ECU 对编程会话的进入条件定义不同,很多控制器要求先进入扩展会话并完成安全解锁,之后才能进入编程会话。通过状态迁移图可以补充出以下边界用例:
- 默认会话直接进入编程会话:按 ECU 设计决定是否允许。
- 扩展会话进入编程会话:常规合法路径。
- 编程会话进入扩展会话:通常允许,但要注意退出编程会话后是否保留安全解锁状态。
- 非默认会话下重复进入同一会话:应返回正响应,但部分 ECU 会返回 0x22 条件不满足。
状态迁移法尤其适合用 testbuddy 生成,因为 testbuddy 支持步骤组合和分支逻辑。把每个会话状态定义成一个前置条件,把 0x3E 子功能定义成动作,自动展开后就能得到覆盖矩阵。
4. 0x3E 服务功能测试用例明细
4.1 默认会话切换测试
TC_3E_001:默认会话下切换到默认会话
- 测试目的:验证重复进入当前会话是否正常处理。
- 前置条件:ECU 上电处于默认会话。
- 测试步骤:发送 0x3E 01。
- 预期结果:正响应 0x7E 01,ECU 保持默认会话。
- 判定标准:响应 SID 正确,无负响应。
TC_3E_002:默认会话下切换到扩展会话
- 测试目的:验证默认会话到扩展会话基础切换路径。
- 前置条件:ECU 上电处于默认会话。
- 测试步骤:发送 0x3E 03。
- 预期结果:正响应 0x7E 03,ECU 进入扩展会话。
- 判定标准:后续发送 0x22 读取扩展会话下才允许访问的 DID 能成功。
TC_3E_003:默认会话下切换到编程会话
- 测试目的:验证不同 ECU 对编程会话进入条件。
- 前置条件:ECU 上电处于默认会话。
- 测试步骤:发送 0x3E 02。
- 预期结果:按 ECU 设计,可能正响应或负响应。若设计允许,ECU 进入编程会话;若不允许,负响应 NRC 0x22。
- 判定标准:必须与诊断规范一致。
4.2 非默认会话切换测试
TC_3E_010:扩展会话保持与超时回退
- 测试目的:验证 S3 超时后是否回到默认会话。
- 前置条件:ECU 处于扩展会话。
- 测试步骤:发送 0x3E 03 进入扩展会话,等待超过 S3 时间(以 AUTOSAR 配置为准,常见 5s 或 10s),再发送 0x22 读取扩展会话 DID。
- 预期结果:超时后 ECU 自动回到默认会话,0x22 返回负响应 0x7F 22 0x7E 或 0x51。
- 判定标准:状态切换时间和回退行为符合设计要求。
TC_3E_011:非默认会话下发送 0x3E 保持会话
- 测试目的:验证周期性发送 0x3E 01 能否防止非默认会话超时。
- 前置条件:ECU 处于扩展会话。
- 测试步骤:进入扩展会话后,在 S3 超时时间内周期性发送 0x3E 01(例如每 2s 发送一次),持续超过 S3 时间。
- 预期结果:ECU 保持在扩展会话,不会回到默认会话。
- 判定标准:整个保持期间 0x22 扩展 DID 可正常读取。
TC_3E_012:非默认会话下写入访问控制
- 测试目的:验证扩展会话下 0x2E 写入权限。
- 前置条件:ECU 处于扩展会话且未安全解锁。
- 测试步骤:发送 0x2E 写入一个需要扩展会话权限的 DID。
- 预期结果:若该 DID 仅要求扩展会话,写入成功;若还要求安全访问,负响应 0x33 安全访问拒绝。
- 判定标准:NRC 值与 DID 权限定义一致。
4.3 编程会话刷写前置条件测试
TC_3E_020:进入编程会话
- 测试目的:验证完整刷写流程的会话切换部分。
- 前置条件:ECU 处于默认会话。
- 测试步骤:0x10 03 进入扩展会话 -> 0x27 01/02 安全解锁 -> 0x3E 02 进入编程会话。
- 预期结果:每一步正响应,最终进入编程会话。
- 判定标准:刷写前置流程完整执行。
TC_3E_021:编程会话下重启保持
- 测试目的:验证编程会话下 ECU 重启后的会话状态。
- 前置条件:ECU 处于编程会话。
- 测试步骤:发送 0x3E 02 进入编程会话,执行 ECU 复位,等待重启完成后发送 0x22 读取会话状态。
- 预期结果:ECU 重启后回到默认会话。
- 判定标准:重启后无法直接执行编程会话专属功能。
5. 0x3E 服务异常与安全用例设计
5.1 异常用例
TC_3E_030:非法子功能
- 测试目的:验证错误子功能处理。
- 前置条件:ECU 上电处于默认会话。
- 测试步骤:发送 0x3E 00 或 0x3E FF。
- 预期结果:负响应 0x7F 3E 12,子功能不支持。
- 判定标准:NRC 必须为 0x12(SNS)。
TC_3E_031:连续快速切换会话
- 测试目的:验证 ECU 对高频率会话切换的稳定性。
- 前置条件:ECU 上电。
- 测试步骤:循环发送 0x3E 01、0x3E 03、0x3E 02,每两条之间间隔 10ms,持续 100 次。
- 预期结果:无总线错误,响应正确,最终会话状态符合最后一次切换。
- 判定标准:无错误帧,ECU 不死机,不进入 Bus Off。
TC_3E_032:通信中断后会话保持
- 测试目的:验证总线断开后非默认会话是否按 S3 超时回退。
- 前置条件:ECU 处于扩展会话。
- 测试步骤:进入扩展会话后断开总线或关闭诊断仪,等待超过 S3 时间后重新连接。
- 预期结果:重新连接后 ECU 处于默认会话。
- 判定标准:回退行为正确,重新进入扩展会话需要重新发送 0x3E 03。
TC_3E_033:0x3E 请求和 0x10 请求交叉
- 测试目的:验证 0x3E 与 0x10 诊断会话控制之间的关系。
- 前置条件:ECU 处于扩展会话。
- 测试步骤:发送 0x10 01 切换到默认会话,再发送 0x3E 03 切换扩展会话,再发送 0x10 03 切换扩展会话。
- 预期结果:所有切换按请求顺序执行,正响应正常。
- 判定标准:最终状态与最后一次请求一致。
5.2 安全用例
TC_3E_040:不同会话下安全解锁状态
- 测试目的:验证会话切换后安全解锁状态是否保留。
- 前置条件:ECU 处于扩展会话。
- 测试步骤:0x27 01/02 完成安全解锁,切换默认会话,再切换回扩展会话,发送需要安全解锁的 0x2E 写入请求。
- 预期结果:按 ECU 设计决定,多数 ECU 在离开扩展会话后取消安全解锁状态。
- 判定标准:与安全规范一致。
TC_3E_041:编程会话下安全解锁失败
- 测试目的:验证安全解锁失败是否阻止编程会话操作。
- 前置条件:ECU 处于扩展会话。
- 测试步骤:发送错误密钥的 0x27 05,接着发送 0x3E 02 进入编程会话。
- 预期结果:若进入编程会话需要安全解锁,应负响应 0x22 或 0x33。
- 判定标准:非授权刷写被阻止。
6. 测试执行与 testbuddy 自动化用例生成
6.1 手工执行流程
0x3E 服务手工测试常用 CANoe 或 PCAN,操作流程:
- 加载 DBC。
- 建立诊断通道,配置物理寻址请求 ID 和响应 ID。
- 使用诊断控制台或 CAPL 脚本发送 0x3E 请求。
- 监听响应,记录响应时间和状态。
以 CANoe 为例,发送 0x3E 01 的 CAPL 代码片段如下:
// 发送 0x3E 01 默认会话请求 diagRequest SessionControl_Default req; req.SessionType = 1; diagSendRequest(req);如果需要自定义 0x3E 原始帧,也可以直接用 CAN 报文发送,但要注意请求 ID 和发送类型:
// 物理请求 0x7E0,0x3E 01 canTx 0x7E0 0x02 0x3E 0x01 0x00 0x00 0x00 0x00 0x00 0x006.2 testbuddy 用例生成思路
testbuddy 这类工具的价值不只是管理用例,更重要的是把需求、设计、用例、执行结果、缺陷串联起来。针对 0x3E 服务,用 testbuddy 辅助用例生成可以按下面的步骤做:
第一步,在 testbuddy 中创建 UDS 诊断测试模板;
第二步,通过 SID/子功能参数化生成基础用例矩阵。例如定义“会话切换”模板,参数为初始会话和目的会话,自动展开出默认到扩展、默认到编程、扩展到默认等组合。
第三步,结合状态机配置补充异常分支。比如 testbuddy 的策略模式允许针对每个正响应路径增加负响应分支,不会重复描述步骤。
第四步,导出用例到自动化执行平台,或者通过脚本批量导入。
6.3 用 Python 扩展自动化用例
如果测试环境本身有诊断自动化框架,可以用 Python 编写 0x3E 服务用例脚本。以下是一个逻辑示意,实际底层通信需要替换为 CAN 库接口:
import time class SessionControlTester: def __init__(self, can_channel, request_id=0x7E0, response_id=0x7E8): self.can_channel = can_channel self.request_id = request_id self.response_id = response_id def send_3e(self, sub_function): # 构造 0x3E 请求帧 request = [0x02, 0x3E, sub_function] # 通过 can_channel 发送 CAN 报文 # self.can_channel.send(self.request_id, request) print(f"Send 0x3E {sub_function:02X}") def switch_to_default(self): resp = self.send_3e(0x01) return resp == 0x7E def switch_to_extension(self): resp = self.send_3e(0x03) return resp == 0x7E def run_s3_timeout_test(self, s3_time=5.0): self.switch_to_extension() time.sleep(s3_time + 1) # 发送非默认会话下的 DID 读取请求,验证是否回到默认会话 # read_did(0xF190) print("S3 timeout test done")这段代码展示的是用例脚本的结构思路。实际执行时,需要把can_channel替换成 CANoe COM 接口、python-can 库或诊断仪 SDK,响应 ID 和 DBC 解析也需要按项目配置。
7. 0x3E 服务用例执行结果判定
7.1 判定正向响应
0x3E 正响应为 0x7E + 子功能,比如发送 0x3E 03,正响应是 0x7E 03。接收到的第一个字节如果等于响应 SID,说明 ECU 已接受会话切换。这里要注意:正响应不代表 ECU 立即切换成功,有些实现会先返回正响应再执行内部状态切换,最稳妥的方式是在正响应后继续发送一个会话相关 DID 读取请求来验证状态。
7.2 判定负响应
0x3E 负响应格式为:
0x7F [0x3E] [NRC]常见 NRC:
| NRC | 含义 | 典型场景 |
|---|---|---|
| 0x12 | 子功能不支持 | 发送非法子功能 |
| 0x22 | 条件不满足 | 直接进入编程会话被禁止 |
| 0x31 | 请求超出范围 | 子功能值在范围外 |
| 0x33 | 安全访问拒绝 | 需要安全解锁才能切换 |
如果负响应值为 0x22,重点检查前置条件是否满足。比如是否先进入了扩展会话,是否完成了安全解锁。
7.3 判定时序指标
0x3E 服务还有几个默认时间参数需要关注:
- P2:服务器响应时间,常见 50ms 以内。
- P2*:延长响应时间,一般 5000ms,仅用于下载/上传请求或长操作。
- S3:非默认会话超时时间,常见 5000ms,部分 ECU 会定义 3s。
测试时通过 CANoe 的 Trace 窗口统计请求发送到响应接收的时间间隔。0x3E 服务属于短请求,若响应时间超过 P2 但未超过 P2*,服务端应发送 0x7F 0x3E 0x78 先行响应,然后才给出最终结果。
8. 0x3E 服务测试常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 发送 0x3E 03 无响应 | 请求 ID 错误、ECU 不在线、波特率不匹配 | 检查 CAN 通信状态,查看总线是否有错误帧 | 确认 DBC 中的节点地址和诊断请求 ID |
| 0x3E 正响应后 0x22 读取仍失败 | 会话切换未真正完成,或 DID 权限不匹配 | 增加延时后再读取 DID | 在正响应后加 200ms 等待,再发送后续请求 |
| 非默认会话超时未回退 | S3 超时时间配置过长或功能未激活 | 查看 DTC/事件日志,确认 S3 定时器 | 按设计文档确认 S3 时间,必要时用诊断仪读取会话状态 |
| 编程会话切换返回 0x22 | 前置条件未满足 | 检查是否先进入扩展会话,是否完成安全解锁 | 按规范执行完整前置流程 |
| 大量连续切换后 ECU Bus Off | 高频率请求导致总线负载过高 | 查看 CANoe 总线统计 | 增加请求间隔,避免 10ms 内连续请求 |
| testbuddy 导入用例失败 | 用例字段与模板不匹配 | 检查自定义字段名称,查看导入日志 | 统一字段映射,重新导入 |
实际项目里,0x3E 服务测试最常见的“坑”是时序问题。尤其是扩展会话下的 S3 超时,如果测试代码在发送 0x3E 03 后没有周期性发送 0x3E 01 保持会话,那么测试过程中非默认会话可能已经悄悄回到默认会话,导致后续所有用例全部失败。更稳妥的方式是每执行一个用例前都先检查当前会话状态,再按测试目的切换。
9. 0x3E 服务测试环境与资源占用
0x3E 服务测试对硬件要求不高,常用环境包括:
| 组件 | 推荐配置 |
|---|---|
| 总线工具 | CANoe、CANalyzer、PCAN-USB、ValueCAN |
| 软件 | CANoe 12.0 及以上、vTESTstudio、testbuddy |
| 诊断协议 | ISO 14229-1、ISO 15765-2(DoCAN) |
| 数据库 | DBC、CDD、ODX |
| 操作系统 | Windows 10/11 x64 |
| 最低资源 | 4G 内存、20G 磁盘空间 |
如果只做 0x3E 服务单一功能验证,用 PCAN 加 python-can 也可以,成本更低。大量用例批量执行时建议用 CANoe + CAPL 或 vTESTstudio,能直接生成测试报告。
批量执行时注意:每个测试用例之间要清空诊断仪会话状态,避免上一个用例的非默认会话状态影响下一个用例。以 testbuddy 批量执行模式为例,建议每条用例前增加“复位 ECU 或等待回默认会话”的前置动作。如果 ECU 支持功能寻址复位,则可在整批用例开始前统一复位。
10. testbuddy 与诊断测试用例资产管理
10.1 用例模板化
testbuddy 支持用例模板和参数化扩展。0x3E 服务的所有用例可以抽象成一个模板:
| 参数 | 取值 |
|---|---|
| 初始会话 | defaultSession, extendedSession, programmingSession |
| 目标会话 | defaultSession, extendedSession, programmingSession |
| 子功能 | 0x01, 0x02, 0x03 |
| 是否需要安全解锁 | true, false |
| 是否检查 S3 超时 | true, false |
通过模板参数化,能自动展开出全组合的用例矩阵。凡是项目中实际不支持的组合,可以通过过滤规则排除,最终落地成为稳定用例集。
10.2 用例与需求追溯
0x3E 服务的每条用例都应该关联系统需求。比如:
- 需求 ID: SYS_DIAG_SESSION_001,描述“ECU 上电进入默认会话”。
- 需求 ID: SYS_DIAG_SESSION_005,描述“非默认会话应支持 S3 超时回退”。
在 testbuddy 里建立需求与用例的关联关系后,执行结果可以自动生成需求覆盖率报告。这个能力对 A-SPICE 和功能安全流程审计很有价值。
10.3 自动化执行闭环
0x3E 服务用例自动化的完整闭环包括:
- 从 testbuddy 导出用例集。
- 通过脚本转换成 CAPL 测试工程或 Python 脚本。
- 执行测试并采集 Trace 和响应数据。
- 将结果回填到 testbuddy。
- 生成测试报告和缺陷单。
具体接口取决于测试平台和 testbuddy 版本,但整体思路都是:用例定义和执行结果分离,避免在自动化工程里重复开发用例描述。
11. 0x3E 服务测试最佳实践
第一,先把会话状态检查做成公共函数。无论在 CANoe 还是 Python 脚本里,都要有一个get_current_session()函数,每次测试开始前调用,避免用例之间状态串扰。
第二,区分物理请求和功能请求。0x3E 服务通常使用物理寻址,功能寻址时响应可能不回复或者延迟回复,按诊断规范确定。
第三,非默认会话测试一定要关注 S3 超时时间。测试报告里必须记录测试开始时间、最后请求时间、回退时间,以便精确定位 S3 参数是否满足设计。
第四,批量执行时把用例间隔设置为大于 S3 超时时间,或者每个用例后主动发送 0x3E 01 回到默认会话。这两种方式中,主动回默认会话更可靠,等待超时会让批量执行时间拉长。
第五,关于版权、安全和数据合规。0x3E 服务测试涉及 ECU 数据和诊断访问权限控制,测试过程中可能读取到车辆 VIN、标定数据、软硬件版本等信息。这些数据只能用于开发测试和售后诊断,不能用于未授权场景。涉及安全访问时,所有密钥和绕过操作必须经过整车厂授权,测试报告中也应避免明文记录敏感安全信息。
12. 总结与后续方向
0x3E 服务虽然协议简单,但从需求拆解到用例落地的完整过程并不简单。真正值得验证的功能点是:默认、扩展、编程会话之间所有合法与非法迁移路径,非默认会话下的访问权限,S3 超时回退,以及安全解锁与会话切换的组合场景。建议首次测试时先跑 TC_3E_001、TC_3E_002、TC_3E_010、TC_3E_030 这四类用例,能快速判断 ECU 的 0x3E 基础实现是否符合协议。
最容易踩的坑是会话状态串扰和 S3 超时设置。测试框架没有状态检查、用例之间不重置会话,会导致批量执行结果完全失真。
后续扩展方向可以包括:把 0x3E 服务用例接入完整 UDS 自动化测试套件,结合 vTESTstudio 生成一致性测试报告;在 testbuddy 里按需求维度统计 0x3E 服务覆盖率;