车载底层 CAN 通信与上层 UDS 诊断协议开发技术文档

一、CAN 总线

1.1、概述

CAN(Controller Area Network)是一种串行、异步、多主控的现场总线标准。

兼容性

  • CAN FD 控制器可以兼容并识别经典 CAN 的报文,但经典 CAN 节点无法处理 CAN FD 报文。在一个混合网络中,需要所有节点都支持 FD 才能使用 FD 功能。
  • CAN XL 的帧格式与 CAN FD 和经典 CAN 不同,无法在同一个网络中混合使用不同帧类型。但 CAN XL 控制器通常设计为向下兼容,能够识别和处理 CAN FD 及经典 CAN 报文。
特性经典 CAN (CAN 2.0)CAN FD (灵活数据速率)CAN XL
最大比特率1 Mbps仲裁段:1 Mbps数据段: 最高 8 Mbps(部分可达 10 Mbps+)仲裁段:1 Mbps数据段: 最高 20 Mbps(常见为 10-15 Mbps)
最大数据载荷8 字节64 字节2048 字节
协议层数据链路层数据链路层增加了网络层功能
帧格式标准帧 / 扩展帧在经典 CAN 基础上改进,有 FDF 位全新的帧格式,与 CAN/CAN FD 不兼容
主要优势简单、稳定、成本低带宽更高,数据长度更长,兼容经典 CAN超高带宽,超大数据包,适合车载以太网等场景的互联
主要应用车身控制、ECU 通信等低速控制汽车诊断、ECU 刷写、车载网络主干自动驾驶、车载高速传感器数据、区域控制器互联

三种 CAN 的负载与速率关系:

  • CAN 一帧负载 8 个字节
  • CAN FD 一帧最大可以负载 64 个字节(数据段最高 8 Mbps)
  • CAN XL 一帧最大可以负载 2048 字节(数据段最高 20 Mbps)

三者的仲裁阶段都是 1 Mbps 速率。

ISO 11898 标准定义了两种物理层:

  • ISO 11898-2:高速闭环 CAN,通信速率 125 Kbps~1 Mbps,总线长度 ≤ 40 米时最大可达 1 Mbps。
  • ISO 11898-3:低速开环 CAN(也叫低速容错 CAN),通信速率 10~125 Kbps,传输速率 40 Kbps 时总线距离可达 1000 米。

CAN 采用总线型拓扑结构,两端各有一个 120 欧姆的终端电阻,用于阻抗匹配、消除信号反射。

总线拓扑示意图

 节点1     节点2     节点3         节点N
  |         |         |            |
  +---------+---------+----....-----+
  |                                |
 [120Ω]                          [120Ω]
  |                                |
 GND                              GND
  • 每个节点通过 CAN 控制器和 CAN 收发器连接到 CAN_H 和 CAN_L 两条差分信号线
  • 总线两端各接一个 120Ω 终端电阻

1.2、特性

  1. 多节点间可通信,节点数实际可达 110 个。
  2. 采用短帧结构,报文帧的有效字节为 8 个(经典 CAN)。
  3. 报文 ID 值越小,优先级越高。
  4. 非破坏性总线仲裁处理机制(仲裁段;线与机制;ID 越小优先级越高;仲裁失败进入只听模式)。
  5. 可靠的 CRC 校验方式,数据传送出错率极低。
  6. 报文帧仲裁失败或传输期间被破坏,有自动重发机制。
  7. 节点在错误严重的情况下,具有自动脱离总线的功能,切断与总线的联系,不影响总线的正常工作。
  8. 通信距离最远可达 10 km(速率 5 Kbps 以下)。
  9. 通信速率最高 1 Mbps(此时最长距离 40 m)。
  10. CAN 节点设计成本低,通信介质采用双绞线。

CAN 节点内部结构

         MCU/CPU
            |
    +------+------+
    |             |
  TX 引脚      RX 引脚
    |             |
    v             ^
 CAN 控制器 (内置或外挂,如 MCP2515)
    |             |
    v             ^
 CAN 收发器 (如 TJA1050 / SN65HVD230)
    |             |
    +------+------+
    |             |
  CAN_H        CAN_L
    |             |
    +-----+-------+
          |
      双绞线总线

1.2.1、CAN 与 CAN FD 对比

特性经典 CAN (CAN 2.0)CAN FD
最高速率通常 1 Mbps仲裁段:与经典 CAN 相同(≤ 1 Mbps)数据段:最高 5 Mbps(CAN FD Non-ISO)或 8 Mbps(CAN FD ISO),实际可达 10 Mbps 以上
数据场长度最大 8 字节最大 64 字节
帧格式标准帧(11 位 ID)、扩展帧(29 位 ID)在标准/扩展帧基础上,引入了新的 FDF (FD Frame) 和 BRS (Bit Rate Switch) 位
兼容性向后兼容:CAN FD 节点可以正确接收经典 CAN 报文,但经典 CAN 节点无法正确解析 CAN FD 报文(会报错)
CRC 校验15 位 CRC更强大的 CRC 校验:17 位(数据长度 ≤ 16 字节)或 21 位(数据长度 > 16 字节)

1.3、物理层

