上周领导需要做个OBD相关的功能,我对OBD没有啥概念,于是周末就了解下这到底是个啥东西。了解过后发现很简单,其实就是个UDS协议的简化版,OBD是英文On-Board Diagnostics的缩写,中文翻译为“车载自动诊断系统”,有自己一套偏向于排放的诊断协议。
硬件
硬件比较简单,就2行8列16个口/引脚,实物长这样。
具体引脚的功能
1 Reserved
2 SAE J1850 总线的正线
3 Reserved
4 底盘地
5 信号地
6 CAN_H
7 K线
8 Reserved
9 Reserved
10 SAE J1850 总线的负线
11 Reserved
12 Reserved
13 Reserved
14 CAN_L Can
15 L线
16 电池电压
所以我们看到里面最重要的就是两条CAN线,一半我们也是重点关注这两条线。
服务的总体介绍
有以下几个服务,其中0x05已经删除了,因为0x06就能完全包含。
读取动力系统当前诊断相关数据(0x01)服务
根据PID读取对应排放相关的当前数据,包括:模拟输入/输出数据数字输入/输出数据,系统状态信息。
要求必须是实际读取的值,非默认值或替代值。
里面定义了一种像DID一样的参数,叫PID,并不要求把这些参数都实现,可以支持部分PID就行。但是有一点,所有支持OBD标准的ECU都必须支持0x01,PID=0x00的服务,其它PID不做强制要求。
有部分PID的作用是查询其他PID是否支持,譬如0x00,0x20,0x40,0x60...0xE0,我们称为查询PID,表示查询ECU对其它PID支持信息回复数据4字节32位,依次对应ECU对其后32个PID支持信息。举几个例子:
PID 0x00 用于查询(0x01~0x20)之间支持的PID参数
PID 0x20 用于查询(0x21~0x40)之间支持的PID参数
PID 0x40 用于查询 (0x41~0x60)之间支持的PID参数
……
后面一样一直到0xE0。
被支持的PID我们称为数据PID。
所以一般诊断的流程分两步:
1、先发送查询PID,看看是否支持我们想要的查询的数据PID。
2、根据接收到的支持PID结果,再发送想要的查询的数据PID。
请求报文要求
最多可以包含六个PID
在同一条请求报文中,可以重复出现同一个PID,但是不能同时出现查询PID不能和数据PID。
响应报文要求
ECU支持最多6个PID的请求
如果同一条请求当中,重复出现同一个PID,就当作多个处理。
响应报文中PID的顺序不要求同于在请求报文中的顺序,譬如请求时候是12345,响应的时候可以是54321。
查询PID举例
请求报文
数据 | 描述 |
0x01 | 服务ID |
0x00 | 查询PID,查询0x01~0x20之间的PID是否支持 |
响应报文
数据 | 描述 |
0x41 | 正响应:服务ID+0x40 |
0x00 | 接收到的查询PID |
0x88 | 0x65 = 1000 1000 支持PID 0x01和0x05 |
0x66 | 0x66 = 0110 0110 支持PID 0x0A/0x0B/0x0E/0x0F |
0x00 | 在0x11~0x18范围内没有支持的PID |
0x00 | 在0x19~0x20范围内没有支持的PID |
数据PID举例
请求报文
数据 | 描述 |
0x01 | 服务ID |
0x05 | 查询数据PID |
0x0A | 查询数据PID |
响应报文
数据 | 描述 |
0x41 | 正响应:服务ID+0x40 |
0x0A | 接收到的数据PID |
0x08 | 数据PID0A的具体数据 |
0x05 | 接收到的数据PID |
0x00 | 数据PID05的具体数据高位 |
0x64 | 数据PID05的具体数据低位 |
在这里大家可以看出,相应的顺序不一定要跟请求的一样,而且每个PID具体数据长度是双方约定好的。
读取动力系统冻结帧数据(0x02)服务
跟UDS协议里面的冻结帧是一样的作用,这个服务也有查询PID,在0x02服务里面,PID就是冻结帧的ID。规定PID=0x02返回的是引起冻结帧数据的DTC,如果ECU中没有冻结帧数据,那么返回的DTC=0x00。OBD协议的DTC比较短,只有2个字节,例子如下。
请求报文要求
最多可以包含3个PID
在同一条请求报文中,可以重复出现同一个PID,但是不能同时出现查询PID不能和数据PID。
响应报文要求
ECU支持最多3个PID
如果同一条请求当中,重复出现同一个PID,就当作多个处理。
响应报文中PID的顺序不要求同于在请求报文中的顺序,譬如请求时候是12345,响应的时候可以是54321。
查询PID举例
请求报文
数据 | 描述 |
0x02 | 服务ID |
0x00 | PID |
0x00 | 帧类型,默认为0 |
响应报文
数据 | 描述 |
0x42 | 正响应:服务ID+0x40 |
0x00 | 查询PID |
0x00 | 帧类型,默认为0 |
0x16 | 支持的PID |
0x36 | 支持的PID |
0x7C | 支持的PID |
0x59 | 支持的PID |
读取冻结帧举例
请求报文
数据 | 描述 |
0x02 | 服务ID |
0x06 | 冻结帧PID |
0x00 | 帧类型,默认为0 |
响应报文
数据 | 描述 |
0x42 | 正响应:服务ID+0x40 |
0x06 | 冻结帧PID |
0x00 | 帧类型,默认为0 |
0x15 | 冻结帧数据 |
0x36 | 冻结帧数据 |
0x74 | 冻结帧数据 |
0xB9 | 冻结帧数据 |
读取引起冻结帧数据的DTC举例
请求报文
数据 | 描述 |
0x02 | 服务ID |
0x02 | 查询引起冻结帧数据的DTC |
0x00 | 帧类型,默认为0 |
响应报文
数据 | 描述 |
0x42 | 正响应:服务ID+0x40 |
0x02 | 查询引起冻结帧数据的DTC |
0x00 | 帧类型,默认为0 |
0x01 | 第1个DTC高位 |
0x30 | 第1个DTC低位 |
0x001 | 第2个DTC高位 |
0x5D | 第2个DTC低位 |
读取确认的排放相关故障码(0x03)服务
看看已经发生故障的DTC有哪些,跟UDS的19服务是一样的。
举例
请求报文
数据 | 描述 |
0x03 | 服务ID |
响应报文
数据 | 描述 |
0x43 | 正响应:服务ID+0x40 |
0x02 | 已经故障的DTC有2个 |
0x01 | 第1个DTC高位 |
0x14 | 第1个DTC低位 |
0x01 | 第2个DTC高位 |
0x56 | 第2个DTC低位 |
如果都没有故障则会回复43 00
清除排放相关诊断信息(0x04)服务
相当于UDS的14服务,清除的数据包括DTC的故障状态码、冻结帧、扩展数据等。
举例
请求报文
数据 | 描述 |
0x04 | 服务ID |
响应报文
数据 | 描述 |
0x44 | 正响应:服务ID+0x40 |
请求氧传感器的检测结果(0x05)服务
监控氧传感器的测试结果,一般06服务已经涵盖了05服务。它跟服务01一样,有查询PID,不过这里叫TID(Test Identifiers)测试表示符,分为三种查询TID,组件TID和数据TID。
整个流程有3步:
1、先发送查询TID,看看是否支持我们想要的查询的组件TID。
2、根据接收到支持的组件TID结果,再发送想要的查询的数据TID。
3、接收到的数据TID结果。
报文跟06服务差不多,如果没有组件TID,流程就缩减为2步,在第二步就请求数据TID结果。
请求规定监测系统的OBD监测结果(0x06)服务
跟UDS的31服务一样,这里的ID被称为MID。
举例
请求报文
数据 | 描述 |
0x06 | 服务ID |
0x10 | MID |
响应报文
数据 | 描述 |
0x46 | 正响应:服务ID+0x40 |
0x10 | MID |
0x01 | 检测结果高位 |
0x56 | 检测结果低位 |
0xFF | 上限值高位 |
0xFF | 上限值低位 |
0x00 | 下限值高位 |
0x00 | 下限值低位 |
读取排放相关当前或最后驾驶循环的故障码(0x07)服务
该服务主要应用于汽车维修后的测试工作当清除所有故障码后,测试一个驾驶循环,如果失败,则会出现故障码,当然这并不代表部件/系统故障,还需要进一步的测试,于是就使用0x03服务进行详细的测试。
举例
请求报文
数据 | 描述 |
0x07 | 服务ID |
响应报文
数据 | 描述 |
0x47 | 正响应:服务ID+0x40 |
0x01 | 第1个DTC高位 |
0x1C | 第1个DTC低位 |
0x33 | 第2个DTC高位 |
0x13 | 第2个DTC低位 |
0x01 | 第3个DTC高位 |
0x56 | 第3个DTC低位 |
请求控制车载系统、测试或元部件(0x08)服务
这个服务使用的比较少,也就是UDS的0x31服务。请求报文只会请求开启、关断或者持续一定时间的循环测试。响应报文里面也只是上报个系统状态或者测试结果。这个服务也有查询TID。
举例
请求报文
数据 | 描述 |
0x08 | 服务ID |
0x45 | 测试TID |
0x89 | 测试数据 |
0x33 | 测试数据 |
响应报文
数据 | 描述 |
0x48 | 正响应:服务ID+0x40 |
0x45 | 测试TID |
0x89 | 测试结果 |
0x86 | 测试结果 |
0x00 | 测试结果 |
0x96 | 测试结果 |
读取车辆信息(0x09)服务
跟UDS的22服务读取DID一样,和前面提到的PID TID一样,这里叫InfoType,一样有查询InfoType。
举例
请求报文
数据 | 描述 |
0x09 | 服务ID |
0x05 | InfoType |
响应报文
数据 | 描述 |
0x49 | 正响应:服务ID+0x40 |
0x05 | InfoType |
0xAA | InfoType05高位 |
0xBB | InfoType05低位 |
多帧处理
最后讲讲这个,大家才知道实际的数据帧里面是怎么发的
单帧举例
请求报文
数据 | 描述 |
0x7DF | 诊断仪发送的报文CANID |
0x08 | DLC |
0x02 | 第1字节数据,有效数据总长。 |
0x01 | 第2字节数据,有效数据第1字节 |
0x00 | 第3字节数据,有效数据第2字节 |
0x00 | 第4字节数据,填充数据 |
0x00 | 第5字节数据,填充数据 |
0x00 | 第6字节数据,填充数据 |
0x00 | 第7字节数据,填充数据 |
0x00 | 第8字节数据,填充数据 |
响应报文
数据 | 描述 |
0x760 | DUT发送的报文CANID |
0x08 | DLC |
0x06 | 第1字节数据,有效数据总长。 |
0x41 | 第2字节数据,有效数据第1字节 |
0x00 | 第3字节数据,有效数据第2字节 |
0x43 | 第4字节数据,有效数据第3字节 |
0xB6 | 第5字节数据,有效数据第4字节 |
0x4A | 第6字节数据,有效数据第5字节 |
0xF3 | 第7字节数据,有效数据第6字节 |
0x00 | 第8字节数据,填充数据 |
多帧举例
请求报文
数据 | 描述 |
0x7DF | 诊断仪发送的报文CANID |
0x08 | DLC |
0x03 | 第1字节数据,有效数据总长。 |
0x02 | 第2字节数据,有效数据第1字节 |
0x02 | 第3字节数据,有效数据第2字节 |
0x00 | 第4字节数据,有效数据第3字节 |
0x00 | 第5字节数据,填充数据 |
0x00 | 第6字节数据,填充数据 |
0x00 | 第7字节数据,填充数据 |
0x00 | 第8字节数据,填充数据 |
响应报文第一帧
数据 | 描述 |
0x760 | DUT发送的报文CANID |
0x08 | DLC |
0x0D | 第1字节数据,有效数据总长。 |
0x42 | 第2字节数据,有效数据第1字节 |
0x02 | 第3字节数据,有效数据第2字节 |
0x00 | 第4字节数据,有效数据第3字节 |
0x01 | 第5字节数据,有效数据第4字节 |
0x30 | 第6字节数据,有效数据第5字节 |
0x01 | 第7字节数据,有效数据第6字节 |
0x5D | 第8字节数据,有效数据第7字节 |
响应报文第二帧
数据 | 描述 |
0x760 | DUT发送的报文CANID |
0x08 | DLC |
0x15 | 第1字节数据,有效数据第8字节 |
0x63 | 第2字节数据,有效数据第9字节 |
0xD2 | 第3字节数据,有效数据第10字节 |
0xCF | 第4字节数据,有效数据第11字节 |
0x66 | 第5字节数据,有效数据第12字节 |
0x88 | 第6字节数据,有效数据第13字节 |
0x00 | 第7字节数据,填充数据 |
0x00 | 第8字节数据,填充数据 |