一、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、特性
- 多节点间可通信,节点数实际可达 110 个。
- 采用短帧结构,报文帧的有效字节为 8 个(经典 CAN)。
- 报文 ID 值越小,优先级越高。
- 非破坏性总线仲裁处理机制(仲裁段;线与机制;ID 越小优先级越高;仲裁失败进入只听模式)。
- 可靠的 CRC 校验方式,数据传送出错率极低。
- 报文帧仲裁失败或传输期间被破坏,有自动重发机制。
- 节点在错误严重的情况下,具有自动脱离总线的功能,切断与总线的联系,不影响总线的正常工作。
- 通信距离最远可达 10 km(速率 5 Kbps 以下)。
- 通信速率最高 1 Mbps(此时最长距离 40 m)。
- 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) | 4 | 0–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–8 | 0–8 |
| 9 | 12 |
| 10 | 16 |
| 11 | 20 |
| 12 | 24 |
| 13 | 32 |
| 14 | 48 |
| 15 | 64 |
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 帧结构对比
| 字段段落 | 字段名称 | 经典 CAN | CAN FD | 说明与差异 |
|---|---|---|---|---|
| 1. 帧开始 | SOF | 1 位 '0' | 1 位 '0' | 相同。一个显性位,标志帧开始。 |
| 2. 仲裁段 | 标识符 (ID) | 11 或 29 位 | 11 或 29 位 | 基本相同。决定报文优先级。此阶段使用较低的仲裁波特率。 |
| RTR | 1 位 '0'(数据帧) | 1 位 '0'(数据帧) | 相同。数据帧中为显性位。 | |
| 3. 控制段 | IDE | 1 位 | 1 位 | 相同。区分标准帧与扩展帧。 |
| FDF | 无(或视为隐性 r0) | 1 位 '1' | 核心区别。隐性 '1' 表明这是 CAN FD 帧。经典 CAN 节点看到此位会产生错误并忽略该帧。 | |
| BRS | 不适用 | 1 位 | 核心区别。'0' 数据段不加速;'1' 数据段切换到更高的波特率。 | |
| ESI | 不适用 | 1 位 | 新增。'1' 发送节点处于被动错误状态;'0' 处于主动错误状态。 | |
| DLC | 4 位(0–8 字节) | 4 位(0–64 字节) | 扩展。CAN FD 的 DLC 编码表被扩展以支持最多 64 字节的数据。 | |
| 4. 数据段 | Data Field | 0–8 字节 | 0–64 字节 | 核心区别。CAN FD 的数据负载能力大幅提升。此阶段可能使用更高的数据段波特率。 |
| 5. CRC 段 | CRC Sequence | 15 位 | 17 或 21 位 | 增强。CAN FD 使用更长的 CRC 来保障更大数据块和更高速度下的可靠性。 |
| CRC Delimiter | 1 位 '1' | 1 位 '1' | 相同。一个隐性位。 | |
| 6. 应答段 | ACK Slot | 1 位 | 1 位 | 相同。发送器发 '1',接收器覆写为 '0' 来应答。 |
| ACK Delimiter | 1 位 '1' | 1 位 '1' | 相同。一个隐性位。 | |
| 7. 帧结束 | EOF | 7 位 '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) |
| 5 | CRC 段 | 循环冗余校验码 + 定界符 |
| 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 的核心优势:
| 增强项 | 经典 CAN | CAN 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 | 含义 |
|---|---|
| 0x10 | General Reject(通用拒绝) |
| 0x11 | Service Not Supported(服务不支持) |
| 0x12 | Sub-Function Not Supported(子功能不支持) |
| 0x13 | Incorrect Message Length(报文长度错误) |
| 0x22 | Conditions Not Correct(条件不满足) |
| 0x31 | Request Out of Range(请求超出范围) |
| 0x33 | Security Access Denied(安全访问拒绝) |
| 0x7F | Service 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 核心差异总结
| 字段 | 经典 CAN | CAN FD | 差异解读 |
|---|---|---|---|
| FDF 位 | 保留位 r0(显性 '0') | FDF 位(隐性 '1') | 身份标识。经典 CAN 节点看到 '1' 会报错。 |
| 数据场 | 固定 0–8 字节 | 灵活 0–64 字节 | 负载能力大幅提升。 |
| BRS 位 | 不存在 | 位速率切换开关 | 性能关键。实现了"慢仲裁,快传输"。 |
| ESI 位 | 不存在 | 错误状态指示器 | 增强了网络的诊断能力。 |
| CRC 场 | 固定 15 位 CRC | 17 位或 21 位 CRC | 可靠性增强。应对高速长数据帧的出错风险。 |
| 传输速率 | 全程单一波特率 | 仲裁段:标准速率;数据/CRC 段:可高速率 | 效率提升。在不影响仲裁可靠性的前提下,大幅提升有效数据吞吐量。 |
可以清晰地看到 CAN FD 如何在继承经典 CAN 稳健的仲裁和错误处理机制的基础上,通过引入关键的控制位和灵活的速率切换,实现了性能和效率的飞跃。
四、测试
4.1、CAN 分析仪接线
CAN 分析仪(如 PCAN、Kvaser)连接目标板:
| 分析仪端 | 目标板端 | 说明 |
|---|---|---|
| CAN_H | CAN_H | CAN 高线 |
| CAN_L | CAN_L | CAN 低线 |
| GND | GND | 必须共地 |
终端电阻:总线两端各需 120Ω,部分分析仪内置终端电阻,需确认是否启用。如果分析仪和 ECU 都启用了终端电阻,可能导致电阻并联为 60Ω,影响通信。
4.2、J-Link SWD 调试接线
如果使用 J-Link 调试 MCU,SWD 接线如下:
| J-Link 引脚 | 信号 | 目标板 | 说明 |
|---|---|---|---|
| 1 | VTref | VDD(目标板) | 参考电压,必须接!用于电平匹配 |
| 4 | GND | GND | 地线,必须接! |
| 7 | TMS/SWDIO | SWDIO | SWD 数据线,必须接! |
| 9 | TCK/SWCLK | SWCLK | SWD 时钟线,必须接! |
| 11 | nRESET | RESET | 复位信号,强烈建议接! |
注意: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 00 | 02 50 03 00 00 00 00 00 |
| 进入编程会话 | 02 10 02 00 00 00 00 00 | 02 50 02 00 00 00 00 00 |
| 读取 VIN (DID 0xF190) | 03 22 F1 90 00 00 00 00 | 11 62 F1 90 [17字节VIN] |
| 安全访问-请求种子 (Level 0x01) | 02 27 01 00 00 00 00 00 | 06 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 00 | 02 51 01 00 00 00 00 00 |
| 保持连接 (Tester Present) | 01 3E 00 00 00 00 00 00 | 01 7E 00 00 00 00 00 00 |
数据格式说明:
- 第 1 字节:单帧 N_PCI(如
02= 单帧,2 字节数据;03= 单帧,3 字节数据) - 第 2 字节:SID(服务 ID)
- 后续字节:Subfunction 或数据
- 不足 8 字节用
00填充(CAN 经典帧固定 8 字节数据场)
4.4、测试注意事项
- 波特率匹配:确认 CAN 分析仪与目标 ECU 的波特率一致(常见 500 Kbps 或 250 Kbps)。
- 终端电阻:确认总线两端都有 120Ω 终端电阻,且分析仪内部终端电阻的启用/禁用状态正确。
- 共地:CAN 分析仪和 ECU 必须共地,否则通信不稳定。
- 会话超时:扩展会话和编程会话有 S3 定时器(默认 5 秒),需定期发送 0x3E 保持连接,否则自动退回默认会话。
- 安全访问:刷写前必须先通过 0x27 安全访问,否则 0x34(请求下载)等操作会被拒绝。
- CAN ID 过滤:确认诊断请求 ID 和响应 ID 的对应关系(通常请求 ID 为 0x7E0,响应 ID 为 0x7E8;物理寻址)。
------------------------------------------------------------------------
📝 后续补充内容优先同步至 GitHub,如有疏漏欢迎指正。
📌 全部相关技术笔记托管于 GitHub 仓库,欢迎访问。
🔗 GitHub仓库:kyshipit/tech‑notes
------------------------------------------------------------------------

1110

被折叠的 条评论
为什么被折叠?