CAN 和 CAN FD 在物理层上基本相同,它们都使用差分信号进行数据传输,这赋予了其卓越的抗干扰能力。

  • 传输介质:通常是一对双绞线(CAN_H 和 CAN_L)。
  • 逻辑电平
    • 显性位:表示逻辑 '0',CAN_H 约 3.5V,CAN_L 约 1.5V,差分电压约 2.0V(ISO 11898-2 阈值 > 0.9V)。
    • 隐性位:表示逻辑 '1',CAN_H 和 CAN_L 均偏置到约 2.5V,差分电压接近于 0V(典型值 < 0.5V)。
  • 拓扑结构:总线型结构,两端各有一个 120 欧姆的终端电阻,用于阻抗匹配,消除信号反射。
  • 节点:每个节点通过一个 CAN 控制器和 CAN 收发器连接到总线。

注意:虽然物理层相同,但为了支持 CAN FD 更高的数据段速率,对物理通道(收发器、线缆等)的延迟时间和信号质量提出了更严格的要求。使用支持 CAN FD 的高速收发器是必要条件。

逻辑电平定义

逻辑值定义CAN_H 电压CAN_L 电压差分电压 (CAN_H - CAN_L)
显性 (Dominant)逻辑 '0'~3.5V~1.5V> 1.5V
隐性 (Recessive)逻辑 '1'~2.5V~2.5V≈ 0V

收发器工作原理:CAN 收发器负责将 MCU 的 TX 引脚输出的逻辑电平转换为 CAN_H/CAN_L 的差分信号,并将接收到的差分信号转换为 RX 引脚的逻辑电平。逻辑信号和物理信号之间的转换采用差分电平方式。

MCU 与 CAN 收发器连接示意

  MCU 端                         CAN 收发器端
  ───────                        ────────────
  TX 引脚 ──── 逻辑电平 ────► 转换为 CAN_H/CAN_L 差分信号
  RX 引脚 ◄──── 逻辑电平 ◄──── 从 CAN_H/CAN_L 差分信号恢复

1.3.1、常见问题与解答

1. 为什么要采用两根线(双绞线)的差分电平信号?

答:双绞线传输差分信号时,共模干扰会同时作用于两根线,接收端做差分后电平差值不变,信号解码正常。这是差分信号抗共模干扰的核心原理。

2. 如何减少波特率的误差带来的通信错误?

答:CAN 总线规定在信号的跳变沿时刻进行同步,将误差累积限制在两个跳变沿之间,避免误差持续累积。

3. 当发送数据出现连续多个 0 或 1 时,没有跳变沿造成的误差累积怎么办?

答:发生多个相同位时没有跳变沿用于同步,导致误差不断累积。采用位填充(Bit Stuffing):在连续 5 个相同位后插入一个相反位,产生跳变沿用于同步。

4. 由于阻抗不连续、阻抗不匹配造成的信号反射、波形震荡,导致信号串扰、信息丢失,怎么办?

答:高速 CAN 在总线两端各加 1 个终端电阻(汽车电子领域一般使用 120 欧姆),用于减少通信线路上的反射,避免引起电平变化导致的传输错误。

5. 所有在测的 ECU 节点 CAN 功能单独测试正常,但装车后 CAN 功能失常,可能仪表紊乱、CAN 错误频发,怎么办?

重点考虑:

  • 选择一个性能好的隔离收发器,或外部隔离收发器
  • 增加 CAN 线缆双绞程度,保证差模信号抗干扰能力
  • 布线时将动力线缆和 CAN 线缆远离,抑制周期脉冲干扰
  • CAN 端增加共模滤波器等抗浪涌效果好的感性防护器件

1.4、链路层

1.4.1、CAN FD 数据帧字段详解

字段区块字段名称位数值类型关键功能说明
帧起始段SOF (Start of Frame)1显性 '0'帧起始同步位,所有节点通过此位实现硬同步,标志新帧开始
仲裁段仲裁场 (Arbitration Field)11/29报文标识符:标准帧 11 位;扩展帧 29 位(11 位基 ID + 18 位扩展 ID)。数值越小优先级越高
RTR (Remote Transmission Request)1显性 '0'远程传输请求位:数据帧中固定为显性 '0';远程帧中为隐性 '1'(现已较少使用)
IDE (Identifier Extension)1标准帧:显性 '0',扩展帧:隐性 '1'标识符扩展位:标识该帧为标准帧还是扩展帧
FDF (FD Format)1隐性 '1'CAN FD 核心标识位:恒为隐性 '1',标识此为 CAN FD 帧。经典 CAN 节点检测到此位会报错
r0 (Reserved Bit 0)1显性 '0'保留位:CAN FD 中固定发送显性 '0',为未来协议扩展预留
控制段DLC (Data Length Code)40–15数据长度码:编码 0–8 对应 0–8 字节;编码 9–15 对应 12, 16, 20, 24, 32, 48, 64 字节
BRS (Bit Rate Switch)1显性 '0' 或隐性 '1'位速率切换开关:显性 '0' 全程仲裁速率;隐性 '1' 数据段切换至更高速率
ESI (Error State Indicator)1显性 '0' 或隐性 '1'错误状态指示器:显性 '0' 节点处于主动错误状态;隐性 '1' 节点处于被动错误状态
数据段数据场 (Data Field)0–64 字节有效数据载荷:长度由 DLC 字段决定,最大 64 字节,是经典 CAN 的 8 倍。此段可能使用更高速率传输
校验段CRC 场 (Cyclic Redundancy Check)17 或 21增强型循环冗余校验:数据长度 ≤ 16 字节使用 17 位 CRC;> 16 字节使用 21 位 CRC
CRC 分隔符 (CRC Delimiter)1隐性 '1'CRC 字段结束标记,波特率在此切回仲裁速率
确认段ACK 槽 (ACK Slot)1隐性 '1' → 显性 '0'应答时隙:发送器发送隐性 '1',正确接收的节点用显性 '0' 覆盖
ACK 分隔符 (ACK Delimiter)1隐性 '1'应答定界符:固定为隐性 '1',确保 ACK 槽被正确界定
结束段EOF (End of Frame)7隐性 '1'帧结束标记:连续 7 个隐性 '1',标志本帧传输完全结束

