3、UDS协议入门:UDS(ISO 14229)概述、服务分类、诊断会话与安全等级

UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229标准定义的应用层诊断协议,也是当前全球汽车电子领域应用最广泛的诊断规范。无论是传统燃油车的ECU刷写、排放检测,还是新能源车的电池管理系统(BMS)标定、OTA远程升级,UDS都扮演着“统一语言”的角色。对于ECU刷写流程而言,UDS不仅是Bootloader与上位机(如INCA、CANape、ODX)之间的通信桥梁,更是定义“何时能写、如何写、写完后如何验证”的规则框架。本章将从协议分层、服务分类、会话管理、安全等级四个维度,系统拆解UDS的核心机制,并结合Bootloader刷写场景说明其工程落地要点。

UDS协议分层与刷写链路关系图 诊断仪/上位机 INCA / CANape / ODX UDS客户端 (Client) 传输层/网络层 ISO-TP (ISO 15765-2) CAN / CAN FD / 以太网 ECU (服务器/Server) Bootloader / 应用程序 诊断服务执行器 UDS服务分类 (ISO 14229-1) 诊断会话 10h 安全等级 27h 数据读写 22h/2Eh 程序控制 31h/34h 故障管理 19h/14h 其他 3Eh/85h Bootloader刷写典型UDS链路 10h 02h 编程会话 27h 01h/02h 安全解锁 34h/36h 请求/传输数据 37h 退出传输 11h 复位ECU 注:刷写前需完成10h会话切换与27h安全解锁,刷写中通过34h/36h/37h传输数据,最后11h复位生效

上图展示了UDS协议在ECU刷写场景中的完整链路关系。上位机作为客户端(Client)通过CAN/CAN FD总线发送诊断请求,ECU作为服务器(Server)响应请求并执行相应操作。传输层采用ISO-TP(ISO 15765-2)协议进行数据分包与重组,确保超过单帧长度(CAN经典帧8字节,CAN FD可达64字节)的诊断消息能够可靠传输。在刷写流程中,UDS服务按照“会话切换→安全解锁→数据传输→复位验证”的顺序依次调用,每一步都有对应的服务ID(SID)和状态机约束。

3.1 UDS协议概述与分层模型

UDS协议位于OSI七层模型的应用层(第7层),其设计目标是提供一套标准化的诊断服务接口,使得不同厂商、不同平台的ECU能够用统一的语义进行通信。ISO 14229-1定义了UDS的核心规范,而ISO 14229-2(会话层)和ISO 15765-2(网络层)则分别规定了传输机制和底层适配。在实际工程中,UDS报文通常承载于CAN总线上,通过CAN ID的仲裁机制区分不同ECU的诊断地址。

UDS协议的核心设计思想是“请求-响应”模式。客户端发送一个诊断请求(Request),服务器执行相应操作后返回一个响应(Response)。响应分为肯定响应(Positive Response)和否定响应(Negative Response)两种。肯定响应以请求SID加0x40作为首字节,例如请求0x10(诊断会话控制)的肯定响应首字节为0x50;否定响应则以0x7F作为首字节,后跟请求SID和否定响应码(NRC,Negative Response Code)。NRC是诊断排障的关键线索,常见的NRC包括0x11(服务不支持)、0x12(子功能不支持)、0x13(消息长度错误)、0x22(条件不满足)、0x31(请求超出范围)、0x33(安全访问被拒绝)等。

协议分层要点:UDS应用层负责定义服务语义和参数格式;ISO-TP层负责将超过单帧长度的消息进行分段传输,支持单帧(SF)、首帧(FF)、连续帧(CF)和流控帧(FC)四种帧类型;CAN驱动层负责物理信号的收发。在刷写场景中,由于A2L文件或HEX文件通常包含数MB的数据,必须依赖ISO-TP的多帧传输机制,因此理解ISO-TP的帧类型和流控参数(如BlockSize、STmin)对刷写稳定性至关重要。

3.2 UDS服务分类与刷写相关服务

ISO 14229-1定义了约26种标准诊断服务,按照功能域可划分为六大类。下表列出了与ECU刷写直接相关的核心服务及其功能说明:

