2、OSI模型与UDS:OSI七层模型回顾、UDS在应用层的定位、诊断通信的物理层与数据链路层
2.1 为什么搞诊断要先聊OSI?
说实话,很多做嵌入式开发的兄弟,一听到OSI七层模型就头疼。觉得这是大学课本里那些搞网络的人才会碰的东西。我以前也这么想。
直到有一次,我在一个项目里排查UDS通信超时问题。应用层代码翻来覆去看了三遍,逻辑完全正确。最后发现,问题出在CAN控制器配置的采样点上——这属于物理层的范畴。从那以后,我养成了一个习惯:遇到诊断通信问题,先从底层往上层捋一遍。
你想想看,UDS诊断说白了就是「两个ECU之间说悄悄话」。但这句话要能说通,得经过好几层「翻译」和「运输」。OSI模型就是帮我们理清这个过程的工具。
核心观点:UDS不是凭空跑在总线上的。它依赖物理层、数据链路层、网络层、传输层一层层往上托。哪一层出问题,诊断都玩不转。
2.2 OSI七层模型快速回顾
我不打算把七层模型从头到尾念一遍。咱们挑跟UDS诊断最相关的几层说。
| OSI层 | UDS中的角色 | 我关注的点 |
|---|---|---|
| 第7层 应用层 | UDS服务本身(比如诊断会话控制、读取数据) | 服务ID、子功能、数据格式 |
| 第6层 表示层 | 数据编码(Intel/Motorola格式) | 字节序、符号扩展 |
| 第5层 会话层 | 诊断会话管理(默认/扩展/编程会话) | 会话状态机、超时处理 |
| 第4层 传输层 | 多帧传输(ISO 15765-2) | 流控制、连续帧、时间参数 |
| 第3层 网络层 | CAN ID过滤、路由 | 物理寻址、功能寻址 |
| 第2层 数据链路层 | CAN帧封装、错误检测 | 帧格式、ACK机制 |
| 第1层 物理层 | CAN总线电平、位时序 | 采样点、终端电阻 |
嗯,这张表我建议你保存下来。调试的时候对照着看,能省不少时间。
2.3 UDS在应用层的定位
UDS(ISO 14229)严格来说属于应用层协议。它定义的是「诊断仪和ECU之间怎么对话」,而不是「数据怎么在线上传输」。
举个例子:
// 这是应用层的内容
诊断请求: 0x10 0x03 // 诊断会话控制 - 扩展会话
诊断响应: 0x50 0x03 0x00 0x32 0x01 0xF4 // 肯定响应 + 会话参数
这段数据到了传输层,会被拆成CAN帧。到了物理层,变成差分信号在总线上跑。但UDS本身只关心「0x10 0x03」这个请求的含义,不关心它怎么变成电信号的。
我的习惯:写UDS代码时,我会把应用层逻辑和底层通信接口严格分开。应用层只处理服务ID、子功能、数据格式。底层通信只负责收发CAN帧。这样哪层出问题,一眼就能看出来。
2.4 诊断通信的物理层
物理层,说白了就是「线缆和电平」。在车载诊断里,最常见的就是CAN总线。
我记得刚入行时,有个项目总是偶发性诊断通信失败。查了半个月代码,最后发现是终端电阻焊错了位置。物理层的问题,有时候就是这么隐蔽。
物理层关键参数:
- 总线电平:CAN_H和CAN_L的差分电压,显性位约2V,隐性位约0V
- 波特率:常见的有125kbps、250kbps、500kbps。诊断通信通常用500kbps
- 采样点:我建议设置在75%-85%之间。采样点太靠前或太靠后,都容易误判位
- 终端电阻:CAN总线两端各一个120Ω电阻。少了信号反射,多了驱动能力不足
避坑指南:我曾经在一个项目里,发现诊断仪连不上ECU。用示波器一看,CAN总线波形乱七八糟。最后发现是线束太长,超过了CAN总线的最大长度限制。物理层的问题,示波器是最好的朋友。
2.5 诊断通信的数据链路层
数据链路层负责把物理层的「0和1」组织成有意义的帧。在CAN总线里,就是CAN帧。
CAN帧结构(数据帧):
| SOF | 仲裁场 | 控制场 | 数据场 | CRC场 | ACK场 | EOF |
| 1 | 12/32 | 6 | 0-64 | 16 | 2 | 7 |
对于UDS诊断来说,最关心的是仲裁场和数据场。
- 仲裁场:包含CAN ID。诊断通信中,CAN ID决定了这条消息是请求还是响应,是物理寻址还是功能寻址
- 数据场:最多8字节(CAN 2.0)。UDS的请求/响应数据就放在这里。如果数据超过8字节,就需要传输层来处理多帧
诊断CAN ID分配(常见做法):
| 方向 | CAN ID(11位) | 说明 |
|---|---|---|
| 诊断请求(物理寻址) | 0x7E0 - 0x7E7 | 通常0x7E0给诊断仪 |
| 诊断响应(物理寻址) | 0x7E8 - 0x7EF | 对应请求ID + 8 |
| 诊断请求(功能寻址) | 0x7DF | 广播给所有ECU |
你想想看,如果数据链路层的CAN ID配错了,ECU根本收不到诊断请求。应用层写得再好也没用。
2.6 我的调试经验总结
做了这么多年UDS诊断,我总结了一个排查思路:
- 先看物理层:示波器量一下CAN_H和CAN_L的波形。看电平对不对,有没有毛刺
- 再看数据链路层:用CAN分析仪抓一下总线上的帧。看CAN ID对不对,帧格式对不对
- 然后看网络层/传输层:检查多帧传输的流控制帧有没有按时发
- 最后看应用层:UDS服务ID、子功能、数据格式是否正确
记住:80%的诊断通信问题,出在物理层和数据链路层。别一上来就怀疑UDS协议栈有bug。
好了,这一章我们聊了OSI模型和UDS的关系,重点讲了物理层和数据链路层。下一章,我们会深入传输层,看看UDS的多帧传输是怎么实现的。