1.4.2、DLC 编码表

DLC 值数据长度(字节)
0–80–8
912
1016
1120
1224
1332
1448
1564

1.4.3、CRC 序列

数据长度 ≤ 16 字节时使用 17 位 CRC,> 16 字节时使用 21 位 CRC。此外,CRC 段还包含 3 个固定填充位(在 CRC 序列之前插入),用于提升高速传输的可靠性。

1.4.4、ESI 位

ESI 位是发送节点的错误状态指示器:

  • ESI = 0:发送节点处于主动错误状态(TEC < 128)
  • ESI = 1:发送节点处于被动错误状态(TEC > 127)

节点进入被动错误状态后仍可继续通信,但会影响错误处理行为。

1.4.5、经典 CAN 与 CAN FD 帧结构对比

字段段落字段名称经典 CANCAN FD说明与差异
1. 帧开始SOF1 位 '0'1 位 '0'相同。一个显性位,标志帧开始。
2. 仲裁段标识符 (ID)11 或 29 位11 或 29 位基本相同。决定报文优先级。此阶段使用较低的仲裁波特率
RTR1 位 '0'(数据帧)1 位 '0'(数据帧)相同。数据帧中为显性位。
3. 控制段IDE1 位1 位相同。区分标准帧与扩展帧。
FDF无(或视为隐性 r0)1 位 '1'核心区别。隐性 '1' 表明这是 CAN FD 帧。经典 CAN 节点看到此位会产生错误并忽略该帧。
BRS不适用1 位核心区别。'0' 数据段不加速;'1' 数据段切换到更高的波特率
ESI不适用1 位新增。'1' 发送节点处于被动错误状态;'0' 处于主动错误状态。
DLC4 位(0–8 字节)4 位(0–64 字节)扩展。CAN FD 的 DLC 编码表被扩展以支持最多 64 字节的数据。
4. 数据段Data Field0–8 字节0–64 字节核心区别。CAN FD 的数据负载能力大幅提升。此阶段可能使用更高的数据段波特率
5. CRC 段CRC Sequence15 位17 或 21 位增强。CAN FD 使用更长的 CRC 来保障更大数据块和更高速度下的可靠性。
CRC Delimiter1 位 '1'1 位 '1'相同。一个隐性位。
6. 应答段ACK Slot1 位1 位相同。发送器发 '1',接收器覆写为 '0' 来应答。
ACK Delimiter1 位 '1'1 位 '1'相同。一个隐性位。
7. 帧结束EOF7 位 '1'7 位 '1'相同

1.4.6、CAN FD 数据帧逐段说明

1. 帧起始 (SOF)

一个显性位('0')。标志一帧的开始,用于同步网络上所有节点。

2. 仲裁场

决定报文的优先级。标识符 ID 值越小,优先级越高。

  • 标识符:标准帧为 11 位,扩展帧为 29 位(包含 11 位基 ID + 18 位扩展 ID)。
  • RTR 位:在数据帧中,此位为显性('0')。
  • IDE 位:标准帧为显性('0'),扩展帧为隐性('1')。
  • FDF 位CAN FD 新增! 此位为隐性('1'),表示这是一个 CAN FD 帧。经典 CAN 帧中,这个位置是保留位,通常为显性('0')。这是区分两种帧的关键。
  • r0 位:保留位,显性('0')。

3. 控制场

传递关于数据长度的信息和控制位。

  • DLC:4 位,表示数据场的字节数。在 CAN FD 中,DLC 的编码方式与经典 CAN 不同,以支持 0–64 字节。
  • BRS 位CAN FD 新增! 位速率切换开关。
    • 显性('0'):不切换,整个帧使用相同的波特率(仲裁速率)。
    • 隐性('1'):从 BRS 位之后到 CRC 定界符之前,切换到更高的数据速率
  • ESI 位CAN FD 新增! 错误状态指示。
    • 显性('0'):节点处于主动错误状态
    • 隐性('1'):节点处于被动错误状态

4. 数据场

实际要传输的有效数据。长度由 DLC 指定,CAN FD 中为 0 到 64 字节

5. CRC 场

循环冗余校验,用于检测传输错误。CAN FD 的增强:

  • 由于数据更长、速率更高,出错的概率增大。
  • CAN FD 使用了更长的 CRC 序列(17 位或 21 位)和受保护填充位,极大地提升了校验能力。
  • CRC 定界符:一个固定的隐性位('1'),标志 CRC 字段结束。