服务ID (SID) 服务名称 功能分类 刷写场景用途
0x10 DiagnosticSessionControl 诊断会话管理 切换至编程会话(0x02)或扩展会话(0x03)
0x27 SecurityAccess 安全等级控制 解锁Bootloader的写入权限
0x22 ReadDataByIdentifier 数据读取 读取ECU软件版本、VIN码、刷写状态等
0x2E WriteDataByIdentifier 数据写入 写入配置参数、标定数据等
0x31 RoutineControl 程序控制 执行擦除Flash、校验完整性、复位等例程
0x34 RequestDownload 数据传输 请求下载,告知ECU即将传输的数据长度和地址
0x36 TransferData 数据传输 分块传输实际固件数据
0x37 RequestTransferExit 数据传输 结束数据传输,触发ECU内部校验
0x11 ECUReset 程序控制 刷写完成后复位ECU,使新程序生效
0x19 ReadDTCInformation 故障管理 读取刷写后产生的故障码,验证刷写结果

在刷写流程中,0x34(请求下载)和0x36(传输数据)是最核心的服务。0x34请求中包含了数据格式标识符(DataFormatIdentifier)、地址和长度信息(AddressAndLengthFormatIdentifier),ECU根据这些参数分配Flash存储空间并准备接收数据。0x36服务则通过块序列号(BlockSequenceCounter)和传输数据(TransferData)字段,将固件按块(通常为4KB或8KB)依次写入Flash。每次0x36请求后,ECU都会返回肯定响应,表示该块数据已成功接收并写入。

工程经验:在Bootloader设计中,0x36服务的块大小(BlockSize)需要根据Flash页大小和CAN通信速率综合确定。块过小会导致传输次数过多、效率低下;块过大则可能超出ISO-TP单帧承载能力,增加传输错误概率。通常建议块大小不超过ISO-TP连续帧的承载上限(经典CAN为4095字节,CAN FD可达更多),同时保证与Flash擦除页大小对齐。

3.3 诊断会话管理:从默认会话到编程会话

UDS协议定义了多种诊断会话(Diagnostic Session),每种会话对应一组允许执行的诊断服务集合。ECU上电后默认进入默认会话(Default Session,0x01),该会话仅允许执行读取类服务(如0x22、0x19)和部分控制类服务,禁止执行刷写相关操作。当需要刷写时,上位机必须通过0x10服务切换到编程会话(Programming Session,0x02)或扩展会话(Extended Session,0x03)。

会话切换的请求格式为:0x10 + 子功能,例如切换到编程会话发送02 10 02(假设CAN ID为0x7E0)。ECU收到请求后,如果条件满足(例如当前车速为0、发动机未运行),则返回肯定响应06 50 02 00 32 01 F4,其中包含P2(Server)和P2*(Server)定时参数,用于告知客户端后续服务的响应超时时间。如果条件不满足,ECU返回否定响应03 7F 10 22,NRC 0x22表示条件不满足。

会话管理的关键机制是会话超时(S3Server)。ECU在进入非默认会话后,会启动一个定时器(通常为5秒)。如果在该时间内未收到任何诊断请求,ECU将自动退回默认会话。这一机制是为了防止ECU长时间停留在编程会话中,导致车辆无法正常行驶。因此,在刷写过程中,上位机必须周期性地发送诊断请求(如0x3E TesterPresent)来保持会话激活。

风险提示:在刷写过程中,如果S3Server超时导致会话回退,ECU会中止当前刷写流程并进入未定义状态。此时必须重新执行10h会话切换和27h安全解锁,才能继续刷写。更严重的是,如果Flash擦除后未完成写入,ECU可能无法启动应用程序,只能依赖Bootloader的恢复机制(如强制编程模式)进行修复。因此,建议在刷写工具中实现S3保活机制,并设置合理的超时重试策略。

3.4 安全等级:安全访问(SecurityAccess)机制

为了防止未经授权的刷写操作,UDS协议通过0x27服务(SecurityAccess)实现安全等级控制。该服务采用“挑战-应答”(Challenge-Response)认证机制:客户端发送请求种子(Seed)的子功能(通常为0x01),ECU返回一个随机种子;客户端根据种子和内部算法计算密钥(Key),并通过子功能0x02发送给ECU;ECU验证密钥正确后,解锁相应的安全等级。

安全访问的请求流程如下:

  1. 请求种子:发送02 27 01,ECU返回06 67 01 [Seed],其中Seed为2-4字节的随机数。
  2. 计算密钥:上位机根据种子和厂商特定的算法(如AES、CRC、查表法)计算密钥。
  3. 发送密钥:发送06 27 02 [Key],ECU验证密钥。
  4. 验证结果:如果密钥正确,ECU返回02 67 02;否则返回03 7F 27 35(NRC 0x35表示无效密钥)。

