第一讲: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 | 诊断会话控制 | 诊断和通信管理 |
| 0x11 | ECU复位 | 诊断和通信管理 |
| 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的地方。到时候我会分享几个我亲手踩过的坑,保证让你少走弯路。