6. 应答场

接收节点确认是否正确接收到报文。

  • ACK Slot:发送节点发出一个隐性位('1')。任何正确接收到该帧的接收节点(无论其是否对该数据感兴趣),都会在此时间段内向总线发送一个显性位('0')来覆盖它。
  • ACK Delimiter:一个隐性位('1'),保证 ACK Slot 被正确界定。

7. 帧结束

连续 7 个隐性位('1'),标志该帧传输结束。

1.4.7、报文帧种类

CAN 报文帧共有以下五种类型:

帧类型说明
数据帧发送节点向接收节点传送数据,使用最多的帧类型
远程帧接收节点向某个发送节点请求数据
错误帧当某个节点检测出错误时,向其他节点发送通知错误的帧
过载帧用于接收节点向发送节点通知自身接收能力的帧
帧间隔将数据帧或远程帧与前面的帧分离的帧

1.4.8、标准帧与扩展帧的 7 段结构

标准帧和扩展帧均包含以下 7 个段:

段序号段名称说明
1帧起始 (SOF)1 位显性位,标志帧开始
2仲裁段包含 ID(11 位或 29 位)、RTR、IDE 等
3控制段包含 DLC、FDF(CAN FD)、BRS(CAN FD)、ESI(CAN FD)等
4数据段有效载荷,0–8 字节(经典 CAN)或 0–64 字节(CAN FD)
5CRC 段循环冗余校验码 + 定界符
6应答段 (ACK)ACK 槽 + ACK 定界符
7帧结束 (EOF)7 位隐性位

标准帧格式(11 位 ID)

SOF | 11位ID | RTR | IDE(0) | r0 | DLC | 数据段(0-8字节) | CRC | ACK | EOF

扩展帧格式(29 位 ID)

SOF | 11位基ID | SRR(1) | IDE(1) | 18位扩展ID | RTR | r1 | r0 | DLC | 数据段 | CRC | ACK | EOF

1.4.9、非破坏性仲裁机制

CAN 总线采用非破坏性逐位仲裁机制(CSMA/CD + 优先级仲裁):

仲裁过程

假设节点 A 发送 ID = 0x15 (0010101),节点 B 发送 ID = 0x1F (0011111)

 位序号:   0    1    2    3    4    5    6
 A发送:   [0]  [0]  [1]  [0]  [1]  [0]  [1]
 B发送:   [0]  [0]  [1]  [1]  [1]  [1]  [1]
          |    |    |     |
        相同  相同 相同   不同!
                          |
                          v
               B 发送 1 (隐性), 但检测到总线上是 0 (显性)
               → B 仲裁失败,进入只听模式
               → A 继续发送,仲裁成功

 规则: 显性位 '0' 覆盖隐性位 '1'(线与机制)
       ID 越小 → 越早出现 '0' → 优先级越高

仲裁失败后的行为

  • 仲裁失败的节点立即停止发送,进入"只听"模式
  • 仲裁成功的节点继续发送,不受影响
  • 仲裁失败的节点会在当前帧结束后自动重试

1.4.10、CAN 错误类型与处理

错误状态分类

状态条件行为
主动错误TEC < 128 且 REC < 128正常参与通信,检测到错误时发送主动错误标志(6 个连续显性位)
被动错误TEC ≥ 128 或 REC ≥ 128正常参与通信,检测到错误时发送被动错误标志(6 个连续隐性位)
总线关闭TEC ≥ 256节点脱离总线,不再参与通信

CAN 错误计数规则(简化版)

场景计数变化
接收节点检测到错误REC + 1
发送节点检测到错误TEC + 8
接收节点发送主动错误标志REC + 8(特定条件下)
成功发送一帧TEC - 1(TEC > 0 时)
成功接收一帧REC - 1(REC > 0 时)

详细规则参考 ISO 11898-1 中的错误管理部分。

错误恢复流程

主动错误状态 ──(TEC≥128)──► 被动错误状态 ──(TEC≥256)──► 总线关闭
     ▲                          │
     │        (TEC<128)         │
     └──────────────────────────┘
     
总线关闭后,节点需等待 128 次 11 位隐性位序列,才能恢复为主动错误状态(TEC 和 REC 清零)。

1.5、CAN FD 增强特性

CAN FD 在经典 CAN 基础上做了以下关键增强:

速率提升机制

仲裁段 (标准速率 ≤ 1 Mbps)               数据段 (高速率 ≤ 8 Mbps)              仲裁段 (标准速率)
  ◄──────────────────────────►  ◄──────────────────────────────────────►  ◄──────────────►
  SOF | ID | 控制 | BRS='1'  →  数据场 (0-64 字节) | CRC | CRC定界符  →  ACK | EOF
                                ↑ 速率切换点                        ↑ 切回仲裁速率

CAN FD 相比经典 CAN 的核心优势

增强项经典 CANCAN FD收益
数据负载8 字节64 字节8 倍负载提升,减少帧数
数据段速率与仲裁段相同可独立提升至 8 Mbps有效吞吐率大幅提升
CRC 校验15 位17/21 位 + 固定填充位更强的错误检测能力
错误状态仅节点内部ESI 位广播网络诊断能力增强