安全等级通常分为多个级别,例如Bootloader刷写需要安全等级1(解锁Flash写入),而标定数据写入可能需要安全等级2。不同等级对应不同的种子和密钥算法,且ECU会限制连续尝试次数(通常为3次),超过次数后ECU会锁定安全访问功能一段时间(如10秒或60秒),以防止暴力破解。

安全等级设计建议:在Bootloader中,安全访问算法应避免使用固定密钥或简单异或运算,建议采用基于AES-128或SHA-256的加密算法,并将密钥分散因子与ECU的VIN码或唯一ID绑定。同时,应实现尝试次数计数和锁定时间递增机制,提高抗攻击能力。在刷写工具中,密钥计算模块应独立封装,避免将算法暴露在应用层。

3.5 实战场景:一次完整的UDS刷写会话拆解

下面通过一个实际案例,展示UDS协议在ECU刷写中的完整应用。假设某ECU的Bootloader支持UDS刷写,上位机通过CAN总线(500kbps)与ECU通信,CAN ID分配为:诊断请求0x7E0,诊断响应0x7E8。

场景背景:车辆在售后维修时需要升级ECU固件,从版本V1.2升级到V1.3。刷写工具为INCA,通过CANape的XCP/CCP模块与ECU建立连接。刷写前需确认车辆处于安全状态(点火开关ON,发动机熄火)。

刷写步骤与关键报文:

步骤 发送报文 (ID:0x7E0) 响应报文 (ID:0x7E8) 说明
1. 切换会话 02 10 02 06 50 02 00 32 01 F4 进入编程会话,P2=50ms,P2*=500ms
2. 安全解锁 02 27 01 06 67 01 1A 2B 3C 4D 获取种子:1A2B3C4D
3. 发送密钥 06 27 02 5E 7A 9F 21 02 67 02 密钥验证通过,解锁成功
4. 擦除Flash 03 31 01 FF 00 03 71 01 FF 00 执行例程0xFF00(擦除应用区)
5. 请求下载 05 34 00 44 00 10 00 00 04 74 20 00 10 00 请求下载,地址0x00100000,长度0x1000
6. 传输数据 10 36 01 [数据块1] 30 00 00 14 首帧传输,块序列号01,流控帧BS=0,STmin=20ms
7. 连续传输 21 [数据块2] ... 2F [数据块16] 02 36 01 连续帧传输,每帧7字节有效数据
8. 退出传输 02 37 01 02 77 01 请求退出传输,ECU进行CRC校验
9. 复位ECU 02 11 01 02 51 01 硬件复位,新固件生效

结果与复盘:刷写完成后,通过0x22服务读取软件版本号,确认已更新为V1.3。同时读取DTC(通过0x19服务),确认无新增故障码。整个刷写过程耗时约3分钟,其中数据传输阶段占90%的时间。复盘发现,在步骤6中,由于ISO-TP流控帧的STmin设置为20ms,导致传输速率受限。如果将STmin调整为10ms,并增大BlockSize,刷写时间可缩短至2分钟以内。此外,在安全解锁步骤中,如果连续3次密钥错误,ECU将锁定安全访问60秒,因此刷写工具应实现密钥重试的退避策略。

常见误区:很多初学者误以为UDS刷写只需要发送0x34和0x36服务即可,忽略了会话切换和安全解锁的前置条件。实际上,如果ECU处于默认会话且未解锁,0x34请求会返回NRC 0x7F(服务不支持)或0x33(安全访问被拒绝)。此外,在传输数据过程中,如果块序列号不连续或数据长度与0x34请求不一致,ECU会返回NRC 0x13(消息长度错误)或0x31(请求超出范围),导致刷写中断。

3.6 总结与工程建议

UDS协议是ECU刷写流程的通信基石,理解其服务分类、会话管理和安全等级机制,是设计可靠Bootloader和刷写工具的前提。在实际工程中,建议从以下四个方面进行把控:

  • 协议栈实现:优先选用经过量产验证的UDS协议栈(如Vector、ETAS、AUTOSAR),避免自行开发底层ISO-TP和UDS状态机,降低协议兼容性风险。
  • 会话管理:在刷写工具中实现S3保活机制,周期发送0x3E服务,防止会话超时回退。同时,在ECU端设计合理的会话超时时间(建议5-10秒),平衡安全性和刷写效率。
  • 安全等级:采用多级安全访问机制,将Bootloader刷写、标定写入、配置修改等操作分配不同安全等级,并实现尝试次数锁定和密钥分散管理。
  • 异常恢复:在Bootloader中实现强制编程模式(如通过特定引脚或CAN报文触发),确保刷写失败后ECU仍可恢复,避免“变砖”风险。