🔧 车载诊断协议深解:从 OBD 溯源到 UDS 核心机制
📌 前言:两种诊断协议,一个共同目标
如果你拆开一辆现代汽车的诊断接口,插上一台通用扫描仪,你能读到发动机转速、故障码、氧传感器数据——这是OBD的功劳。
但当你使用原厂诊断仪刷写 ECU、匹配钥匙、校准雷达时,背后真正在工作的,是UDS。
它们不是竞争对手,而是法规底线与深度工具的完美搭档。
本文将从起源讲起,带你完整掌握 OBD 与 UDS 的技术全貌,并深入剖析 UDS 中最核心的安全访问服务(0x27)。
一、🔍 OBD:因环保而生,为排放而战
1.1 📅 起源:一场雾霾催生的法规
上世纪 80 年代,美国加州洛杉矶地区光化学烟雾事件频发。加州空气资源委员会(CARB)认定汽车尾气是主要元凶,于是强制要求:1988 年起,所有在加州销售的车辆必须装备能实时监控排放的车载诊断系统。
这便是 OBD(On‑Board Diagnostics)的雏形。随后美国 EPA 推广至全美,形成OBD‑II标准;欧洲、日本分别跟进为EOBD、JOBD。
💡核心驱动力:政府环保法规,而非技术创新。
🎯本质定位:车辆排放的“健康证”,只关心尾气是否超标。
1.2 ✅ OBD 提供的基础服务
| 服务 | 说明 |
|---|---|
| 读取故障码(DTC) | 仅读取排放相关系统(发动机、三元催化、氧传感器、燃油蒸发)的故障码 |
| 清除故障码 | 修复后清除,熄灭仪表盘上的发动机故障灯(MIL) |
| 读取实时数据 | 发动机转速、车速、氧传感器电压、进气压力、冷却液温度等 |
| 检查系统就绪状态 | 确认各排放相关系统自检是否完成(用于年检) |
⚠️ OBD不关心车窗、气囊、空调、刹车——它只关心“排出来的气干不干净”。
二、📡 OBD 通信机制与 OSI 模型的关系
OBD 的通信协议栈完全参考了 OSI 七层模型,只是在实际实现中合并了部分层次。
OBD 通信机制基于经典的七层 OSI 模型构建,每一层都有明确的分工与标准协议。
📊 对应关系表
| OSI 层 | OBD 中的标准 | 作用(通俗解释) |
|---|---|---|
| 7. 应用层 | SAE J1979/ ISO 15031-5 | 规定“问什么”:读故障码、清码、读数据的指令格式 |
| 6. 表示层 | ISO 15031-2 / SAE J1930-DA | 统一术语:故障码、参数 ID 标准化,诊断仪能看懂 |
| 5. 会话层 | ISO 14229-2(部分) | 建立/维持诊断对话,管理超时 |
| 4. 传输层 | ISO 15765-2 | 长文再打包:超过 8 字节的数据拆成多个包发送 |
| 3. 网络层 | ISO 15765-2(合并) | 寻址:确保数据包发给正确的 ECU |
| 2. 数据链路层 | ISO 11898-1(CAN) | 把电信号变成数据帧,加 CRC 校验 |
| 1. 物理层 | ISO 11898-2(高速 CAN)或 ISO 9141(K线) | 定义电压、电缆、接头、波特率 |
🧠为什么传输层和网络层合并?
CAN 总线每帧最多 8 字节数据。当诊断数据超过 8 字节时,需要拆包(传输层功能)并指定目标 ECU(网络层功能)。ISO 15765-2 同时承担这两项任务,是工程效率的体现。
物理层早期多采用基于 ISO 9141 的 K 线通信,如今则广泛采用高速 CAN 总线(ISO 11898),实现车辆 ECU 与诊断设备间的高速、稳定数据传输。
三、🔢 OBD 故障码(DTC)格式
OBD 故障码遵循SAE J2012标准,全世界统一格式。
📝 例子:P0103
| 位置 | 含义 | 值 | 解释 |
|---|---|---|---|
| 第1位 | 系统类别 | P | Powertrain(动力总成) |
| 第2位 | 故障类型 | 0 | 通用故障码(SAE 定义) |
| 第3-5位 | 具体故障 | 103 | 空气流量计电路高输入 |
🧩 系统类别(首位字母)
| 字母 | 系统 | 示例 |
|---|---|---|
| P | Powertrain(发动机、变速箱、燃油) | P0300 多缸失火 |
| C | Chassis(底盘、ABS、转向) | C1234 轮速传感器故障 |
| B | Body(车身、气囊、空调) | B1000 气囊模块内部故障 |
| U | Network(CAN 总线通信) | U0100 与 ECM 失去通信 |
🔢 故障类型(第二位数字)
| 数字 | 含义 |
|---|---|
| 0 | ISO/SAE 通用码 |
| 1 | 制造商自定义 |
| 2 | ISO/SAE 保留 |
| 3 | 未来扩展 |
DTC 由三部分组成:DTC High Byte、DTC Middle Byte、DTC Low Byte(采用 ISO 15031-6 定义的标准)。其中 DTC High Byte、DTC Middle Byte 这两个字节表示故障内码,对应 5 位标准故障码。
💪标准化故障码让全球修车师傅都能看懂 P0103 的含义。
四、🚀 为什么需要 UDS?OBD 的局限
OBD 只盯着排放系统,但现代汽车拥有几十甚至上百个 ECU:
🔧 发动机、变速箱、ABS、气囊、空调、座椅、车灯、自动驾驶辅助……
车企需要深度诊断:刷写固件、修改配置、执行例程、远程升级。
OBD完全不够用。
于是,国际标准化组织(ISO)联合各大车企,于 2006 年发布了ISO 14229,即统一诊断服务(UDS)。
🌟UDS 本质:汽车诊断领域的“通用 API”。
诊断仪发送标准化指令,ECU 返回标准化响应,无需为不同 ECU 定制专属逻辑。
五、📋 UDS 协议全面解析
5.1 🎯 特点与范围
- ✅ 支持多种物理总线:CAN(DoCAN)、以太网(DoIP)、LIN、FlexRay、K 线
- ✅ 覆盖全车所有 ECU:动力、底盘、车身、信息娱乐、自动驾驶……
- ✅26 种诊断服务,分为 6 大功能单元
💡 UDS 诊断协议就是 ISO 14229 协议,在 ISO 14229 协议中定义了 UDS 服务用法、服务格式等信息。
5.2 📊 UDS 服务列表(6 大类 26 种)
| 大类 | SID (hex) | 中文服务名 | 英文服务名 |
|---|---|---|---|
| 诊断和通信管理 | 0x10 | 诊断会话控制 | DiagnosticSessionControl |
| 0x11 | ECU复位 | ECUReset | |
| 0x27 | 安全访问 | SecurityAccess | |
| 0x28 | 通讯控制 | CommunicationControl | |
| 0x3E | 待机握手 | TesterPresent | |
| 0x83 | 访问时间参数 | AccessTimingParameter | |
| 0x84 | 安全数据传输 | SecuredDataTransmission | |
| 0x85 | 控制DTC的设置 | ControlDTCSetting | |
| 0x86 | 事件响应 | ResponseOnEvent | |
| 0x87 | 链路控制 | LinkControl | |
| 数据传输 | 0x22 | 通过ID读数据 | ReadDataByIdentifier |
| 0x23 | 通过地址读内存 | ReadMemoryByAddress | |
| 0x24 | 通过ID读比例数据 | ReadScalingDataByIdentifier | |
| 0x2A | 通过周期ID读数据 | ReadDataByPeriodicIdentifier | |
| 0x2C | 动态定义标识符 | DynamicallyDefineDataIdentifier | |
| 0x2E | 通过ID写数据 | WriteDataByIdentifier | |
| 0x3D | 通过地址写内存 | WriteMemoryByAddress | |
| 存储数据传输 | 0x14 | 清除诊断信息 | ClearDiagnosticInformation |
| 0x19 | 读取故障码信息 | ReadDTCInformation | |
| 输入输出控制 | 0x2F | 通过ID控制输入输出 | InputOutputControlByIdentifier |
| 例行程序 | 0x31 | 例行程序控制 | RoutineControl |
| 上传下载 | 0x34 | 请求下载 | RequestDownload |
| 0x35 | 请求上传 | RequestUpload | |
| 0x36 | 数据传输 | TransferData | |
| 0x37 | 请求退出传输 | RequestTransferExit | |
| 0x38 | 请求文件传输 | RequestFileTransfer |
UDS 诊断包括 6 大类、26 种服务,每种服务都有自己独立的 SID(Service Identifier)。
5.3 💬 基本通信模型
- 客户端:诊断仪(Tester)
- 服务端:ECU
采用“请求-响应”模式:
- 客户端发送请求报文
- 服务端返回正响应或负响应
5.4 📦 UDS 传输方法(基于 CAN 总线)
UDS 报文需要通过CAN 总线传输,但 CAN 帧最多携带8 字节数据,而 UDS 报文可能长达数千字节。
为此定义ISO 15765-2传输协议(网络层/传输层)。
🔢 四种 CAN 帧类型
| 帧类型 | 高4位(N_PCI) | 作用 |
|---|---|---|
| 单帧(SF) | 0 | 数据 ≤ 7 字节时直接发送 |
| 首帧(FF) | 1 | 数据 > 7 字节时,发送第一帧(携带总长度和前 6 字节数据) |
| 连续帧(CF) | 2 | 后续数据帧,带有序列号(SN) |
| 流控帧(FC) | 3 | 接收端控制发送端速率 |
在 ISO 15765-2 中对于网络层协议数据单元 N_PDU 有 4 种类型,分别为单帧 SF、首帧 FF、连续帧 CF、流控帧 FC。
🌊 多帧传输流程
🎮 关键参数说明
- FlowStatus (FS):
0=继续,1=暂停,2=溢出 - BlockSize (BS):发送 BS 个连续帧后需等待新的流控帧;
0表示不再发流控 - SeparationTime (STmin):两个连续帧之间的最小间隔(单位 ms)
这些机制确保了大数据块(如固件镜像)在 CAN 总线上可靠、高效地传输。
六、🔐 深入 UDS 0x27 安全访问服务
作为信息安全工程师,0x27 服务是必须啃下的硬骨头。它负责保护 ECU 中的所有敏感操作,防止未授权访问。
6.1 🎬 应用场景
- ECU 固件刷新:刷写前必须解锁,否则 ECU 会拒绝下载请求
- 产线写入重要数据(如 VIN 码、标定参数):通过 2E 服务写入前需先解锁
- 向 Flash 写入数据:任何写 Flash 的操作都需要安全解锁
- 执行关键例程(31 Routine):如擦除 EEPROM、自学习等
0x27 SecurityAccess 安全访问服务旨在提供一种安全访问权限,用于将程序或数据上传/下载到 ECU、从 ECU 中读取特定内存位置的诊断服务。
💡直观理解:这就好比你去银行取钱,光有银行卡还不够,必须输入正确的密码才能操作。$27 服务就是 ECU 的“密码验证”机制。
6.2 🚪 先决条件:诊断会话(0x10 服务)
UDS 定义了三种诊断会话,0x27 安全访问必须在扩展会话下进行。
| 会话类型 | 子功能代码 | 主要功能 | 常见支持的服务 |
|---|---|---|---|
| 默认会话 | 01 | 读取数据、读取/清除故障码、重置 ECU | 22, 14, 19, 11 等 |
| 扩展会话 | 03 | 解锁 ECU、控制输入输出 | 27, 2E, 2F 等 |
| 编程会话 | 02 | 执行 ECU 刷写相关服务 | 34, 35, 36, 37 等 |
🔑 切换会话使用
10 03(进入扩展会话)或10 02(进入编程会话)。
并不是所有服务都只在一个会话下活动,由此就有了会话优先级的概念。
6.3 🔢 安全级别:完全可自定义
0x27 服务通过子功能(Sub‑function)区分安全级别。标准约定:
- 奇数子功能:请求种子(Request Seed)
- 偶数子功能:发送密钥(Send Key)
| 安全级别 | 请求种子 | 发送密钥 | 典型用途 |
|---|---|---|---|
| 1级 | 27 01 | 27 02 | 解锁读取受保护的 DID(如车辆配置信息) |
| 2级 | 27 03 | 27 04 | 解锁写操作(如写入 VIN 码、执行例程) |
| 3级 | 27 05 | 27 06 | 解锁最高风险操作(如固件刷写、BootLoader) |
🛠️重要提醒:不同厂商对 sub-function 的定义可能不同。比如大众平台常用 0x01 表示 Level 1,而某些国产 ECU 可能用 0x05。
💪车企可以任意扩展安全级别(子功能范围 0x01~0x7F),每个级别绑定不同的解锁算法和受保护的诊断服务。
🔐算法自定义:种子-密钥算法由车企自主设计(如自定义 CRC、AES 变形等),但必须保证与诊断仪一致。
6.4 🌱 种子-密钥(Seed‑Key)交互流程
安全访问的本质是建立一道权限关卡。验证过程采用典型的“挑战-响应”机制:
- 诊断仪发送 seed 请求(相当于问 ECU 要密码题)
- ECU 返回随机 seed 值(出题)
- 诊断仪用预设算法计算 key(解题)
- ECU 验证 key 的正确性(批改答案)
📌关键技术点:
- Seed 是 ECU 内部随机生成的数据,随机性增加了每次请求的不可预测性,能有效防止重放攻击。
- 在任何时间,仅有一个安全级别处于激活状态。
- 如果所请求的安全级别已经处于解锁状态,ECU 将发送 Seed 值 = 00 的肯定响应消息。
📝 步骤详解:
- 诊断仪发送
27 01(请求种子) - ECU 返回随机种子(长度可配置,通常 4~8 字节)
- 诊断仪使用与 ECU 完全相同的算法计算密钥
- 诊断仪发送
27 02+ 密钥 - ECU 校验:一致则返回
67 02,解锁对应安全级别;否则返回负响应。
6.5 ❌ 0x27 服务常见的否定响应码(NRC)
| NRC (hex) | 描述 | 排查建议 |
|---|---|---|
0x12 | 子功能不支持 | 检查发送的奇数/偶数子功能是否在 ECU 支持范围内 |
0x22 | 条件不正确,未处于扩展会话 | 先发送10 03进入扩展会话 |
0x24 | 未请求种子直接发送密钥 | 必须先27 01请求种子,再27 02发送密钥 |
0x35 | 密钥不正确(验证失败) | 检查算法或种子值是否正确 |
0x36 | 达到最大失败次数 | ECU 已锁定该安全级别,需等待或复位 |
0x37 | 处于延迟锁定时间(Lockout Time)内 | 等待计时结束,或执行 ECU 复位清除锁定 |
📖补充说明:若请求失败或验证密钥失败,ECU 均回复 7F 27+NRC 的否定响应。
这些 NRC 是协议级标准,任何符合 UDS 的 ECU 都必须按此含义返回。
七、📊 总结:OBD 与 UDS 的全面对比
| 对比维度 | OBD | UDS |
|---|---|---|
| 起源 | 政府环保法规(CARB/EPA) | 车企 + ISO 技术驱动 |
| 诊断范围 | 仅排放相关 ECU | 全车所有 ECU |
| 服务数量 | ~10 个($01~$0A) | 26 种(6 大类) |
| 典型功能 | 读/清故障码,读数据流 | 刷写固件、写配置、安全访问、例程控制 |
| 故障码信息 | 2 字节 + 固定格式 | 3 字节 + 状态位 + 快照数据 |
| 安全机制 | 几乎无 | 种子-密钥(0x27)/ PKI 认证(0x29) |
| 法规属性 | 强制 | 非强制,但成事实标准 |
OBD 与 UDS 是当前车载诊断领域两大核心协议,它们各自承载着不同的使命,在诊断范畴、功能特性、通信机制等方面存在显著差异,却又在现代化汽车中协同工作。
八、🔄 融合趋势:它们并非二选一
- 共用同一个16 针 OBD 诊断口(位于驾驶位下方)
- 共用同一条 CAN 总线(可同时收发 OBD 和 UDS 指令)
OBD 诊断接口的 16 号针脚是常电,直接连电瓶正极,电压通常在 12V 左右;4 号和 5 号是接地针脚;6 号和 14 号是 CAN 高、CAN 低线,现在 90% 以上的新车都用这个协议。
- 最新标准 SAE J1979-2 (OBDonUDS)要求 OBD 排放数据也通过 UDS 服务读取。到 2027 年,所有燃油车将强制执行。
📌 本文基于 SAE J1979、ISO 15031、ISO 15765、SAE J2012、ISO 14229、ISO 15765-2 等公开标准及行业技术资料整理。
欢迎收藏、转发,留言讨论! 💬