1.6、兼容性问题

经典 CAN 与 CAN FD 混合网络注意事项

场景结果
CAN FD 帧发送到经典 CAN 节点经典 CAN 节点检测到 FDF 位为隐性 '1'(它认为是保留位错误),产生错误帧并忽略该报文
经典 CAN 帧发送到 CAN FD 节点CAN FD 节点正确接收,无兼容性问题
混合网络中同时存在两种节点必须所有参与 FD 通信的节点都支持 CAN FD,否则 FD 帧会被经典 CAN 节点破坏

CAN XL 兼容性

场景结果
CAN XL 节点收到 CAN FD / 经典 CAN 帧可识别并处理(向下兼容)
CAN FD / 经典 CAN 节点收到 CAN XL 帧无法识别,会产生错误
混合网络CAN XL 帧格式与 CAN FD/经典 CAN 完全不同,无法在同一网络中混合使用

二、UDS 诊断协议

2.1、概述

UDS(Unified Diagnostic Services,统一诊断服务)诊断协议即 ISO 14229 协议,是在汽车电子 ECU 环境下的一种诊断通信协议。

UDS 是一种定向通信的交互协议(Request/Response),诊断方(Tester)发送服务请求,ECU 返回响应(肯定响应/否定响应)。

UDS 请求/响应交互流程

  Tester (诊断工具)                          ECU (电子控制单元)
       |                                          |
       |  ──── 请求 (Request) ────►               |
       |     SID + SubFunction + Data             |
       |                                          |
       |  ◄──── 响应 (Response) ────               |
       |     肯定响应: SID+0x40 + Data             |
       |     否定响应: 0x7F + SID + NRC            |
       |                                          |

背景知识:截止到 2020 年,UDS 诊断由以下 8 个部分组成:

  • ISO 14229-1-2020:规范和要求
  • ISO 14229-2-2013:会话层服务
  • ISO 14229-3-2012:CAN 实现的统一诊断服务(UDSonCAN)
  • ISO 14229-4-2012:FlexRay 实现的统一诊断服务(UDSonFR)
  • ISO 14229-5-2013:Internet 协议实现的统一诊断服务(UDSonIP)
  • ISO 14229-6-2013:K 线实现的统一诊断服务(UDSonK-Line)
  • ISO 14229-7-2015:本地互联网络实现的统一诊断服务(UDSonLIN)
  • ISO 14229-8-2020:时钟扩展外围接口实现的统一诊断服务(UDSonCXPI)

2.2、服务 ID 总览

UDS 服务按功能单元分类,常用服务如下:

SID (HEX)服务名称说明
10诊断会话控制 (Diagnostic Session Control)切换 ECU 的诊断会话模式(默认/扩展/编程)
11电控单元复位 (ECU Reset)复位 ECU,复位后激活默认会话
14清除诊断信息 (Clear Diagnostic Information)清除 ECU 中存储的故障码和诊断信息
19读取诊断故障代码信息 (Read DTC Information)读取 ECU 存储的故障码(DTC)及相关状态
22根据标识符读取数据 (Read Data By Identifier)按标识符(DID)读取数据,如车速、电压
23读取内存 (Read Memory By Address)按地址读取内存数据
24按标识符读取换算数据 (Read Scaling Data By Identifier)按标识符读取带换算公式的数据
27安全访问 (Security Access)安全解锁,用于刷写软件等敏感操作
28通讯控制 (Communication Control)控制 ECU 消息的发送和接收(禁言/恢复)
2A读取数据(周期标识符)(Read Data By Periodic Identifier)周期性读取数据
2C动态定义数据标识符 (Dynamically Define Data Identifier)动态定义新的数据标识符
2E根据标识符写入数据 (Write Data By Identifier)按标识符写入数据,如修改配置
2F根据标识符输入输出控制 (Input Output Control By Identifier)控制 ECU 的 IO 端口
31例程控制 (Routine Control)触发 ECU 执行特定例程,如自检
34请求下载 (Request Download)客户端请求向 ECU 传输数据(刷写)
35请求上传 (Request Upload)客户端请求从 ECU 读取数据
36传输数据 (Transfer Data)实际传输数据块
37请求传输终止 (Request Transfer Exit)终止数据传输
38请求文件传输 (Request File Transfer)请求文件传输操作
3D写入内存 (Write Memory By Address)按地址写入内存
3E保持连接 (Tester Present)保持 ECU 维持在非默认的诊断会话中,防止 S3 超时
83访问计时 (Access Timing Parameter)配置通信时序参数(可选服务,部分 ECU 不支持)
84受保护的数据传输 (Secured Data Transmission)加密传输诊断数据
85控制诊断故障码设置 (Control DTC Setting)开启或关闭 DTC 的设置
86事件响应 (Response On Event)事件触发时的响应配置
87链路层控制 (Link Control)控制链路层行为
90整机检测 (Diagnostic Capability)检测 ECU 的诊断能力

2.2.1、服务请求/响应格式

UDS 服务请求和响应有两类:

  • 具有 Subfunction(子功能):如 0x10(诊断会话控制)、0x11(ECU 复位)、0x31(例程控制)
  • 不具有 Subfunction(子功能):如 0x22(按标识符读取)、0x2E(按标识符写入)

