4、刷写协议基础:UDS协议(ISO 14229)在刷写中的应用
UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229标准定义的车载电子控制单元(ECU)诊断服务协议,也是AUTOSAR体系中诊断通信的核心协议。在Bootloader刷写场景中,UDS协议承担着建立诊断会话、安全认证、数据传输、程序校验和复位激活等关键任务。理解UDS协议在刷写流程中的具体应用,是掌握Bootloader设计与刷写测试的基础。本章将围绕刷写过程中最核心的四个服务——诊断会话控制(0x10)、安全访问(0x27)、通信控制(0x28)以及数据传输相关服务(0x34/0x36/0x37),深入剖析其原理、操作流程、实战案例与常见误区。
上图展示了UDS刷写服务的完整链路:从会话切换、安全解锁、通信抑制到数据传输与复位激活。在实际工程中,这些服务并非孤立执行,而是按照严格的时序和状态机逻辑协同工作。下面我们将逐一剖析每个关键服务的原理与实战要点。
4.1 诊断会话控制服务(0x10)
核心原理
诊断会话控制服务用于切换ECU的诊断模式。在刷写场景中,最核心的切换是从默认会话(Default Session,0x01)切换到编程会话(Programming Session,0x02)。默认会话下,ECU仅支持有限的诊断服务(如读取故障码、读取数据),而编程会话会启用Bootloader中的刷写相关服务,同时禁用应用层程序的正常运行。AUTOSAR规范中,会话状态由会话状态管理器(Session State Manager)统一维护,切换会话时ECU会执行一系列内部操作:停止应用任务、初始化刷写驱动、配置通信参数等。
操作流程
- 诊断仪发送
0x10 02请求进入编程会话。 - ECU收到请求后,校验当前状态是否允许切换(例如车速为零、发动机停机等条件)。
- ECU返回正响应
0x50 02,表示会话切换成功。 - 若条件不满足,ECU返回负响应
0x7F 0x10 0x22(条件不满足)。
案例拆解:编程会话切换失败
某车型在产线刷写时,发现约2%的ECU无法进入编程会话。通过抓取CAN总线日志,发现ECU返回 0x7F 0x10 0x22。进一步分析发现,这些ECU在收到会话切换请求时,车速信号仍为有效值(由于产线测试台架未完全断电)。解决方案是在刷写流程前增加一条预处理指令:先发送 0x28 03 抑制应用报文,再发送 0x10 02。同时,在ECU的会话切换条件中增加“车速信号无效或为零”的容错判断。优化后,刷写成功率提升至99.98%。
常见误区
- 误区一:认为编程会话是“永久”的。实际上,ECU在刷写完成后必须通过复位或超时机制退出编程会话,否则应用层程序无法正常运行。
- 误区二:忽略会话切换前的条件检查。部分ECU要求先进入扩展会话(0x03)才能切换到编程会话,或者需要先执行特定的预处理服务。
- 误区三:未处理S3Server超时。刷写过程中若诊断仪暂停发送请求超过5秒,ECU将回退到默认会话,导致后续刷写服务被拒绝。
4.2 安全访问服务(0x27)
核心原理
安全访问服务用于防止未授权的刷写操作。其原理是挑战-应答(Challenge-Response)机制:ECU生成一个随机种子(Seed),诊断仪根据种子和密钥算法计算出密钥(Key),ECU校验密钥是否正确。AUTOSAR中,安全访问算法通常由OEM定义,存储在ECU的NVM中,且不同安全等级对应不同的种子/密钥对。在刷写场景中,通常需要解锁安全等级1(允许刷写)和安全等级2(允许修改校准数据)。
操作流程
- 诊断仪发送
0x27 01请求种子(01表示安全等级1)。 - ECU返回正响应
0x67 01,后跟4字节种子数据(如0x1A 2B 3C 4D)。 - 诊断仪使用内部算法计算密钥,发送
0x27 02,后跟4字节密钥。 - ECU校验密钥:若正确,返回
0x67 02;若错误,返回0x7F 0x27 0x35(无效密钥)并启动延时计数器。
案例拆解:安全访问延时导致的刷写超时
某ECU在刷写测试中,连续两次输入错误密钥后,第三次输入正确密钥仍返回 0x7F 0x27 0x36(超过尝试次数)。测试人员误以为ECU故障,但通过查阅规范发现,ECU在连续失败3次后,会进入延时锁定状态,需等待10秒才能重新请求种子。优化测试脚本:在连续失败后主动等待10秒,再重新执行安全访问流程。此案例提醒我们,安全访问的失败处理机制必须纳入测试用例设计。
常见误区
- 误区一:认为种子长度固定为4字节。实际上,不同ECU的种子长度可能为2字节、4字节或8字节,需根据ECU规范确定。
- 误区二:忽略安全等级。部分ECU要求先解锁等级1,才能解锁等级2,不能直接请求高等级。
- 误区三:未处理延时锁定。测试脚本应包含失败后的等待逻辑,否则会误判ECU故障。
4.3 通信控制服务(0x28)
核心原理
通信控制服务用于控制ECU的通信行为。在刷写场景中,最常用的是抑制应用报文(0x28 03),即关闭ECU应用层周期性发送的CAN报文(如车速、转速、状态信息等)。这样做的目的有两个:一是减少总线负载,为刷写数据提供更多带宽;二是避免应用报文干扰诊断仪与ECU之间的诊断通信。AUTOSAR中,通信控制服务由通信管理器(Communication Manager)实现,可以控制应用报文的发送、接收以及诊断报文的使能。
操作流程
- 诊断仪发送
0x28 03 00(抑制应用报文的发送和接收)。 - ECU返回正响应
0x68 03,表示应用报文已停止。 - 刷写完成后,诊断仪发送
0x28 00 00(恢复通信)或直接执行ECU复位。
0x7F 0x28 0x31(请求超出范围)。
案例拆解:总线负载过高导致刷写失败
某商用车在刷写时,由于其他ECU(如仪表、车身控制器)持续发送大量报文,导致总线负载率超过80%。刷写过程中频繁出现 0x7F 0x36 0x72(传输数据被拒绝)错误。分析发现,刷写数据帧的发送优先级低于应用报文,导致数据帧被延迟。解决方案:在刷写流程中增加 0x28 03 指令,抑制本ECU的应用报文,同时协调其他ECU降低发送频率。优化后,总线负载率降至40%以下,刷写成功率显著提升。
常见误区
- 误区一:忘记恢复通信。刷写完成后若直接复位ECU,通信控制状态会被复位,但若在刷写过程中异常中断,ECU可能一直处于抑制状态,导致应用层无法通信。
- 误区二:抑制范围错误。
0x28 03抑制的是应用报文,但诊断报文(如0x7DF)不受影响。若需要抑制诊断报文,需使用其他参数。 - 误区三:未考虑其他ECU的报文。通信控制只影响本ECU,若总线上其他ECU报文过多,仍需协调处理。
4.4 数据传输服务(0x34/0x36/0x37)
核心原理
数据传输服务是刷写流程的核心,包括三个子服务:请求下载(0x34)、传输数据(0x36)和请求退出传输(0x37)。其原理是:诊断仪将应用程序拆分为多个数据块(Block),每个数据块通过多次0x36请求发送,ECU将数据写入Flash。AUTOSAR中,Flash驱动(Fls)通过Flash抽象层(Fls Interface)管理擦除和写入操作,0x34服务会触发Flash擦除,0x36服务触发数据写入,0x37服务结束传输并校验完整性。
操作流程
- 诊断仪发送
0x34 00 44(请求下载,00表示按地址写入,44表示数据格式),后跟地址和长度信息。 - ECU返回正响应
0x74,后跟最大传输块长度(如0x64表示100字节)。 - 诊断仪发送
0x36 01(块序列号01),后跟最多100字节数据。 - ECU返回
0x76 01,表示该块接收成功。 - 重复步骤3-4,直到所有数据发送完毕。
- 诊断仪发送
0x37,ECU返回0x77,表示传输完成。
0x7F 0x36 0x13(消息长度错误)或 0x7F 0x36 0x31(请求超出范围)。
案例拆解:Flash写入失败与地址对齐
某ECU在刷写时,0x34请求下载成功,但0x36传输数据时返回 0x7F 0x36 0x72(传输数据被拒绝)。通过分析ECU日志,发现请求下载的起始地址为 0x8000,但Flash扇区大小为 0x4000(16KB),导致地址未按扇区对齐。ECU的Flash驱动要求每次擦写必须对齐到扇区边界。解决方案:将起始地址调整为 0x8000 所在扇区的起始地址 0x8000(恰好对齐),并确保数据长度是扇区大小的整数倍。调整后刷写成功。
常见误区
- 误区一:忽略块序列号连续性。部分诊断仪在重发数据时,序列号不重置,导致ECU拒绝接收。
- 误区二:未处理最大传输块长度。若0x36请求的数据长度超过0x34响应中的最大值,ECU会返回错误。
- 误区三:未进行完整性校验。0x37退出传输后,ECU会执行CRC或校验和检查,若数据不完整,ECU会返回错误并拒绝复位。
4.5 刷写流程中的时序与状态管理
核心原理
刷写流程是一个严格的状态机,每个服务必须在正确的状态下执行。AUTOSAR中,Bootloader的状态机通常包括:空闲(Idle)、编程会话(Programming Session)、安全解锁(Security Unlocked)、数据传输中(Data Transfer)和编程完成(Programming Complete)。状态转换由诊断服务触发,任何非法状态转换都会导致负响应。
状态转换表
| 当前状态 | 触发服务 | 下一状态 | 条件 |
|---|---|---|---|
| 默认会话 | 0x10 02 | 编程会话 | 车速为零、发动机停机 |
| 编程会话 | 0x27 01/02 | 安全解锁 | 密钥正确 |
| 安全解锁 | 0x28 03 | 通信抑制 | 无 |
| 通信抑制 | 0x34 | 请求下载 | 地址合法、Flash可擦除 |
| 请求下载 | 0x36 | 数据传输中 | 块序列号连续 |
| 数据传输中 | 0x37 | 编程完成 | 所有数据块发送完毕 |
| 编程完成 | 0x11 01 | 默认会话 | 复位后重新启动 |
案例拆解:状态机异常导致刷写中断
某ECU在刷写过程中,诊断仪发送0x36传输数据时,ECU返回 0x7F 0x36 0x24(子功能不支持)。经排查,发现诊断仪在发送0x34请求下载后,未等待ECU的0x74正响应,而是立即发送0x36。此时ECU仍处于“安全解锁”状态,尚未进入“请求下载”状态,因此拒绝0x36。解决方案:在测试脚本中增加响应等待机制,确保每个服务收到正响应后再发送下一个服务。此案例强调了时序管理在刷写测试中的重要性。
常见误区
- 误区一:忽略状态转换条件。例如,在未完成安全访问时直接发送0x34,ECU会返回
0x7F 0x34 0x33(安全访问被拒绝)。 - 误区二:未处理超时。每个服务都有响应超时时间(如0x36通常为500ms),若诊断仪发送后未在超时时间内收到响应,应重发或终止刷写。
- 误区三:未考虑异常恢复。刷写过程中若发生通信中断,ECU可能停留在中间状态,需通过复位或重新进入编程会话恢复。