CANFD协议与UDS服务
CANFD与CAN的差异
二者差异主要集中在MAC层上,依旧是分为非扩展帧和扩展帧,
非扩展:
- RTR→RRS
- r0→FDF
- 新增res、BRS、ESI
- CRC段之前多出Stuff-bitcounter
- CRC变为17/21位,且包含固定填充位
| 段名 | 帧起始 | 仲裁段 | 控制段 | 数据段 | CRC段 | ACK段 | 帧结束 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 含义 | SOF | ID | RRS | IDE | FDF | res | BRS | ESI | DLC | Data | SBC | CRC | DEL | ACK | DEL | EOF |
| 长度 | 1 | 11 | 1 | 1 | 1 | 1 | 1 | 1 | 4 | 0~64字节 | 4(3+1) | 17/21 | 1 | 1 | 1 | 7 |
扩展:
| … | 仲裁段 | 控制段 | … | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| ID | SSR | IDE | EID | RRS | IDE | FDF | res | BRS | ESI | DLC | |
| 11 | 1 | 1 | 18 | 1 | 1 | 1 | 1 | 1 | 1 | 4 |
仲裁段
- RRS:RemoteRequestSubstitution,替代ClassicalCAN的RTR,CANFD中固定为显性0,不再表示远程帧
- SSR:在 Classical CAN 中“保证标准帧优先级高于扩展帧”的仲裁功能,但在纯CANFD环境里并没有被复用,即在CANFD仅作为“为了帧结构兼容而保留的占位位”
控制段
- FDF:FDFormatbit,=1表示本帧为CANFD帧格式(Classical CAN中对应r0,保留并固定为显性0)
- res:新保留位(类似Classical CAN中的r0),为将来协议扩展预留
- BRS:BitRateSwitch,=1时表示从本位开始进入数据段后,比特率切换到高速;=0时保持仲裁段速率
- ESI:ErrorStateIndicator,显性=ErrorActive,隐性=ErrorPassive,用于指示发送节点的错误状态
数据段
- DLC:仍为4位,但含义扩展:0~8同Classical CAN;9~15分别对应12/16/20/24/32/48/64字节
- SBC:StuffBitCounter,在CRC段之前新增,由3位格雷码+1位奇偶校验构成(这里统一写成4位)
- CRC:17位(数据≤16字节)或21位(数据>16字节),不再是ClassicalCAN的15位
UDS统一诊断服务
UDS是一种应用层协议,通常跑可以在CAN、LIN、Flexray、Interact等协议上
UDS通讯基础
UDS使用Client-Server模型,诊断仪发送“Request”,ECU返回“Response” ,如下:
| Client (诊断仪/Tester) | 方向 | Server (ECU) |
|---|---|---|
| 场景 1:仅 SID (以 0x14 清除故障信息为例) | ||
服务请求:14 FF FF FF (请求清除所有 DIDs) |
-> | |
| <- | 肯定响应(格式为 SID + 0x40):54 (计算:14 + 40 = 54) |
|
| <- | 否定响应(格式固定为 7F + SID + NRC):7F 14 13 (NRC 13:报文长度错误或格式不正确) |
|
| 场景 2:SID + SF (以 0x10 会话控制为例) | ||
服务请求:10 03 (请求进入扩展会话) |
-> | |
| <- | 肯定响应:50 03 [P2 Time parameters] (50 是 10+40,03 是回显子功能) |
|
| <- | 否定响应:7F 10 22 (NRC 22:当前条件不满足,如车速不为0) |
|
| 场景 3:SID + DID (以 0x22 读取数据为例) | ||
服务请求:22 F1 90 (请求读取 VIN 码) |
-> | |
| <- | 肯定响应:62 F1 90 [VIN Data...] (62 是 22+40,F1 90 是数据标识符) |
|
| <- | 否定响应:7F 22 31 (NRC 31:请求的标识符不存在/超出范围) |
|
| 场景 4:SID + SF + DID (以 0x31 例程控制为例) | ||
服务请求:31 01 02 01 (启动 0201 号灯光测试程序) |
-> | |
| <- | 肯定响应:71 01 02 01 [Status] (71 是 31+40,01 是启动,02 01 是程序ID) |
|
| <- | 否定响应:7F 31 33 (NRC 33:安全访问拒绝,可能需要先执行 0x27 解锁) |
SID:服务ID,决定当前诊断通信的性质,类似于HTTP的Method,常见有
-
0x10:会话控制,切换 ECU 的工作状态(如进入调试、编程模式),支持NRC
0x12、0x13、0x22,常见SubFunction:- 默认会话0x01:最小权限的会话,提供基本诊断能力,但不具备高风险功能,当前状态下下不需要任何诊断应⽤程序的在线服务(
0x3E服务)保持此模式激活。如果在其他状态下请求10 01回到默认会话并收到了肯定响应,之前激活的控制服务(如 0x28 通信控制)会复位,已解锁的安全访问(0x27)也会重新锁定 - 扩展会话0x03:扩展会话状态⽀持在 ECU 存储器中进⾏操作,比起默认会话,允许更多高权限操作,⽐如
0x22/0x2E读/写服务、0x28通信控制、0x31例程等操作。扩展会话状态通常仅可从默认会话状态进入 - 编程会话0x02:编程会话⽀持 ECU 内存编程操作,⼀般在此会话下执⾏ bootloader(刷写)操作,会有更多高权限功能,比如
0x34请求下载、0x36传输数据、0x37请求传输退出、0x31例程控制等,但安全要求非常严格,需要通过0x27服务做验证,同时通常仅可通过扩展会话状态进入,并且不可退回到扩展会话状态 - 安全系统诊断会话0x04:比较少见
- 自定义会话0x05~0x3F、0x41~0x7F
- 默认会话0x01:最小权限的会话,提供基本诊断能力,但不具备高风险功能,当前状态下下不需要任何诊断应⽤程序的在线服务(
-
0x11:复位服务,请求ECU 重启,根据SF采用不同的重启方式,支持NRC:
0x12、0x13、0x22、0x33,常见SubFunction:- 硬复位0x01:模拟掉电重启
- 钥匙复位0x02:模拟点火从关到开的过程
- 软复位0x03:不初始化数据,仅重置PC寄存器,不完全重启
- 启用快速下电休眠0x04:针对具备待机模式的 ECU
- 抑制快速下电休眠0x05
-
0x14:清除DTC(诊断故障码)及其相关数据
-
0x19:读取DTC
-
0x22:读数据,通过DID获取ECU内部存储的信息,支持NRC:
0x13、0x14、0x22、0x31、0x33,常见DID:F1 90(VIN码)、F1 8C(序列号) 等 。 -
0x27:安全访问,通过 Seed & Key 算法解锁高权限服务(如写数据、刷写、下载),支持 NRC:
0x12、0x13、0x22、0x24(请求顺序错误)、0x35、0x36(超过尝试次数) 、0x37(错误延迟未到),常见SubFunction:- 奇数 (0x01, 0x03…):请求种子 (Request Seed) 。
- 偶数 (0x02, 0x04…):发送密钥 (Send Key) 。
- Seed 为 0 通常表示已解锁 。
-
0x28:通信控制,开启或关闭 ECU 的应用层报文(非诊断报文)发送或接收,常用于刷写前清理总线带宽
-
常见
SubFunction:- 恢复正常通信:0x00
- 只读不写:0x01
- 只写不读:0x02
- 完全静默:0x03(最常用,禁止收发)
-
常见参数 (CommunicationType):
- 0x01:应用报文;0x02:网管报文;0x03:两者都控制
-
-
0x2E:写数据,通过DID修改ECU的配置或参数,支持NRC:
0x13、0x22、0x31、0x33、0x72(编程错误),请求格式:0x2E+DID+数据 -
0x31:例程(Routine)控制,如擦除内存、自检、校验,请求格式:
0x31+RoutineID+参数- 常见
SubFunction:- 启动例程:0x01
- 停止例程:0x02
- 查询例程执行结果:0x03
- 常见
-
0x34:请求下载,启动数据传输,用于协商传输参数
- dataFormatIdentifier:高四位为压缩方式,低四位为加密方式 (通常 0x00) 。
- addressAndLengthFormatIdentifier:定义后续地址和长度占几个字节 (如 0x44 表示各占 4 字节)
- memoryAddress:写入的起始地址
- memorySize:数据总大小
-
0x35:请求上传,与0x34反向
-
0x36:实际传输数据块,在0x34或0x35之后使用
- BlockSequenceCounter:块序列号 (01-FF 循环),用于防丢包
- transferRequestParameterRecord:实际数据内容
-
0x37:请求退出传输,数据传输完成后,通知ECU结束传输流程,通常会触发 ECU 进行数据完整性校验
- 可包含校验和 (Checksum/CRC) 供ECU验证,若发送方没有包含,ECU也会返回CRC32供客户端进行验证
-
0x3E:会话保持,告诉 ECU 诊断仪还在线,用于保持非默认会话(如扩展/编程会话)不超时退回,通常 2-4 秒发一次,支持NRC
0x12、0x13,常见SubFunction:- 需要响应0x00:ECU 收到后回复
7E 00,用于确认连接正常 - 抑制响应0x80:ECU 收到后保持会话但不回复,用于减少总线负载
- 需要响应0x00:ECU 收到后回复
-
0x85:暂停/恢复 DTC 状态位的更新(冻结故障记录)
DID:数据标识符,是 0x22 和 0x2E 服务的操作对象,类似于变量名,常见有
- 0xF190:车架号。车辆的唯一身份证
- 0xF18C:ECU 序列号。硬件的唯一标识
- 0xF19E:版本号。当前 ECU 运行的软件版本
- 0x0100 - 0xEFFF:厂家自定义 DID,比如读取水温、发动机转速、电池电压等实时动态参数
- 0xFD01:标定数据。用于存储影响车辆性能的配置参数
RoutineID:例程标识符,专属于 0x31 服务,类似于远程代码执行,常见有
- 0xFF00:擦除内存。刷写固件前的必备步骤
- 0xFF01:检查结果。比如检查刚刚刷入的固件校验和(Checksum)是否正确
- 0x0201:自检例程。让全车灯光闪烁或仪表盘指针扫表
- 0xDF01:依赖性检查。检查当前的硬件版本是否兼容即将刷入的软件
NRC:否定代码,类似于HTTP的400响应码,常见有
- 0x11:服务不支持
- 0x12:服务支持,但子功能不对
- 0x13:服务支持,但长度不对
- 0x22:服务支持,子功能存在,但条件不满足,比如在车开的时候刷写固件,ECU会回这个
- 0x31:请求超出范围,标识符超出范围、服务器不支持或当前会话不支持
- 0x33:安全访问拒绝,说明服务器没解锁不让用
- 0x35:密钥错误,暴力破解失败时会出现
- 0x78:ECU 忙,这会延长超时时间
使用CAN传输UDS报文(DoCAN)
CAN以及CANFD传输数据时单帧能传输的数据相当有限,为了传输更多的数据,与TCP/IP的设计类似(MSS/MTU),设计了分包的传输机制CAN TP
UDS在通讯时使用CAN ID进行寻址,共有两种寻址方式:
- 物理寻址:1对1,物理地址(标识符)与CAN仲裁ID一致,诊断仪通过
0x7xx进行请求,ECU用0x6xx作为响应ID,两个ID的低8位在工程设计上常定义成一样的值,也有逆序和固定增值,没有强制规定 - 功能/逻辑寻址:广播1对多,常见诊断仪通过
0x7DF进行广播,各ECU用0x7E8–0x7EF范围内的CAN ID作为响应ID
同一个ECU在面对不同类型寻址方式时返回地址不一样,这是为了区别物理寻址和功能寻址
UDS在传输数据时总共有四种报文类型,这里展示在数据段的结构
| 报文类型 | 位7~4 | 位3~0 | 字节1 | 字节2 | 字节3~7 | 描述 |
|---|---|---|---|---|---|---|
| 单帧(SF) | 0000 | DLC<=7 | DATA | 数据长度<7字节 | ||
| 第一帧(FF) | 0001 | 7<DLC<4095 | DLC后半段 | DATA | 第一包,告诉 ECU 后面还有多少数据 | |
| 控制帧(FC) | 0011 | FS | BS | STmin | - | ECU 收到首帧后,回复 FC |
| 连续帧(CF) | 0010 | SN(帧序号,0~F循环计数) | DATA | 后续的数据包 |
FS(流状态):
- FS=0,CTS:继续发送
- FS=1,WT:暂停发送,等待下一个FS
- FS=2,OVFLW:接收方溢出,要求停止发送
BS(块大小):
- BS=0:块大小不受限制,可以一直发送
- BS=01~FF:在没有接受流控帧期间能发送的最大数目的连续帧
STmin(发送间隔):单位为毫秒
DLC:
- 这里的DLC与CAN上控制段的DLC并不指的是同一个值,此DLC仅描述报文内的数据长度