肯定响应格式:(SID + 0x40) + Subfunction + 数据

否定响应格式:0x7F + SID + NRC

示例

  • 请求 0x10 服务,Subfunction 为 0x02:
    • 肯定响应:第 1 字节 0x50,第 2 字节 0x02
    • 否定响应:第 1 字节 0x7F,第 2 字节 0x10,第 3 字节为 NRC

2.2.2、常见 NRC(否定响应代码)

NRC含义
0x10General Reject(通用拒绝)
0x11Service Not Supported(服务不支持)
0x12Sub-Function Not Supported(子功能不支持)
0x13Incorrect Message Length(报文长度错误)
0x22Conditions Not Correct(条件不满足)
0x31Request Out of Range(请求超出范围)
0x33Security Access Denied(安全访问拒绝)
0x7FService Not Supported in Active Session(当前会话不支持该服务)

注意:0x7F 作为 NRC 表示"当前会话不支持该服务",与作为否定响应 SID 前缀(0x7F + SID + NRC)的 0x7F 是不同的概念,不要混淆。

2.3、帧格式(UDSonCAN)

UDS 在 CAN 上的传输使用 ISO 15765-2(DoCAN)定义的网络层协议,负责将较长的 UDS 报文拆分成 CAN 帧进行传输。

2.3.1、N_PCI(网络层协议控制信息)

CAN 帧数据场的首字节为 N_PCI,用于标识帧类型:

帧类型N_PCI 字节说明
单帧 (SF)0x0N (N = 0–7)数据长度 ≤ 7 字节,一帧完成传输。N 表示数据字节数
首帧 (FF)0x1N + 后续1字节数据长度 > 7 字节,第一帧。N + 后续 1 字节共 12 位表示总数据长度 (FF_DL)
连续帧 (CF)0x2N (N = 1–15)首帧之后的后续数据帧。N 为序列号 (SN),从 1 开始递增
流控帧 (FC)0x3N (N = 0–2)接收方控制发送速率。N = 0: 继续发送 (CTS);N = 1: 等待 (WT);N = 2: 溢出 (OVFLW)

2.3.2、多帧传输流程

正常多帧传输流程

  发送方 (Sender)                                 接收方 (Receiver)
       |                                                |
       |  ── 首帧 (FF) ──►                               |
       |    FF_DL = 总数据长度                           |
       |                                                |
       |  ◄── 流控帧 (FC) ──                             |
       |    FS = CTS (0), BS = 块大小, STmin = 最小间隔   |
       |                                                |
       |  ── 连续帧 (CF) SN=1 ──►                        |
       |  ── 连续帧 (CF) SN=2 ──►                        |
       |  ── 连续帧 (CF) SN=3 ──►                        |
       |       ...                                       |
       |  ── 连续帧 (CF) SN=N ──►                        |
       |                                                |

2.3.3、N_PCI 字段详解

字段位置说明
SF_DL单帧 N_PCI 低 4 位单帧数据字节长度,有效范围 0–7。SF_DL=0 表示无数据载荷;SF_DL > 7 无效
FF_DL首帧 N_PCI 低 4 位 + 下一字节首帧数据字节长度(12 位),有效范围 8–4095。FF_DL < 8 无效
SN连续帧 N_PCI 低 4 位序列号:0–F,从 1 开始递增,溢出后从 1 重新开始。接收方检测到非连续 SN 则中止接收
FS流控帧 N_PCI 低 4 位流状态:0 = CTS(继续发送),1 = WT(等待),2 = OVFLW(溢出),3–F = 保留
BS流控帧数据第 2 字节块大小:允许发送方连续发送的 CF 帧数。0 表示不限制
STmin流控帧数据第 3 字节连续帧之间的最小间隔。00–7F:毫秒 (ms);F1–F9:100 微秒 (µs),如 F1 = 100 µs

2.3.4、N_PDU 到 CAN 帧的映射

以标准地址(11 位 ID)为例:

 N_PDU 格式:
 +----------+----------+------+----------+
 | N_AI     | N_PCI    | Data | ...      |  N_AI = 地址信息 (可选)
 +----------+----------+------+----------+

 CAN 帧映射:
 +---------+----------+------+----------+
 | CAN ID  | N_PCI    | Data | ...      |  (最多 8 字节/经典CAN, 64字节/CAN FD)
 +---------+----------+------+----------+

 标准地址模式: N_AI 不占用数据场字节,通过 CAN ID 区分
 扩展地址模式: N_AI 占用数据场第 1 字节
 混合地址模式: 根据 CAN ID 范围决定是否使用地址字节

2.4、会话模式

2.4.1、三种会话模式

UDS 协议定义了三种会话模式,按权限从低到高:

会话模式子功能码权限用途
默认会话0x01最低ECU 上电后的默认状态。可操作的服务最少,如读取 DTC、读取数据等基本操作
扩展会话0x03中等大部分诊断功能在此模式下进行。用于写入 VIN/序列号、控制应用通信、更新故障信息、解锁高权限诊断服务等
编程会话0x02最高用于 ECU 程序刷写。超时或刷写失败时自动跳转回默认会话

