UDS 诊断服务系列文章目录
诊断和通信管理功能单元
UDS 诊断 - DiagnosticSessionControl(诊断会话控制)(0x10)服务
UDS 诊断 - ECUReset(ECU重置)(0x11)服务
UDS 诊断 - SecurityAccess(安全访问)(0x27)服务
UDS 诊断 - CommunicationControl(通信控制)(0x28)服务
UDS 诊断 - TesterPresent(测试仪保活)(0x3E)服务
UDS 诊断 - AccessTimingParameter(访问计时参数)(0x83)服务
UDS 诊断 - SecuredDataTransmission(受保护的数据传输)(0x84)服务
UDS 诊断 - ControlDTCSetting(控制DTC设置)(0x85)服务
UDS 诊断 - ResponseOnEvent(基于事件响应)(0x86)服务
UDS 诊断 - LinkControl(链路控制)(0x87)服务
数据传输功能单元
UDS 诊断 - ReadDataByIdentifier(按标识符读取数据)(0x22)服务
UDS 诊断 - ReadMemoryByAddress(按地址读取内存)(0x23)服务
UDS 诊断 - ReadScalingDataByIdentifier(按标识符读取换算数据)(0x24)服务
UDS 诊断 - ReadDataByPeriodicIdentifier(按周期性标识符读取数据)(0x2A)服务
UDS 诊断 - DynamicallyDefineDataIdentifier(动态定义数据标识符)(0x2C)服务
文章目录
- UDS 诊断服务系列文章目录
- 一、服务说明
- 二、请求消息
- 三、肯定响应消息
- 四、支持的NRC
- 五、示例
- 1. 假设
- 2. 示例 1:sub-funtion = defineByIdentifier,单一数据信息的 2 字节 DID
- 3. 示例 2:sub-funtion = defineByIdentifier,复合数据块的 DID
- 4. 示例 3:sub-funtion = defineByMemoryAddress
- 5. 示例 4:sub-funtion = defineByIdentifier,复合数据块的DID,0x2A 请求
- 6. 示例 5:sub-funtion = clearDynamicallyDefinedDataIdentifier
- 7. 示例 7:动态定义的数据标识符,定义的串联(defineByIdentifier(按标识符定义)/ defineByAddress(按地址定义))
一、服务说明
0x2C 服务允许客户端在服务器中动态定义一个可在以后通过 0x22 服务读取的数据标识符。
此服务旨在使客户端可以将一个或多个数据元素组合在一个数据超集中,而该数据超集可通过 0x2C 服务或 0x2A 服务一起进行请求。待组合在一起的数据元素可被以下任意一项引用:
— 一个源数据标识符、一个位置和大小或
— 一个内存地址和一个内存长度,或
— 使用多条请求以定义单一数据元素的上述两种方法的一个组合。
动态定义的 DID 则会包含一串数据参数定义。
此服务可以更灵活地处理扩展到超过特定信息的诊断应用程序的特别数据需求,可通过静态定义的数据标识符读取此类信息,并且,此类信息也可用于通过避免与频繁请求 / 响应事务关联的开销惩罚来降低带宽利用率。
动态定义的数据标识符可通过一条单一请求消息或多条请求消息进行定义。因此,在定义单一数据元素时可以引用源标识符和内存地址。服务器须串联单一数据元素的多个定义。清除当前定义并用新定义重新开始,即可重新定义一个动态定义的数据标识符。当使用多条 0x2C 服务请求消息配置一个单一 DID 且服务器检测到此 DID 的后续请求(如,定义一个 periodicDataldentifier(周期性数据标识符))期间溢出了最大字节数时,服务器应将该 Dataldentifier(数据标识符)的定义保留在可能已导致溢出的请求之前的状态。
尽管本服务不会禁止此功能,但不建议客户端在一个动态定义的数据记录中引用另一个动态定义的数据记录,这是因为删除被引用的记录会导致引用的记录出现数据一致性问题。
本服务也允许清除一项现有的已动态定义的数据记录。若指定的数据记录标识符在服务器支持的有效动态数据标识符范围内,则清除数据记录的请求应得到肯定响应。
服务器应保留动态定义的数据记录直至该数据被清除或满足车辆制造商指定的其他条件(例如,在会话转换时或服务器电源关闭时删除动态定义的数据记录)。
服务器可以通过两种方式实现数据记录:
— 包含未单独被引用的多个基本数据记录的复合数据记录。
— 独特 2 字节标识 “标志” 或服务器内受支持的单个基本数据记录的 DID 值(如,基本数据记录或 DID 是发动机转速或进气温度)。本数据记录的实现是一个复合数据记录实现的子集,因为其仅引用了一个单一基本数据记录,而非包含多个基本数据记录的数据记录。
上述两种数据记录实现方式均为 0x2C 服务所支持,以定义一个动态数据标识符。
— 复合数据块:位置参数须引用复合数据块中的起点,而大小参数须表明动态定义的数据标识符中数据的长度。测试仪负责不将复合数据块基本数据记录的一部分纳入动态数据记录中。
— 2 字节数据标识符:位置参数须设为 1,而大小参数须表明数据标识符的长度(基本数据记录的长度)。测试仪负责不将 2 字节数据标识符值的一部分纳入动态数据记录中。
动态定义的数据记录中数据的排序应与其在客户端请求消息中指定的顺序一致。此外,按照前句所述排序要求,客户端请求中指定的数据的第一个位置应最靠近动态数据记录起始处。
除通过逻辑引用(一个记录数据标识符)定义动态数据标识符外,此服务还允许通过一个绝对内存地址和一条内存长度信息定义一个动态定义的数据标识符。仅在服务器的开发阶段建议使用这种机制定义动态数据标识符。
二、请求消息
1. 请求消息定义
下表定义了请求消息 — sub-function = difineByIdentifier
。
字节 | 参数名称 | 字节值 | Cvt |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier(动态定义数据标识符)请求SID | 0x2C | M |
#2 | sub-function = [
| 0x01 | M |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [
byte#2(LSB)] | 0x00 - 0xFF 0x00 - 0xFF | M M |
#5 #6 | sourceDataIdentifier #1[] = [
byte#2(LSB)] | 0x00 - 0xFF 0x00 - 0xFF | M M |
#7 | positionInSourceDataRecord #1(第 1 个源数据记录中的位置) | 0x01 - 0xFF | M |
#8 | memorySize #1(第 1 个内存大小) | 0x00 - 0xFF | M |
. . | . . | . . | . . |
#n-3 #n-2 | sourceDataIdentifier #m[] = [
byte#2(LSB)] | 0x00 - 0xFF 0x00 - 0xFF | U U |
#n-1 | positionInSourceDataRecord #m(第 m 个源数据记录中的位置) | 0x01 - 0xFF | U |
#n | memorySize #m(第 m 个内存大小) | 0x00 - 0xFF | U |
下表定义了请求消息 — sub-function = difineByMemoryAddress
。
字节 | 参数名称 | 字节值 | Cvt |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier(动态定义数据标识符)请求SID | 0x2C | M |
#2 | sub-function = [
| 0x02 | M |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [
byte#2(LSB)] | 0xF2/0xF3 0x00 - 0xFF | M M |
#5 | addressAndLengthFormatIdentifier(地址和长度格式标识符) | 0x01 - 0xFF | M1 |
#6 . . #(m-1)+6 | memoryAddress[] = [
. . byte#m ] | 0x00 - 0xFF . . 0x00 - 0xFF | M . . C1 |
#m+6 . . #m+6+(k-1) | memorySize[] = [
. . byte#k ] | 0x00 - 0xFF . . 0x00 - 0xFF | M . . C2 |
. . | . . | . . | . . |
#n-k-(m-1) . . #n-k | memoryAddress[] = [
. . byte#m ] | 0x00 - 0xFF . . 0x00 - 0xFF | U . . U/C2 |
#n-(k-1) . . #n | memorySize[] = [
. . byte#k ] | 0x00 - 0xFF . . 0x00 - 0xFF | U . . U/C2 |
M1:addressAndLengthFormatIdentifier(地址和长度格式标识符)参数仅在请求消息起始处出现过一次,该参数说明了地址长度和整条请求消息中各存储单元引用的长度信息。
C1:本参数的存在与否取决于 addressAndLengthFormatIdentifier(地址和长度格式标识符)的地址长度信息参数。
C2:此参数的存在性取决于 addressAndLengthFormatIdentifier(地址和长度格式标识符)的内存大小长度信息。
下表定义了请求消息 — sub-function = clearDynamicallyDefinedDataIdentifier
。
字节 | 参数名称 | 字节值 | Cvt |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier(动态定义数据标识符)请求SID | 0x2C | M |
#2 | sub-function = [
| 0x03 | M |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [
byte#2(LSB)] | 0xF2/0xF3 0x00 - 0xFF | C C |
C:若存在本参数,则服务器需清除第 1 个字节和第 2 个字节中包含的 dynamicallyDefineDataIdentifier(动态定义数据标识符)。若本参数不存在,则应请求服务器中所有的 dynamicallyDefineDataIdentifier(动态定义数据标识符)。
2. 请求消息子功能参数定义
第 6 - 0 位 | 说明 |
---|---|
00 | 保留 |
01 | defineBydentifier(按标识符定义) 本值须用于指定服务器通过引用一个数据标识符来定义动态数据标识符。 |
02 | defineByMemoryAddress(按内存地址定义) 本值须用于指定服务器通过引用一个地址来定义动态数据标识符。 |
03 | clearDynamicallyDefinedDataldentifier(清除动态定义的数据标识符) 本值应用于清除指定的动态数据标识符。注意,服务器应对客户端发出的清除请求作出肯定响应,即使指定的动态数据标识符在发出请求时并不存在。但是,指定的动态数据标识符须在一个有效范围内。若在发出请求时周期性报告了指定的动态数据标识符,则应先停止然后清除该动态标识符。 |
04 - 7F | 保留 |
3. 请求消息数据参数定义
定义 |
---|
dynamicallyDefinedDataldentifier(动态定义的数据标识符) 本参数说明了客户端定义的动态数据记录在未来的调用中被服务 0x22 或 0x2A 引用的方式。dynamicalyDefinedDataldentifier(动态定义的数据标识符)应视作 0x22 服务中的 DID 处理。应将其视作 0x2A 服务中的 periodicRecordldentifier(周期性记录标识符)进行处理(为周期性请求动态定义的数据标识符)。 |
sourceDataldentifer(源数据标识符) 本参数仅针对 sub-function = defineByldentifier 存在。本参数从逻辑上指定了待纳入动态数据记录中的信息源。例如,可使用一个 2 字节数据标识符引用发动机转速,或一个 2 字节数据标识符引用一个包含发动机转速、车速、进气温度等的复合信息块。 |
positionInSourceDataRecord(源数据记录中的位置) 本参数仅针对 sub-function = defineByidentifier 存在。本单字节参数可用于指定待纳入动态数据记录中的源数据记录摘录的起始字节位置。其中一个位置应引用 sourceDataldentifier(源数据标识符)引用的数据记录的第一个字节。 |
addressAndLengthFormatldentifier(地址和长度格式标识符) 此参数为单字节值,每个半字节采用单独的编码:第 7 位至第 4 位:memorySize(内存大小)参数的长度(字节数量);第 3 - 0 位:memoryAddress(内存地址)参数的长度(字节数量);(示例值见文章 0x23 服务2.1节) |
memoryAddress(内存地址) 本参数仅针对 sub-function = defineByMemoryAddress 存在。本参数指定了待纳入动态数据记录中的信息的内存源地址。该地址所用的字节数由 addressAndLengthFormatdentifier(地址和长度格式标识符)的低效半字节(第 3 位至第 0 位)确定。memoryAddress(内存地址)参数的第 m 个字节始终为服务器中当前所引用的地址的最低有效字节。地址的最高有效字节可以用作内存标识符。 |
memorySize(内存大小) 本参数用于从待纳入动态数据记录中的源数据记录 / 内存地址中指定字节总数。 若 sub-function = defineByldentifier,则应另外使用 positionInSourceDataRecord(源数据记录中的位置)参数来指定 memorySize 适用的源数据标识符中的起始位置。该内存大小参数的字节数为 1。 若 sub-fnction = defineByMemoryAddress,则本参数应表明在指定 memoryAddress 处开始的待纳入动态定义的数据标识符中的字节数。该内存大小所用的字节数由 addressAndLengthFormatldentifier(地址和长度格式标识符)的高效半字节(第 7 位至第 4 位)确定。 |
三、肯定响应消息
1. 肯定响应消息定义
字节 | 参数名称 | 字节值 | Cvt |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier(动态定义数据标识符)响应SID | 0x6C | M |
#2 | sub-function = [ definitionType ] | 0x00 - 0xFF | M |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [
byte#2(LSB)] | 0x00 - 0xFF 0x00 - 0xFF | C C |
C:若请求消息中存在 dynamicallyDefinedDataIdentifier,则本参数也应该存在,否则本参数不得包含在内。
2. 肯定响应消息数据参数定义
定义 |
---|
definitionType(定义类型) 该参数是对来自请求消息的子功能参数第 6 位至第 0 位的回显。 |
dynamicallyDefinedDataIdentifier(动态定义的数据标识符) 本参数是请求消息中数据参数 dynamicallyDefinedDataIdentifier 的回显。 |
四、支持的NRC
NRC | 说明 |
---|---|
0x12 | 不受支持的子功能 |
0x13 | 消息长度不正确或格式无效 |
0x22 | 条件不正确 若因不满足服务器的运行条件而无法执行所需的操作,则应发送此 NRC。 |
0x31 | 请求超过限值 以下情况下,应发送此 NRC: — 请求消息中的所有数据标识符(dynamicallyDefinedDataldentifier(动态定义的数据标识符)或 sourceDataldentifier(源数据标识符))均不受支持 / 无效;; — positionInSourceDataRecord(源数据记录中的位置)不正确(小于 1 或大于服务器允许的最大值); — 请求消息中的所有内存地址在服务器中均不受支持; — 指定的 memorySize(内存大小)无效; — 待放入动态数据标识符中的数据数量超过服务器允许的最大值; — 指定的 addressAndLengtFormatldentifier(地址和长度格式标识符)无效; — 动态定义的 periodicDataldentifier(周期性数据标识符)的总长度超过适合一个数据链路(用于传输周期性响应消息)单帧的最大长度; |
0x33 | 安全访问被拒绝 下述情况下,应发送此 NRC: — 请求消息中的任何数据标识符(dynamicallyDefinedDataldentifier(动态定义的数据标识符)或 sourceDataldentifier(源数据标识符))是受保护的,并且服务器不处于解锁状态; — 请求消息中的任何内存地址均是受保护的,并且服务器不处于解锁状态; |
五、示例
1. 假设
本条款规定了本示例执行 0x2C 服务所需满足的条件。
本示例中的服务不受服务器任何限制条件的限制。
第一个示例中,服务器支持引用了一条单一数据信息的 2 字节标识符(DID)。该示例使用 defineByidentifier(按标识符定义)法生成了一个动态数据标识符,并发送了一条 ReadDataByldentifier(按标识符读取数据)请求,以读取刚配置的动态数据标识符。
第二个示例中,服务器支持引用了一个复合数据块(包含多条数据信息)的数据标识符。该示例也使用 defineByldentifier(按标识符定义)法生成了一个动态标识符,并发送了一条 ReadDataByldentifier(按标识符读取数据)请求,以读取刚定义的数据标识符。
第三个示例使用 defineByMemoryAddress(按内存地址定义)法生成了一个动态数据标识符,并发送了一条 ReadDataByldentifier(按标识符读取数据)请求,以读取刚定义的数据标识符。
第四个示例中,服务器支持引用了一个复合数据块(包含多条数据信息)的数据标识符。该例使用 defineByldentifier(按标识符定义)法生成了一个动态数据标识符,并 ReadDataByPeriodicldentifier(按周期性标识符读取数据)服务请求服务器周期性发送动态定义的数据标识符。
第五个示例展示了动态定义的数据标识符的删除过程。
下表应用于以下各个示例。针对实车报告的值会随时间而改变,但为明确起见,下表中将其显示为常数。
在所有示例中,客户端通过将 suppressPosRspMsgIndicationBit(抑制肯定响应消息指示位)设置为 “FALSE(假)” 来请求响应消息。
下表定义了复合数据块 — 数据标识符的定义
数据标识符(块) | 数据字节 | 数据记录内容 | 字节值 |
---|---|---|---|
0x010A | #1 | dataRecord[ data#1 ] = B+ | 0x8C |
#2 | dataRecord[ data#2 ] = ECT | 0xA6 | |
#3 | dataRecord[ data#3 ] = TP | 0x66 | |
#4 | dataRecord[ data#4 ] = RPM | 0x07 | |
#5 | dataRecord[ data#5 ] = RPM | 0x50 | |
#6 | dataRecord[ data#6 ] = MAP | 0x20 | |
#7 | dataRecord[ data#7 ] = MAF | 0x1A | |
#8 | dataRecord[ data#8 ] = VSS | 0x00 | |
#9 | dataRecord[ data#9 ] = BARO | 0x63 | |
#10 | dataRecord[ data#10 ] = LOAD | 0x4A | |
#11 | dataRecord[ data#11 ] = IAC | 0x82 | |
#12 | dataRecord[ data#12 ] = APP | 0x7E | |
0x050B | #1 | dataRecord[ data#1 ] = SPARKADV | 0x00 |
#2 | dataRecord[ data#2 ] = KS | 0x91 |
下表定义了基本数据记录 — 数据标识符的定义
数据标识符(块) | 数据字节 | 数据记录内容 | 字节值 |
---|---|---|---|
0x1234 | #1 | EOT(最高有效位) | 0x4C |
#2 | EOT(最低有效位) | 0x36 | |
0x5678 | #1 | AAT | 0x4D |
0x9ABC | #1 | EOL(最高有效位) | 0x49 |
#2 | EOL | 0x21 | |
#3 | EOL | 0x00 | |
#4 | EOL(最低有效位) | 0x17 |
下表定义了内存数据记录 — 内存地址的定义
内存地址 | 数据字节 | 数据记录内容 | 字节值 |
---|---|---|---|
0x21091968 | #1 | dataRecord[ data#1 ] = B+ | 0x8C |
#2 | dataRecord[ data#2 ] = ECT | 0xA6 | |
#3 | dataRecord[ data#3 ] = TP | 0x66 | |
#4 | dataRecord[ data#4 ] = RPM | 0x07 | |
#5 | dataRecord[ data#5 ] = RPM | 0x50 | |
#6 | dataRecord[ data#6 ] = MAP | 0x20 | |
#7 | dataRecord[ data#7 ] = MAF | 0x1A | |
#8 | dataRecord[ data#8 ] = VSS | 0x00 | |
#9 | dataRecord[ data#9 ] = BARO | 0x63 | |
#10 | dataRecord[ data#10 ] = LOAD | 0x4A | |
#11 | dataRecord[ data#11 ] = IAC | 0x82 | |
#12 | dataRecord[ data#12 ] = APP | 0x7E | |
0x13101994 | #1 | dataRecord[ data#1 ] = SPARKADV | 0x00 |
#2 | dataRecord[ data#2 ] = KS | 0x91 |
2. 示例 1:sub-funtion = defineByIdentifier,单一数据信息的 2 字节 DID
本示例使用 2 字节数据标识符作为要求数据的引用来生成一个包含发动机机油温度、环境空气温度以及发动机油位的动态数据标识符(DDDI 0xF301)。
step1:0x2C 动态定义
req 2C 01 F3 01
12 34 (sourceDataIdentifier#1)
01(positionInSourceDataRecord#1 - 发动机机油温度)
02(memorySize#1)
56 78(sourceDataIdentifier#2)
01(positionInSourceDataRecord#2 - 环境空气温度)
01(memorySize#2)
9A BC(sourceDataIdentifier#3)
01(positionInSourceDataRecord#3 - 发动机油位)
04(memorySize#3)
resp 6C 01 F3 01
step2:请求 0x22 读取 DDDI 0xF301
req 22 F3 01
resp 62 F3 01 4C 36 4D 49 21 00 17
3. 示例 2:sub-funtion = defineByIdentifier,复合数据块的 DID
本示例会生成一个包含发动机冷却液温度(来自数据记录 0x010A)、发动机转速(0x010A)、怠速空气控制枢轴位置(0x010A)以及爆震传感器(0x050B)的动态标识符(DDDI 0xF302)。
step1:0x2C 动态定义
req 2C 01 F3 02
01 0A (sourceDataIdentifier#1)
02(positionInSourceDataRecord#1 - 发送机冷却液温度)
01(memorySize#1)
01 0A(sourceDataIdentifier#2)
04(positionInSourceDataRecord#2 - 发动机转速)
02(memorySize#2)
01 0A(sourceDataIdentifier#3)
0B(positionInSourceDataRecord#3 - 怠速空气控制)
01(memorySize#3)
05 0B(sourceDataIdentifier#3)
02(positionInSourceDataRecord#3 - 爆震传感器)
01(memorySize#3)
resp 6C 01 F3 02
step2:请求 0x22 读取 DDDI 0xF302
req 22 F3 02
resp 62 F3 02 A6 07 50 82 91
4. 示例 3:sub-funtion = defineByMemoryAddress
本示例会生成一个包含发送机冷却液温度(来自从内存地址 0x21091969 开始的内存块)、发动机转速(来自从内存地址 0x21091969 开始的内存块)以及爆震传感器(来自从内存地址 0x13101995 开始的内存块)的动态标识符(DDDI 0xF302)。
step1:0x2C 动态定义
req 2C 02 F3 02
14(addressAndLengthFormatIdentifier)
21 09 19 69(memoryAddress#1)
01(memorySize#1)
21 09 19 6B(memoryAddress#2)
02(memorySize#2)
13 10 19 95(memoryAddress#2)
01(memorySize#3)
resp 6C 02 F3 02
step2:请求 0x22 读取 DDDI 0xF302
req 22 F3 02
resp 62 F3 02 A6 07 50 91
5. 示例 4:sub-funtion = defineByIdentifier,复合数据块的DID,0x2A 请求
本示例会生成一个包含发动机冷却液温度(来自数据记录 0x010A)、发动机转速(0x010A)、以及爆震传感器(0x050B)的动态标识符(DDDI 0xF2E7)。
动态数据标识符的值选自可用于周期性请求数据的范围内。在定义动态数据标识符后,客户端请求待周期性(较快速率)发送的数据标识符。
step1:0x2C 动态定义
req 2C 01 F2 E7
01 0A (sourceDataIdentifier#1)
02(positionInSourceDataRecord#1 - 发动机冷却液温度)
01(memorySize#1)
01 0A (sourceDataIdentifier#2)
04(positionInSourceDataRecord#2 - 发动机转速)
02(memorySize#2)
05 0B(sourceDataIdentifier#3)
02(positionInSourceDataRecord#3 - 爆震传感器)
01(memorySize#3)
resp 6C 01 F2 E7
step2:请求 0x2A
req 2A 04 E7
resp 6A
resp-1 E7 A6 07 50 91
resp-n E7 A6 07 55 98
// 本示例中未展示字节值不同的多条响应消息。
关于 0x2A 的请求响应信息,见0x2A服务
6. 示例 5:sub-funtion = clearDynamicallyDefinedDataIdentifier
本示例展示了动态定义的数据标识符的清除过程,并假设发出请求时 DDDI 0xF303 存在。
req 2C 03 F3 03
resp 6C 03 F3 03
7. 示例 7:动态定义的数据标识符,定义的串联(defineByIdentifier(按标识符定义)/ defineByAddress(按地址定义))
本示例会使用两种定义类型生成一个动态数据标识符(DDDI 0xF301)。下文列出了动态定义的数据标识符中数据的顺序(定义动态数据标识符的请求消息的隐序):
— 第 1 部分:2 字节数据标识符引用的发送机机油温度和环境空气温度,
— 第 2 部分:内存地址引用的发动机冷却液温度和发动机转速,
— 第 3 部分:2 字节数据标识符引用的发动机油位。
step1:第 1 部分
第 1 部分:2 字节数据标识符引用的发送机机油温度和环境空气温度
req 2C 01 F3 01
12 34 (sourceDataIdentifier#1)
01(positionInSourceDataRecord#1 - 发动机机油温度)
02(memorySize#1)
56 78(sourceDataIdentifier#2)
01(positionInSourceDataRecord#2 - 环境空气温度)
01(memorySize#2)
resp 6C 01 F3 01
step2:第 2 部分
第 2 部分:内存地址引用的发动机冷却液温度和发动机转速
req 2C 02 F3 01
14(addressAndLengthFormatIdentifier)
21 09 19 69(memoryAddress#1)
01(memorySize#1)
21 09 19 6B(memoryAddress#2)
02(memorySize#2)
resp 6C 02 F3 01
step3:第 3 部分
第 3 部分:2 字节数据标识符引用的发动机油位。
req 2C 01 F3 01
9A BC(sourceDataIdentifier#1)
01(positionInSourceDataRecord#1 - 发动机油位)
04(memorySize#1)
resp 6C 01 F3 01
step4:请求 0x22,读取 DDDI 0xF301
req 22 F3 01
resp 62 F3 01 4C 36 4D A6 07 50 49 21 00 17
step5:清楚 DDDI 0xF301
req 2C 03 F3 01
resp 6C 03 F3 01