第一讲:UDS协议栈基础回顾

各位同学好,我是你们的老朋友。今天咱们开始第一讲,先把UDS协议栈的基础打牢。说实话,我见过太多工程师一上来就调代码,结果连服务分类都搞混,最后定位问题花了三天。所以啊,地基得稳。

1.1 OSI七层模型在UDS中的映射

UDS协议是基于OSI七层模型的,但实际应用中,我们主要关注下面几层。我个人习惯把UDS的协议栈想象成一套快递系统——应用层是包裹内容,会话层是快递单号,传输层是运输车辆,网络层是路线规划,数据链路层是道路,物理层就是那条柏油路。

具体映射关系是这样的:

OSI层 UDS对应层 实际内容
应用层(第7层) UDS应用层 诊断服务(如读取DTC、写入数据)
表示层(第6层) (通常合并到应用层) 数据编码格式
会话层(第5层) UDS会话层 会话控制(默认、扩展、编程)
传输层(第4层) ISO 15765-2(TP层) 多帧传输、流控制
网络层(第3层) ISO 15765-2(网络层) 单帧/多帧寻址
数据链路层(第2层) CAN控制器 CAN帧封装、仲裁
物理层(第1层) CAN收发器 差分信号、电平转换

嗯,这里要注意一点。很多新手以为UDS就是应用层的事,其实不然。我在项目中遇到过一个问题:明明应用层发了正确的诊断请求,但ECU就是不响应。查了半天,发现是传输层的流控制帧没处理好。所以啊,每一层都得懂。

1.2 服务分类:6类26种

UDS定义了6大类服务,总共26种。你想想看,这26种服务就像工具箱里的26把扳手,各有各的用处。我刚开始学的时候,觉得记这么多服务太痛苦了。后来发现,其实核心的就那么几个,其他的用到再查也不迟。

这6大类分别是:

  • 诊断和通信管理类(0x10~0x3E):会话控制、ECU复位、安全访问等。说白了就是管"能不能聊"和"怎么聊"。
  • 数据传输类(0x22~0x2E):读取数据、写入数据、动态定义数据标识符。这是最常用的,我几乎每天都要用0x22读数据。
  • 存储数据传输类(0x14~0x19):读取DTC、清除DTC、读取DTC快照。修车必备,你懂的。
  • 输入输出控制类(0x2F):控制执行器、模拟输入信号。调试硬件时特别好用。
  • 远程激活类(0x31~0x3D):例程控制、启动诊断程序。比如刷写固件时就会用到。
  • 上传下载类(0x34~0x37):请求下载、请求上传、传输数据。刷写Bootloader的核心服务。

具体到每个服务,我这里列个表,方便你对照:

服务ID 服务名称 所属类别
0x10诊断会话控制诊断和通信管理
0x11ECU复位诊断和通信管理
0x14清除诊断信息存储数据传输
0x19读取DTC信息存储数据传输
0x22读取数据标识符数据传输
0x27安全访问诊断和通信管理
0x2E写入数据标识符数据传输
0x2F输入输出控制输入输出控制
0x31例程控制远程激活
0x34请求下载上传下载
0x36传输数据上传下载
0x37请求传输退出上传下载
0x3E测试仪保持连接诊断和通信管理

我的小技巧:刚开始记不住服务ID没关系。你只要记住0x10、0x22、0x19、0x27这几个最常用的就行。其他的,写代码时查一下ISO 14229-1的表格,很快就能上手。

1.3 物理层与CAN总线基础

UDS最常用的物理层就是CAN总线。说白了,CAN总线就是两根线——CAN_H和CAN_L,通过差分信号传输数据。为什么用差分?抗干扰能力强啊。你想想看,汽车发动机舱里电磁干扰那么严重,单端信号早就被淹没了。

CAN总线的几个关键参数:

  • 波特率:常见的有125kbps、250kbps、500kbps。我建议你调试时先用低速,稳定了再切高速。我曾经因为波特率没配对,折腾了一整天。
  • 终端电阻:120欧姆,两端各一个。没有终端电阻,信号会反射,通信就会出错。嗯,这个坑我踩过。
  • CAN帧格式:标准帧(11位ID)和扩展帧(29位ID)。UDS通常用扩展帧,因为诊断地址需要更多的ID空间。

CAN帧的结构是这样的:

SOF | 仲裁场 | 控制场 | 数据场 | CRC场 | ACK场 | EOF
 1bit | 12/32bit | 6bit | 0~64bit | 16bit | 2bit | 7bit

对于UDS来说,数据场里装的就是诊断消息。一个CAN帧最多能装8字节数据。如果诊断消息超过8字节,就需要用到传输层(ISO 15765-2)进行多帧传输了。

避坑指南:我曾经遇到过一个案例,ECU在发送多帧响应时,流控制帧的块大小(BlockSize)设成了0,结果测试工具一直收不到后续帧。后来查标准才发现,块大小为0表示不限制,但有些工具实现得不对。所以啊,建议块大小设成1~5之间,稳妥。

1.4 物理层常见问题

调试UDS时,物理层的问题往往最隐蔽。我总结了几点:

  • CAN_H和CAN_L接反了:这个错误很蠢,但真的会发生。接反了之后,总线上的节点还能通信吗?答案是:不能。因为差分信号反了,接收端读到的数据全是错的。
  • 地线没共地:两个ECU之间如果地电位差太大,CAN收发器会烧掉。我见过一个项目,因为地线接触不良,连续烧了三个收发器。
  • 终端电阻位置不对:终端电阻一定要在总线的最两端。如果放在中间,信号反射会导致通信不稳定。

核心要点:UDS协议栈的每一层都环环相扣。物理层出问题,上层再怎么写代码也没用。所以,调试时先从物理层查起——用示波器看CAN_H和CAN_L的波形,确认电平、波特率、终端电阻都正常,再往上查。

好了,第一讲就到这里。下一讲咱们聊聊诊断会话管理和安全访问,这两个是UDS里最容易出bug的地方。到时候我会分享几个我亲手踩过的坑,保证让你少走弯路。