2.4.2、会话切换规则

UDS 标准规定的切换关系(ISO 14229):三种会话模式是平级、独立的状态,理论上可以互相切换。

实际工程实践中的切换限制(安全考量):

                         默认会话 (Default)
                        /                \
                       /  (可以切换)       \  (禁止直接切换)
                      v                    v
              扩展会话 (Extended)      编程会话 (Programming)
                      \                    /
                       \  (禁止直接切换)   /
                        v                v
                         默认会话 (Default)

  S3 定时器超时 或 ECU 复位 (0x11) → 返回默认会话

切换规则总结

当前会话目标会话是否允许原因
默认会话扩展会话✅ 允许正常权限提升
默认会话编程会话❌ 禁止必须先经过扩展会话进行安全解锁
扩展会话编程会话✅ 允许安全解锁后进入刷写
扩展会话默认会话✅ 允许正常降级
编程会话扩展会话❌ 禁止防止刷写过程中绕回高权限状态
编程会话默认会话✅ 允许刷写完成或退出

2.4.3、为什么这样设计?

核心原因一:安全访问的强制介入

安全访问服务 (0x27) 是唯一的钥匙,这把钥匙只放在"扩展会话"这个房间里。

  • 为什么不能从"默认"直接到"编程"? 编程会话(刷写)是最高风险操作,必须经过安全访问 (0x27) 验证。在 ECU 软件设计中,安全访问服务仅在扩展会话和编程会话下有效,在默认会话下被禁用。因此必须先进入扩展会话完成安全解锁。
// 伪代码:安全访问服务处理函数
void handleSecurityAccess(uint8_t* data) {
    // 【关键检查】如果不在扩展或编程会话,直接拒绝
    if ((currentSession != EXTENDED_SESSION) && (currentSession != PROGRAMMING_SESSION)) {
        sendNegativeResponse(0x27, NRC_SERVICE_NOT_IN_SESSION);
        return;
    }
    // ... 否则,继续处理种子和密钥
}
  • 为什么不能从"编程"直接回"扩展"? 防止在刷写过程中"绕回"到另一个高权限状态,从而可能执行非预期的操作,破坏严谨的刷写流程。编程会话被设计为一个单一目的、纯净的环境,只做刷写相关的事情。

核心原因二:状态机的简洁与可靠

工程师倾向于设计一个线性的、而非网状的清晰状态流。理想化的安全流程:

 默认会话 ──► 扩展会话 ──► 安全解锁(0x27) ──► 编程会话
    ▲                                              │
    │◄──────────── 刷写完成/复位(0x11) ────────────┘
    │◄──────────── S3 超时 ────────────────────────┘
  • 进入路径是线性的、受控的:默认 → 扩展 → 安全解锁 → 编程。没有捷径。
  • 退出路径是确定的:刷写完成后,通过 ECU 复位 (0x11) 或超时,直接回到默认会话。这是一个"硬重置",确保了 ECU 回到一个干净、已知的初始状态。

如果允许在"编程"和"扩展"之间随意切换,就会形成一个循环,使得状态管理变得复杂,需要处理更多的边缘情况。

// 伪代码:处理 0x10 诊断会话控制服务
void handleDiagnosticSessionControl(uint8_t* data) {
    requestedSession = data[1]; // 获取请求的子功能(目标会话)

    // 【规则1:禁止从默认直接到编程】
    if ((currentSession == DEFAULT_SESSION) && (requestedSession == PROGRAMMING_SESSION)) {
        sendNegativeResponse(0x10, NRC_CONDITIONS_NOT_CORRECT); // 0x22
        return;
    }

    // 【规则2:禁止从编程直接到扩展】
    if ((currentSession == PROGRAMMING_SESSION) && (requestedSession == EXTENDED_SESSION)) {
        sendNegativeResponse(0x10, NRC_CONDITIONS_NOT_CORRECT); // 0x22
        return;
    }

    // 【允许的切换路径】
    if (isSessionSupported(requestedSession)) {
        currentSession = requestedSession;
        startS3Timer();
        sendPositiveResponse(0x50, ...);
    } else {
        sendNegativeResponse(0x10, NRC_SUB_FUNC_NOT_SUPPORTED); // 0x12
    }
}

三、CAN 与 UDS 的关系

UDS 是运行在 CAN 总线这个"信息公路"上的一套重要的"交通规则"或"高级沟通协议"。

  • 依赖关系:UDS 依赖于 CAN 总线。CAN 是物理层和底层数据链路层的基础,UDS 是应用层的协议。没有 CAN 这条"公路",UDS 这本"沟通手册"就无用武之地。
  • 分工合作
    • CAN 总线负责:"我这里有一包数据,主题是 '0x7E0',现在要发给你们。"
    • UDS 协议负责:当 ECU 收到这包数据后,解析发现里面的内容是 0x22 0xF4 0x0C,于是明白:"哦,对方是要求我(用 0x22 服务)读取标识符为 0xF40C 的数据(比如车速),我要准备好数据并回复给他。"
  • 类比
    • CAN 总线像 互联网的 TCP/IP 协议,负责把数据包从你的电脑送到服务器。
    • UDS像 HTTP 协议,定义了你是要 "GET" 一个网页,还是 "POST" 提交数据。互联网(TCP/IP)负责传输,HTTP 负责定义传输内容的意义。

