本篇文章主要介绍在ISO 14229-1标准中定义的UDS服务——$22 ReadDataByIdentifier,其为Tester提供了向目标ECU请求读取指定DID的当前值的能力。
目录
1 服务介绍
$22 ReadDataByIdentifier服务允许Tester通过一个或多个数据标识符(dataIdentifier,DID)向ECU请求数据记录值。
$22服务的请求消息可以包含一个或多个双字节DID,其用于标识ECU中的数据记录。不同数据记录的格式和定义应由车辆制造商或系统供应商规范,并可能包括模拟输入和输出信号,数字输入和输出信号,内部数据和系统状态信息。
ECU可以根据车辆制造商和系统供应商的规定,限制$22服务同时请求DID的数量。
一旦收到$22服务的请求,ECU应读取由DID指定的数据元素记录值,并将其填充在单个$22服务肯定响应的报文中。请求报文中可能会多次包含同一个DID,ECU应将这些重复的DID看作独立的DID并做出响应。
2 服务数据格式
2.1 请求数据格式
以下是$22服务的请求数据格式:
字节序 | 参数 | 字节值 | 说明 |
---|---|---|---|
#Byte1 | ReadDataByIdentifier SID | 0x22 | 必选 |
#Byte2 – #Byte3 | dataIdentifier[]#1 = [byte#1 : byte#2](MSB) | 0x00 – 0xFF 0x00 – 0xFF | 必选 |
#ByteN-1 – #ByteN | dataIdentifier[]#m = [byte#1 : byte#2](MSB) | 0x00 – 0xFF 0x00 – 0xFF | 可选 |
2.1.1 dataIdentifier
dataIdentifier参数表示Tester向ECU请求读取数据记录的标识符
2.2 肯定响应数据格式
以下是$22服务的肯定响应数据格式:
字节序 | 参数 | 字节值 | 说明 |
---|---|---|---|
#Byte1 | ReadDataByIdentifier SID + 0x40 | 0x62 | 必选 |
#Byte2 – #Byte3 | dataIdentifier[]#1 = [byte#1 : byte#2](MSB) | 0x00 – 0xFF 0x00 – 0xFF | 必选 |
#Byte4 – #Byte(K-1)+4 | dataRecord[]#1 = [data#1 : data#K] | 0x00 – 0xFF – 0x00 – 0xFF | 必选 |
– | – | – | – |
#ByteN-(O-1)-2 – #ByteN-(O-1)-1 | dataIdentifier[]#m = [byte#1 : byte#2](MSB) | 0x00 – 0xFF 0x00 – 0xFF | 可选 |
#ByteN-(O-1) – #ByteN | dataRecord[]#m = [data#1 : data#O] | 0x00 – 0xFF – 0x00 – 0xFF | 可选 |
2.2.1 dataIdentifier
dataIdentifier是对应$22服务请求报文中的dataIdentifier参数回显。
2.2.2 dataRecord
dataRecord参数是$22服务的肯定响应报文中包含的对应请求DID的ECU中的DID值
2.3 否定响应数据格式
以下是$22服务的否定响应数据格式:
字节序 | 参数 | 字节值 | 说明 |
---|---|---|---|
#Byte1 | Negative Response SID | 0x7F | 必选 |
#Byte2 | ReadDataByIdentifier SID | 0x22 | 必选 |
#Byte3 | NRC | supportedNRC | 必选 |
supportedNRC的可选值如下表所示:
supportedNRC | NRC define | 描述 |
---|---|---|
0x13 | incorrectMessageLengthOrInvalidFormat | 诊断请求指令的长度或格式不对 |
0x14 | responseTooLong | 诊断响应数据过长,超过网络层支持的最大字节数 |
0x22 | conditionsNotCorrect | 执行诊断的条件不满足 |
0x31 | requestOutOfRange | 诊断请求参数超出范围或DID/RID不支持 |
0x33 | securityAccessDenied | 不满足安全策略 |
3 服务通信示例
3.1 读取DID 0xF190(VIN)
本例展示了Tester如何通过$22服务向ECU读取DID 0xF190的值,其包含了VIN码信息,其中,存在以下条件:
- sub-function bit7: SPR = 0
3.1.1 请求报文
字节序 | 参数 | 字节值 |
---|---|---|
#Byte1 | ReadDataByIdentifier SID | 0x22 |
#Byte2 | dataIdentifier[byte#1] | 0xF1 |
#Byte3 | dataIdentifier[byte#2] | 0x90 |
3.1.2 肯定响应报文
字节序 | 参数 | 字节值 |
---|---|---|
#Byte1 | ReadDataByIdentifier SID + 0x40 | 0x62 |
#Byte2 | dataIdentifier[byte#1] | 0xF1 |
#Byte3 | dataIdentifier[byte#2] | 0x90 |
#Byte4 | dataRecord[data#1] = VIN 1 = “W” | 0x57 |
#Byte5 | dataRecord[data#2] = VIN 2 = “0” | 0x30 |
#Byte6 | dataRecord[data#3] = VIN 3 = “L” | 0x4C |
#Byte7 | dataRecord[data#4] = VIN 4 = “0” | 0x30 |
#Byte8 | dataRecord[data#5] = VIN 5 = “0” | 0x30 |
#Byte9 | dataRecord[data#6] = VIN 6 = “0” | 0x30 |
#Byte10 | dataRecord[data#7] = VIN 7 = “0” | 0x30 |
#Byte11 | dataRecord[data#8] = VIN 8 = “4” | 0x34 |
#Byte12 | dataRecord[data#9] = VIN 9 = “3” | 0x33 |
#Byte13 | dataRecord[data#10] = VIN 10 = “M” | 0x4D |
#Byte14 | dataRecord[data#11] = VIN 11 = “B” | 0x42 |
#Byte15 | dataRecord[data#12] = VIN 12 = “5” | 0x35 |
#Byte16 | dataRecord[data#13] = VIN 13 = “4” | 0x34 |
#Byte17 | dataRecord[data#14] = VIN 14 = “1” | 0x31 |
#Byte18 | dataRecord[data#15] = VIN 15 = “3” | 0x33 |
#Byte19 | dataRecord[data#16] = VIN 16 = “2” | 0x32 |
#Byte20 | dataRecord[data#17] = VIN 17 = “6” | 0x36 |
3.2 读取DID 0x010A/0x0110
本例展示了Tester如何通过$22服务向ECU读取DID 0x010A/0x0110的值,其中,存在以下条件:
- sub-function bit7: SPR = 0
3.2.1 请求报文
字节序 | 参数 | 字节值 |
---|---|---|
#Byte1 | ReadDataByIdentifier SID | 0x22 |
#Byte2 | dataIdentifier[byte#1] | 0x01 |
#Byte3 | dataIdentifier[byte#2] | 0x0A |
#Byte4 | dataIdentifier[byte#1] | 0x01 |
#Byte5 | dataIdentifier[byte#2] | 0x10 |
3.2.2 肯定响应报文
字节序 | 参数 | 字节值 |
---|---|---|
#Byte1 | ReadDataByIdentifier SID + 0x40 | 0x62 |
#Byte2 | dataIdentifier[byte#1] | 0x01 |
#Byte3 | dataIdentifier[byte#2] | 0x0A |
#Byte4 | dataRecord[data#1] = ECT | 0xA6 |
#Byte5 | dataRecord[data#2] = TP | 0x66 |
#Byte6 | dataRecord[data#3] = RPM | 0x07 |
#Byte7 | dataRecord[data#4] = RPM | 0x50 |
#Byte8 | dataRecord[data#5] = MAP | 0x20 |
#Byte9 | dataRecord[data#6] = MAF | 0x1A |
#Byte10 | dataRecord[data#7] = VSS | 0x00 |
#Byte11 | dataRecord[data#8] = BARD | 0x63 |
#Byte12 | dataRecord[data#9] = LOAD | 0x4A |
#Byte13 | dataRecord[data#10] = IAC | 0x82 |
#Byte14 | dataRecord[data#11] = APP | 0x71 |
#Byte15 | dataIdentifier[byte#1] | 0x01 |
#Byte16 | dataIdentifier[byte#2] | 0x10 |
#Byte17 | dataRecord[data#14] = B+ | 0x8C |