2. ISO 14229标准解读:核心内容与UDS服务分类

好,咱们进入第二章。ISO 14229这个标准,说白了就是UDS诊断协议的“宪法”。你开发任何诊断功能,最终都得回到这份文档里找依据。我刚开始接触UDS那会儿,看着这好几百页的PDF头都大,后来才发现,只要抓住了它的骨架,剩下的都是血肉。

这一章,我带你把ISO 14229-1的核心内容捋一遍,重点看看UDS的服务分类和协议数据单元(PDU)结构。这些东西搞清楚了,后面写代码、搭测试环境,你心里就有底了。

2.1 ISO 14229-1核心内容概览

ISO 14229-1定义了诊断服务的通用需求,不依赖具体的通信总线(比如CAN、LIN、以太网)。它规定了客户端(通常是诊断仪)和服务器(ECU)之间怎么对话。

核心要点: 标准定义了26种诊断服务,分为6大类。每个服务都有一个唯一的SID(Service Identifier,服务标识符),占用1个字节。

举个例子,0x10就是“诊断会话控制”,0x22是“通过ID读取数据”。这些SID你以后会天天跟它们打交道。

2.2 UDS服务分类详解

ISO 14229-1把服务分成了6个功能单元。我习惯把这6类记成“诊、数、存、输、远、上”,对应下面这张表:

功能单元 服务列表(SID) 一句话用途
诊断与通信管理 0x10, 0x11, 0x27, 0x28, 0x3E, 0x83, 0x84, 0x85 控制会话、复位、安全访问、通信控制
数据传输 0x22, 0x23, 0x24, 0x2A, 0x2C, 0x2E 读写DID、内存地址、周期读取数据
存储数据传输 0x14, 0x19 清除/读取诊断故障码(DTC)
输入输出控制 0x2F 强制控制ECU的输入/输出信号
远程激活 0x31 启动ECU内部例程(如自学习、校准)
上传下载 0x34, 0x35, 0x36, 0x37, 0x38 刷写软件、上传/下载数据块

咱们挑几个重点类说说。

2.2.1 诊断与通信管理

这是ECU的“看门人”。你发任何诊断请求之前,ECU得先知道你在哪个“会话”里。

  • 0x10 诊断会话控制:ECU有默认会话、编程会话、扩展会话。我遇到过不少新手,上来就发0x22读数据,结果ECU回了个NRC 0x78(请求正确接收-响应待定),其实就是会话没切对。
  • 0x11 ECU复位:硬件复位、钥匙关/开复位、快速启动复位。刷完软件后,这个服务用得最多。
  • 0x27 安全访问:解锁受保护的功能。需要种子和密钥的“握手”流程。
  • 0x3E 测试仪在线:俗称“心跳包”。防止ECU因为超时自动跳回默认会话。

我的习惯: 写测试脚本时,我会把0x3E放在一个独立线程里,每500ms发一次。这样主线程做其他操作时,会话不会掉。

2.2.2 数据传输

这是日常诊断最常用的功能。通过DID(Data Identifier,数据标识符)来读写ECU的内部数据。

  • 0x22 通过ID读取数据:读电压、温度、版本号。DID是2个字节,比如0xF190代表“ECU硬件版本”。
  • 0x2E 通过ID写入数据:写配置参数、标定值。注意,写操作通常需要先切到扩展会话,并且通过安全访问。
  • 0x23 通过地址读取内存:直接访问物理内存地址。这个服务在Bootloader里很常见,用来读Flash内容。

2.2.3 存储数据传输

专门处理故障码(DTC)。

  • 0x14 清除诊断信息:清除所有DTC和快照数据。修完车后,维修技师会用这个服务清故障灯。
  • 0x19 读取DTC信息:这个服务有28个子功能,比如读当前故障、读历史故障、读故障发生时的环境数据(快照)。

我曾经踩过的坑: 0x19的子功能0x02(读取与DTC相关的快照记录)返回的数据长度是不固定的。如果你的解析代码写死了长度,遇到多帧响应时,很容易丢数据。一定要按ISO 15765-2的传输层协议来组包。

