1. 课程导入

UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229系列标准定义的诊断应用层协议,它并不直接跑在CAN总线上,而是通过ISO-TP(ISO 15765-2)传输层承载在CAN/CAN FD、DoIP等底层网络之上。理解这一点,是嵌入式开发者建立正确心智模型的第一步:UDS是"服务语义层",不是"物理链路层"。ECU内部真正处理的是0x10、0x22、0x2E、0x27、0x31这些服务请求,而总线上的帧、流控、分包重组由传输层完成。

在整车电子电气架构中,UDS诊断节点通常扮演"被诊断者"(Server)角色,由诊断仪(Tester/Client)发起请求。典型链路是:诊断仪 → OBD接口 → 网关 → 目标ECU。嵌入式开发者的任务,就是让ECU能够正确解析请求、执行诊断逻辑、返回肯定或否定响应,并在刷写、下线检测、售后维修等场景中稳定工作。

UDS诊断在车载网络中的分层定位 诊断仪 Tester Client / 请求方 中央网关 路由 / 转发 目标 ECU Server / 被诊断节点 MCU 固件 UDS 协议栈 应用层 ISO 14229-1 UDS 服务:0x10 会话 / 0x22 读数据 / 0x2E 写数据 / 0x27 安全访问 / 0x31 例程 / 0x34-0x37 刷写 传输层 ISO 15765-2 ISO-TP:单帧 / 首帧 / 连续帧 / 流控帧,处理分包与重组 数据链路层 CAN / CAN FD 帧格式、ID 仲裁、位定时、错误帧 物理层 CAN_H / CAN_L 差分电平、终端电阻、收发器

学习目标

完成本课程后,你应当能够独立完成一个UDS诊断节点的嵌入式开发闭环。具体目标如下:

  • 协议理解:掌握ISO 14229-1服务模型、请求/响应格式、NRC否定响应码含义。
  • 传输实现:能基于ISO-TP实现多帧收发,正确处理流控与超时。
  • 服务开发:能实现会话控制、安全访问、读写数据、例程控制、DTC读取等核心服务。
  • 刷写支持:理解Bootloader与App的跳转关系,能配合0x34/0x36/0x37完成固件下载。
  • 调试排障:能用CANoe、PCAN、CANalyzer或开源工具定位诊断失败原因。

整体知识框架

本课程按"协议基础 → 传输实现 → 服务开发 → 刷写与安全 → 测试验证"的主线推进。下表给出各模块的核心内容与产出物,便于你建立全局地图。

模块 核心内容 关键标准 产出物
协议基础 服务模型、寻址方式、会话与安全状态 ISO 14229-1 服务清单与状态机
传输实现 ISO-TP 单帧/多帧、流控、超时 ISO 15765-2 收发驱动与缓冲管理
服务开发 0x10/0x22/0x2E/0x27/0x31/0x19 ISO 14229-1 服务处理函数与NRC
刷写与安全 Bootloader、0x34/0x36/0x37、种子密钥 ISO 14229-1 / OEM规范 刷写流程与安全算法
测试验证 诊断仪联调、自动化测试、故障注入 ISO 14229-1 / 测试规范 测试用例与报告

嵌入式开发环境准备

在动手写代码之前,先把工具链和硬件环境搭好。以下是一个典型的开发环境清单,适用于大多数基于CAN的UDS节点开发。

硬件:
  - 目标ECU开发板(含CAN收发器,如TJA1050/1042)
  - USB-CAN分析仪(PCAN-USB、Kvaser、CANoe硬件或开源CANable)
  - 120Ω终端电阻(总线两端各一个)
  - 12V电源与线束

软件:
  - 编译器:GCC ARM / IAR / Keil MDK
  - 调试器:J-Link / ST-Link / Lauterbach
  - 总线工具:PCAN-View、CANoe、SavvyCAN 或 python-can
  - 诊断脚本:CAPL、Python-uds、ODX/PDX 解析工具

代码骨架(伪代码):
  void uds_task(void) {
      can_frame_t rx;
      if (can_receive(&rx)) {
          isotp_input(&rx);          // 传输层重组
          uds_dispatch(&rx.payload); // 服务分发
      }
  }
建议先用PCAN-View或SavvyCAN手动发送一条0x22读数据请求,观察ECU是否返回0x62肯定响应。这一步能快速验证物理层、传输层和应用层是否全部打通,是最高效的"冒烟测试"。

案例场景:一次典型的诊断交互

假设诊断仪要读取ECU的VIN码(数据标识符0xF190)。完整交互如下:

  1. 诊断仪发送:22 F1 90(请求读取VIN)。
  2. ECU应用层解析服务0x22,检查会话状态与安全权限。
  3. 若允许,ECU返回肯定响应:62 F1 90 + VIN数据(17字节)。
  4. 由于VIN长度超过单帧容量,ISO-TP会拆分为首帧+连续帧,诊断仪回送流控帧。
  5. 若会话不满足,ECU返回否定响应:7F 22 7F(服务不支持于当前会话)。

这个例子说明:UDS开发不是只写应用层逻辑,而是应用层、传输层、链路层协同工作的结果。任何一层出错,诊断仪看到的都是"无响应"或"否定响应"。

常见误区与复盘

误区一:把UDS当成CAN协议。UDS是应用层协议,CAN只是承载方式之一。DoIP、FlexRay同样可以承载UDS。混淆层次会导致排障时方向错误。
误区二:忽略会话与安全状态。很多服务(如0x2E写数据、0x31例程)必须在扩展会话且通过0x27安全访问后才能执行。状态机没设计好,功能测试必然失败。
误区三:只测单帧,不测多帧。VIN、DTC快照、刷写数据都是多帧场景。ISO-TP的流控、块大小(BS)、最小间隔(STmin)配置错误,是现场最常见的故障源。

复盘建议:每实现一个服务,都按"正常请求 → 边界长度 → 错误会话 → 错误安全状态 → 错误参数"五个维度设计测试用例。这样能在集成前暴露大部分问题,减少台架调试时间。