第1章:刷写协议标准——UDS on CAN概述

大家好,我是老李。做车载ECU开发十几年了,今天咱们聊聊Bootloader刷写里最核心的东西——UDS协议。

说实话,很多新手工程师一上来就啃ISO文档,看得云里雾里。我当年也一样,第一次看ISO 14229-1的时候,差点被那些术语劝退。后来做项目多了才明白,这东西说白了就是一套「车规级对话规则」。

1.1 为什么刷写非得用UDS?

你想想看,ECU刷写不是简单的「发数据、写进去」就完事了。它需要:

  • 诊断会话控制(进入刷写模式)
  • 安全访问(防止非法刷写)
  • 数据传输(分包发送)
  • 完整性校验(确保没写错)
  • 例程控制(擦除、校验等操作)

这些功能,UDS全给你定义好了。我见过有些团队自己搞私有协议,结果每次换芯片都要重新适配,累得半死。用UDS,说白了就是站在巨人肩膀上。

核心观点:UDS on CAN是目前汽车行业最主流的刷写协议栈,没有之一。无论你是做Tier1还是OEM,这套东西必须吃透。

1.2 ISO 14229-1:刷写相关的服务

ISO 14229-1定义了UDS的服务和子服务。刷写场景下,我们最常用的是这几个:

服务ID 服务名称 刷写中的作用
0x10 诊断会话控制 切换到编程会话
0x27 安全访问 解锁刷写权限
0x31 例程控制 擦除Flash、校验完整性
0x34 请求下载 告知ECU我要开始刷了
0x36 传输数据 实际的数据分包发送
0x37 请求传输退出 结束数据传输
0x11 ECU复位 刷完后重启ECU

嗯,这里要注意:0x34请求下载0x36传输数据是刷写的核心。我刚开始做的时候,总搞混这两个服务的时序关系。后来画了个流程图才彻底理清。

我的经验:实际项目中,0x31例程控制经常被用来做Flash擦除和校验。我曾经遇到一个坑——擦除指令发完后,ECU还没擦完就收到了数据包,结果数据全写飞了。所以一定要等例程响应回来再发下一步。

1.3 ISO 15765-2:传输层到底在干嘛?

ISO 15765-2,圈内人叫它「TP层」或者「CanTp」。它的任务很简单:把大包拆成小包,再从小包拼回大包

为什么需要它?因为CAN帧一次最多发8字节数据(CAN 2.0)。你要刷一个256KB的固件,总不能一帧一帧手动拼吧?TP层自动帮你搞定:

  • 单帧(SF):数据≤7字节,一帧搞定
  • 首帧(FF):数据>7字节,先发首帧告知总长度
  • 连续帧(CF):后续数据分包发送
  • 流控帧(FC):接收方告诉发送方「慢点发」或「继续发」

说白了,TP层就是个「快递分拣系统」。我习惯把首帧比作「发货单」,上面写着总共有多少货。连续帧就是「一个个包裹」。流控帧则是「仓库说:别发了,我忙不过来」。

避坑指南:我曾经在一个项目里,ECU的接收缓冲区只有64字节。结果上位机一股脑发了100个连续帧,ECU直接丢包。后来加了流控机制才解决。记住:流控帧不是摆设,一定要用对

1.4 三者的关系

这三个标准不是孤立的。它们的关系是这样的:

  1. ISO 15765-2 负责「怎么传」——数据的分包和重组
  2. ISO 14229-1 负责「传什么」——定义服务的格式和含义
  3. CAN总线 负责「物理传输」——把电信号发出去

打个比方:你要寄一箱书。

  • CAN总线就是快递车
  • ISO 15765-2就是快递员,负责把书分箱打包
  • ISO 14229-1就是快递单,上面写着「这是书,请签收」

三者缺一不可。我见过有人只实现了UDS服务,却忽略了TP层的流控,结果刷写成功率不到50%。

1.5 实际项目中的注意事项

最后,分享几个我在项目中踩过的坑:

  • 超时处理:UDS每个服务都有响应超时。我习惯设P2为50ms,P2*为2000ms。别设太短,ECU擦Flash的时候可能忙不过来。
  • 会话保持:编程会话下,如果长时间不发请求,ECU会自动跳回默认会话。我一般每100ms发个0x3E(测试仪在线)保持会话。
  • 安全访问种子长度:不同ECU的种子长度可能不同。有的用4字节,有的用8字节。写代码时别写死,做成可配置的。

总结一下:UDS on CAN刷写,核心就是理解这三个标准怎么配合。ISO 14229-1定义「做什么」,ISO 15765-2定义「怎么做」,CAN总线提供「做的基础」。下一章,咱们深入讲讲0x34请求下载和0x36传输数据的具体实现。

好了,今天就聊到这儿。有什么问题欢迎交流,咱们下章见。