4、CAN FD应用层协议基础:UDS on CAN FD概述、ISO 14229-1标准在CAN FD上的映射、诊断会话控制

好,咱们进入第四讲。前面几章我们把CAN FD的物理层、数据链路层和传输层都捋了一遍。从这一章开始,咱们要聊点真正“应用”层面的东西了——UDS on CAN FD。

说实话,UDS(统一诊断服务)在传统CAN上已经非常成熟了。但到了CAN FD时代,很多老工程师习惯性地把那一套直接搬过来用。我个人觉得,这其实是个坑。为什么?因为CAN FD的带宽和payload长度都变了,协议栈的映射方式也得跟着调整。

4.1 UDS on CAN FD概述

UDS,全称是Unified Diagnostic Services,定义在ISO 14229-1标准里。它是一套汽车电子控制单元(ECU)的通用诊断协议。说白了,就是让诊断仪(Tester)和ECU之间能说上话,能读故障码、刷写软件、配置参数等等。

在CAN FD上跑UDS,本质上和传统CAN没太大区别。但有几个关键点你得注意:

  • 物理层兼容:UDS on CAN FD仍然使用CAN FD的物理层,速率可以到2Mbps甚至更高。我遇到过一些项目,为了兼容老设备,故意把速率降到500kbps,结果CAN FD的优势全没了。嗯,这里要提醒一下,如果你要用CAN FD做OTA,速率别降太低。
  • 数据链路层:CAN FD的数据场最长可以到64字节。这意味着UDS的单个请求/响应可以塞进一帧里,不需要像传统CAN那样频繁地做流控制(FC)和分段传输(Segmentation)。
  • 传输层适配:ISO 15765-2(DoCAN)在CAN FD上做了扩展,支持更大的PDU(协议数据单元)。我个人习惯,在CAN FD上做UDS时,尽量把单帧(SF)控制在64字节以内,这样能省掉很多传输层的麻烦。

核心观点:UDS on CAN FD不是简单的“把CAN换成CAN FD”,而是要从协议栈的每一层重新审视。尤其是传输层,64字节的payload让很多传统设计变得多余。

4.2 ISO 14229-1标准在CAN FD上的映射

ISO 14229-1定义了UDS的服务和协议,但它不关心底层是CAN、LIN还是以太网。所以,我们需要一个“映射层”,把UDS的抽象服务翻译成CAN FD能理解的东西。

这个映射主要涉及两个方面:

4.2.1 寻址方式

在CAN FD上,UDS的寻址方式和传统CAN一样,分为物理寻址和功能寻址。

  • 物理寻址:一对一的通信。诊断仪发一个请求,只有目标ECU响应。CAN ID通常由源地址和目标地址组合而成。
  • 功能寻址:一对多的通信。诊断仪发一个请求,所有支持该功能的ECU都会响应。CAN ID通常是固定的功能地址。

这里有个坑:CAN FD的ID段仍然是29位(扩展帧)或11位(标准帧)。我见过有人把功能寻址的ID设成和物理寻址一样,结果多个ECU同时响应,总线直接冲突。避坑指南:我曾经在一个项目中,因为功能寻址ID配置错误,导致OTA刷写时多个ECU同时回复,总线负载瞬间爆表。后来我们强制规定:功能寻址ID必须和物理寻址ID的高位不同,并且用DLC(数据长度码)来区分。

4.2.2 服务映射

UDS的服务(比如10 03诊断会话控制、22 01读取数据等)在CAN FD上怎么封装?很简单,还是用N_PDU(网络协议数据单元)。

举个例子,一个UDS请求“10 03”在CAN FD上的典型帧结构如下:

CAN ID: 0x7DF (功能寻址)
DLC: 8 (或更多,取决于CAN FD)
Data: [PCI] [SID] [Sub-function] [Data...]
// PCI: 协议控制信息,比如单帧、首帧、流控制帧等
// SID: 服务ID,比如0x10代表诊断会话控制
// Sub-function: 子功能,比如0x03代表扩展诊断会话

在CAN FD上,因为数据场可以到64字节,所以PCI的格式也做了调整。比如单帧(SF)的PCI长度字段可以表示0-63字节的数据。我建议你仔细看看ISO 15765-2的CAN FD扩展部分,里面定义了新的PCI格式。

个人经验:在CAN FD上做UDS映射时,我习惯把SID和Sub-function放在数据场的前两个字节,后面紧跟数据。这样解析起来最直观,也方便调试。你想想看,如果数据场有64字节,你把SID藏在中间,调试的时候找半天,多浪费时间。

4.3 诊断会话控制

诊断会话控制(Diagnostic Session Control)是UDS里最基础的服务,服务ID是0x10。它用来切换ECU的工作模式。常见的会话有:

  • 默认会话(Default Session):0x01。ECU上电后的默认状态,只允许执行一些基础诊断服务(比如读取故障码)。
  • 编程会话(Programming Session):0x02。用于刷写软件,允许执行0x34(请求下载)、0x36(传输数据)等服务。
  • 扩展诊断会话(Extended Diagnostic Session):0x03。用于更复杂的诊断,比如读写配置参数、执行例程等。
  • 安全系统诊断会话(Safety System Diagnostic Session):0x04。用于安全相关的ECU,比如安全气囊控制器。

在CAN FD上,诊断会话控制的实现和传统CAN完全一样。但有一个细节:会话切换后,ECU可能会改变CAN FD的通信参数。比如,从默认会话切换到编程会话时,ECU可能会把CAN FD的速率从500kbps提升到2Mbps,以加快刷写速度。

我记得有一次做OTA项目,ECU在编程会话下把速率提到了2Mbps,但诊断仪没跟上,结果通信直接断了。后来我们加了一个“速率协商”机制:ECU在切换会话前,先发一个响应告诉诊断仪“我要提速了”,诊断仪确认后再切换。嗯,这个细节在ISO 14229-1里没有强制要求,但实际项目中非常实用。

注意事项:诊断会话切换是有时间限制的。ECU收到“10 03”请求后,必须在规定时间内(通常是50ms)响应。如果超时,ECU会自动回到默认会话。在CAN FD上,因为数据帧变长,处理时间可能会增加。我曾经遇到过因为CAN FD驱动处理不及时,导致会话切换超时的问题。解决方案是:在CAN FD中断服务程序里,把UDS协议栈的处理优先级提高。

最后,总结一下这一章的核心:

  • UDS on CAN FD不是简单的移植,要重新审视传输层和寻址方式。
  • ISO 14229-1的映射主要关注PCI格式和CAN ID分配。
  • 诊断会话控制是OTA刷写的基础,注意速率切换和超时处理。

下一章,我们会深入聊UDS的另一个核心服务——安全访问(Security Access)。这个在OTA里至关重要,因为刷写软件前必须通过安全认证。咱们到时候见。