2.2.4 输入输出控制

只有一个服务:0x2F。它允许诊断仪临时接管ECU的某个输入或输出信号。比如强制让某个继电器吸合,或者模拟某个传感器值。

这个服务在产线测试和售后维修中非常有用。但要注意,操作完成后,一定要用“返回正常模式”的控制选项,否则ECU会一直处于“被控制”状态。

2.2.5 远程激活

0x31 例程控制。ECU内部预置了一些“小程序”,通过这个服务来启动、停止或查询结果。

举个例子:在Bootloader里,0x31可以用来擦除Flash扇区、检查应用程序的完整性(CRC校验)。

2.2.6 上传下载

这是刷写(Flash Programming)的核心服务组。

  • 0x34 请求下载:告诉ECU“我要写数据了”,协商数据格式和长度。
  • 0x36 传输数据:实际的数据块传输,一次最多传4095字节。
  • 0x37 请求传输退出:结束本次传输。

这三个服务配合起来,就是完整的刷写流程。我后面会专门用一章来讲刷写协议栈的实现。

2.3 协议数据单元(PDU)结构

UDS的报文,在应用层叫PDU。它由三部分组成:

+----------------+----------------+------------------+
|  A_Data (SID)  |  SubFunction   |  Data Parameters |
|  (1 byte)      |  (0-1 byte)    |  (0-N bytes)     |
+----------------+----------------+------------------+
  • A_Data (SID):服务标识符,必选。比如0x22。
  • SubFunction:子功能,可选。比如0x10服务的子功能0x01(默认会话)、0x02(编程会话)。
  • Data Parameters:数据参数,可选。比如0x22服务后面跟着的2字节DID。

你想想看,一个完整的诊断请求,其实就是把这些字节拼起来,然后交给传输层(比如CAN的ISO 15765-2)去打包发送。

下面这张图,把UDS服务的分类和PDU结构串在了一起,方便你建立整体认知:

UDS协议知识体系(ISO 14229-1) 协议数据单元(PDU)结构 A_Data (SID) - 1字节 SubFunction - 0/1字节 Data Parameters - 0~N字节 UDS 6大服务分类(功能单元) 诊断与通信管理 0x10,0x11,0x27... 数据传输 0x22,0x2E,0x23... 存储数据传输 0x14,0x19 输入输出控制 0x2F 远程激活 0x31 上传下载 0x34~0x38 应用场景 ECU刷写 | 故障诊断 | 产线测试 | 售后维修 | 远程升级

2.4 响应格式与NRC

UDS的响应分为肯定响应和否定响应。

  • 肯定响应:格式是 SID + 0x40 开头。比如请求0x22,肯定响应就是0x62。
  • 否定响应:格式是 0x7F + 请求SID + NRC。NRC(Negative Response Code)告诉客户端为什么被拒。

常见的NRC有:

NRC (Hex) 含义 常见原因
0x10 一般拒绝 服务不支持或当前状态不允许
0x12 子功能不支持 比如0x19的子功能0x05没实现
0x22 条件错误 没切到正确会话就发写请求
0x31 请求超出范围 DID不存在或数据长度不对
0x33 安全访问拒绝 没解锁就操作受保护功能
0x78 请求正确接收-响应待定 ECU需要额外时间处理,稍后重试

注意: NRC 0x78比较特殊。它表示ECU收到了请求,但还没处理完。客户端收到0x78后,应该等待一段时间再发相同的请求,而不是立即重试。我曾经见过一个测试脚本,收到0x78后疯狂重发,结果把ECU的通信栈搞崩了。

2.5 小结

这一章我们把ISO 14229-1的骨架搭起来了。你记住了6大类服务、它们的典型SID,以及PDU的三段式结构,后面学具体服务实现时就不会迷路。

嗯,标准文档是死的,但应用是活的。我建议你手边常备一份ISO 14229-1的PDF,遇到不确定的NRC或服务行为时,直接翻原文档,比网上搜来的二手信息靠谱得多。