OSI 层级对应

OSI 层协议/标准说明
应用层ISO 14229 (UDS)诊断服务定义
网络层ISO 15765-2 (DoCAN)多帧传输、流控
数据链路层ISO 11898-1 (CAN 2.0 / CAN FD)帧格式、仲裁、错误处理
物理层ISO 11898-2 / 11898-3差分信号、电平定义、拓扑

3.1、经典 CAN 与 CAN FD 核心差异总结

字段经典 CANCAN FD差异解读
FDF 位保留位 r0(显性 '0'FDF 位(隐性 '1')身份标识。经典 CAN 节点看到 '1' 会报错。
数据场固定 0–8 字节灵活 0–64 字节负载能力大幅提升。
BRS 位不存在位速率切换开关性能关键。实现了"慢仲裁,快传输"。
ESI 位不存在错误状态指示器增强了网络的诊断能力。
CRC 场固定 15 位 CRC17 位或 21 位 CRC可靠性增强。应对高速长数据帧的出错风险。
传输速率全程单一波特率仲裁段:标准速率;数据/CRC 段:可高速率效率提升。在不影响仲裁可靠性的前提下,大幅提升有效数据吞吐量。

可以清晰地看到 CAN FD 如何在继承经典 CAN 稳健的仲裁和错误处理机制的基础上,通过引入关键的控制位和灵活的速率切换,实现了性能和效率的飞跃。


四、测试

4.1、CAN 分析仪接线

CAN 分析仪(如 PCAN、Kvaser)连接目标板:

分析仪端目标板端说明
CAN_HCAN_HCAN 高线
CAN_LCAN_LCAN 低线
GNDGND必须共地

终端电阻:总线两端各需 120Ω,部分分析仪内置终端电阻,需确认是否启用。如果分析仪和 ECU 都启用了终端电阻,可能导致电阻并联为 60Ω,影响通信。

如果使用 J-Link 调试 MCU,SWD 接线如下:

J-Link 引脚信号目标板说明
1VTrefVDD(目标板)参考电压,必须接!用于电平匹配
4GNDGND地线,必须接!
7TMS/SWDIOSWDIOSWD 数据线,必须接!
9TCK/SWCLKSWCLKSWD 时钟线,必须接!
11nRESETRESET复位信号,强烈建议接!

注意:CAN 分析仪和 J-Link 是两种不同用途的设备。CAN 分析仪用于监控 CAN 总线通信,J-Link 用于调试 MCU 固件,不要混淆两者的连接方式。

4.3、常用 UDS 测试命令示例

以下为使用 CAN 分析仪发送 UDS 命令的示例(以标准 11 位 ID,诊断请求 ID = 0x7E0,响应 ID = 0x7E8 为例):

目的发送数据期望肯定响应
进入扩展会话02 10 03 00 00 00 00 0002 50 03 00 00 00 00 00
进入编程会话02 10 02 00 00 00 00 0002 50 02 00 00 00 00 00
读取 VIN (DID 0xF190)03 22 F1 90 00 00 00 0011 62 F1 90 [17字节VIN]
安全访问-请求种子 (Level 0x01)02 27 01 00 00 00 00 0006 67 01 [4字节种子]
安全访问-发送密钥 (Level 0x01)06 27 02 [4字节密钥]02 67 02 00 00 00 00 00
读取 DTC (0x19 服务)03 19 02 08 00 00 00 00包含 DTC 数量及具体 DTC 码
硬件复位 (0x11 服务)02 11 01 00 00 00 00 0002 51 01 00 00 00 00 00
保持连接 (Tester Present)01 3E 00 00 00 00 00 0001 7E 00 00 00 00 00 00

数据格式说明

  • 第 1 字节:单帧 N_PCI(如 02 = 单帧,2 字节数据;03 = 单帧,3 字节数据)
  • 第 2 字节:SID(服务 ID)
  • 后续字节:Subfunction 或数据
  • 不足 8 字节用 00 填充(CAN 经典帧固定 8 字节数据场)

4.4、测试注意事项

  1. 波特率匹配:确认 CAN 分析仪与目标 ECU 的波特率一致(常见 500 Kbps 或 250 Kbps)。
  2. 终端电阻:确认总线两端都有 120Ω 终端电阻,且分析仪内部终端电阻的启用/禁用状态正确。
  3. 共地:CAN 分析仪和 ECU 必须共地,否则通信不稳定。
  4. 会话超时:扩展会话和编程会话有 S3 定时器(默认 5 秒),需定期发送 0x3E 保持连接,否则自动退回默认会话。
  5. 安全访问:刷写前必须先通过 0x27 安全访问,否则 0x34(请求下载)等操作会被拒绝。
  6. CAN ID 过滤:确认诊断请求 ID 和响应 ID 的对应关系(通常请求 ID 为 0x7E0,响应 ID 为 0x7E8;物理寻址)。

------------------------------------------------------------------------

📝 后续补充内容优先同步至 GitHub,如有疏漏欢迎指正。

📌 全部相关技术笔记托管于 GitHub 仓库,欢迎访问。

🔗 GitHub仓库:kyshipit/tech‑notes

------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kyshipit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值