目录
1、0x2C服务(DynamicallyDefineDataIdentifier,动态定义数据标识符服务)
Service description:
0x2C服务(DynamicallyDefineDataIdentifier,动态定义数据标识符服务)允许客户端在服务端动态地定义一个数据标识符(DID),在之后一段时间内可以通过0x22服务(ReadDataByIdentifier,读取数据标识符服务)读取。
该服务的目的是为客户端提供将一个或多个数据元素分组到一个数据超集的能力,该超集可以通过0x22服务(ReadDataByIdentifier,读取数据标识符服务)或 0x2A服务(ReadDataByPeriodicIdentifer,根据周期数据标识符读取数据)进行请求。要分组的数据元素可以参考如下:
——一个源数据标识符,一个position和size
——一个内存地址和一个内存长度
——上面列出的两种方法的组合,并使用多个请求定义单个数据元素。然后,动态定义的数据标识符将包含一连串的数据参数定义。
在处理诊断应用程序的临时数据需求,该服务有更大的灵活性,这些数据需求超出了通过静态定义数据标识符读取的信息。该服务可以通过避免与频繁请求/响应任务相关的开销损失,来降低带宽使用率。
动态定义数据标识符可以通过一条请求报文或者多个请求报文来完成。这允许引用源标识符和内存地址的单个数据元素。服务端必须连接单个数据元素的定义。动态定义的数据标识符的重新定义可以通过清除当前定义并重新使用新定义来实现。当多个DynamicallyDefineDataIdentifier请求报文用于配置单个数据标识符,并且服务端在该数据标识符的后续请求期间检测到最大字节数的溢出(例如,周期性数据标识符的定义),那么服务端将保留数据标识符的定义,因为它在请求之前会导致溢出。
尽管此服务不禁止此类功能,但不建议客户端从一个动态定义的数据记录中引用另一个动态定义的数据记录,因为删除被引用的记录可能会在引用记录中产生数据一致性问题。
此服务提供了清除现有动态定义数据记录的功能。如果指定的数据记录标识符在服务端支持的有效动态数据标识符范围内,则对清除数据记录的请求报文作出肯定应答。服务端应该保持动态定义数据记录直到其被删除或者是车辆制造厂商指定的条件(如会话切换时删除或者服务端下电时删除)。
服务端可以用两种不同的方式实现数据记录:
——包含不单独引用的多个元素数据记录的组合数据记录;
——唯一的2字节标识“tag”或数据标识符(DID)值,用于服务端中支持的单个元素数据记录(例如元素数据记录,或DID,是发动机转速或进气温度)。数据记录的实现是复合数据记录实现的一个子集,因为它只引用单个元素数据记录,而不是包含多个元素数据记录的数据记录。
——DynamicallyDefineDataIdentifier服务支持以上两种实现数据记录的方法来定义动态的数据标识符。复合数据块:position参数必须引用复合数据块中的起始点,size参数必须反映要放在动态定义的数据标识符中的数据的长度。测试人员有责任在动态数据记录中不只包括复合数据块的基本数据记录的一部分。
——2字节DID: position参数必须设置为1,size参数必须反映DID的长度(元素数据记录的长度)。测试人员负责在动态数据记录中不只包括2字节DID值的一部分。动态定义数据记录内的数据顺序应与客户端请求消息中指定的顺序相同。此外,客户请求中指定的数据的第一个位置应根据前句所述的排序要求,使其最靠近动态数据记录的开始位置。
除了通过逻辑引用(记录数据标识符)定义动态数据标识符之外,此服务还提供了通过绝对内存地址和内存长度信息定义动态定义数据标识符的功能。建议仅在服务端的开发阶段使用这种定义动态数据标识符的机制。
2、请求报文格式
2.1 请求报文定义
sub-function = defineByIdentifier的请求报文定义:
字节序号 | 参数值 | 约定 | 字节值 |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | M | 0x2C |
#2 | sub-function = [ definitionType = defineByIdentifier ] | M | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [ byte#1 (MSB) byte#2 (LSB) ] | M M | 0xF2/0xF3 0x00 - 0xFF |
#5 #6 | sourceDataIdentifier[]#1 = [ byte#1 (MSB) byte#2 (LSB) ] | M M | 0x00 - 0xFF 0x00 - 0xFF |
#7 | positionInSourceDataRecord#1 | M | 0x00 - 0xFF |
#8 | memorySize#1 | M | 0x00 - 0xFF |
. . | . . | . . | . . |
#n-3 #n-2 | sourceDataIdentifier[]#m = [ byte#1 (MSB) byte#2 (LSB) ] | U U | 0x00 - 0xFF 0x00 - 0xFF |
#n-1 | positionInSourceDataRecord#m | U | 0x01 - 0xFF |
#n | memorySize#m | U | 0x00 - 0xFF |
sub-function = defineByMemoryAddress的请求报文定义:
字节序号 | 参数值 | 约定 | 字节值 |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | M | 0x2C |
#2 | sub-function = [ definitionType = defineByMemoryAddress ] | M | 0x02 |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [ byte#1 (MSB) byte#2 (LSB) ] | M M | 0xF2/0xF3 0x00 - 0xFF |
#5 | addressAndLengthFormatIdentifier | M1 | 0x00 - 0xFF |
#6 . . #(m-1)+6 | memoryAddress[] = [ byte#1 (MSB) . . byte#m ] | M . . C1 | 0x00 - 0xFF . . 0x00 - 0xFF |
#m+6 . . #(m+6)+(k-1) | memorySize[] = [ byte#1 (MSB) . . byte#k ] | M . . C2 | 0x00 - 0xFF . . 0x00 - 0xFF |
. . | . . | . . | . . |
#n-k-(m-1) . . #n-k | memoryAddress[] = [ byte#1 (MSB) . . byte#m ] | M . . C1 | 0x00 - 0xFF . . 0x00 - 0xFF |
#n-(k-1) . . #n | memorySize[] = [ byte#1 (MSB) . . byte#k ] | U . . U/C2 | 0x00 - 0xFF . . 0x00 - 0xFF |
M1:addressAndLengthFormatIdentifier参数只在请求消息的开头出现一次,它定义了整个请求消息中每个内存位置引用的地址长度和长度信息。
C1:该参数的存在取决于addressAndLengthFormatIdentifier的地址长度信息参数。
C2:该参数的存在取决于addressAndLengthFormatIdentifier的内存大小长度信息。
sub-function = clearDynamicallyDefinedDataIdentifier的请求报文定义:
字节序号 | 参数值 | 约定 | 字节值 |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | M | 0x2C |
#2 | sub-function = [ definitionType = clearDynamicallyDefinedDataIdentifier ] | M | 0x03 |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [ byte#1 (MSB) byte#2 (LSB) ] | C C | 0xF2/0xF3 0x00 - 0xFF |
C:这个参数的存在要求服务端清除包含在字节#1和字节#2中的动态定义数据标识符。如果该参数不存在,服务端中的所有dynamallydefineddataidentifier都将被清除。
2.2 请求报文中子函数参数定义
子函数参数定义如下表:
字节值 | 描述 | 约定 |
---|---|---|
0x00 | ISOSAEReserved ISO保留 | M |
0x01 | defineByIdentifier 该值用于向服务端指定动态数据标识符的定义应通过引用数据标识符发生。 | U |
0x02 | defineByMemoryAddress 该值用于向服务端指定动态数据标识符的定义应通过引用地址发生。 | U |
0x03 | clearDynamicallyDefinedDataIdentifier 该值用于清除指定的动态数据标识符。请注意,服务端应该正响应来自客户端的明确请求,即使在请求时指定的动态数据标识符不存在。但是,指定的动态数据标识符必须在有效范围内。如果在请求时正在周期报告的动态数据标识符,则应首先停止动态标识符,然后清除。 | U |
0x04-0x7F | ISOSAEReserved ISO保留 | M |
2.3 请求报文中数据参数定义
该服务在请求报文中的数据参数定义如下表所示:
定义 |
---|
dynamicallyDefinedDataIdentifier 该参数指定客户端定义的动态数据记录将如何在将来调用ReadDataByIdentifier或ReadDataByPeriodicDataIdentifier服务时被引用。动态定义的数据标识符应该在ReadDataByIdentifier服务中作为数据标识符(DID)来处理。它应该在ReadDataByPeriodicDataIdentifier服务中作为一个periodicRecordIdentifier来处理(请参阅ReadDataByPeriodicDataIdentifier服务,了解该参数值的要求,以便能够定期请求动态定义的数据标识符)。 |
sourceDataIdentifier 此参数仅在sub-function = defineByIdentifier中出现。此参数在逻辑上指定了要包含在动态数据记录中的信息源。例如,可用于表示发动机转速的2字节DID,或者一个用于表示包含发动机转速、车速、进气温度等信息的复合块的2字节DID。 |
positionInSourceDataRecord 此参数仅在sub-function = defineByIdentifier中出现。这个1字节的参数指定了包含在动态数据记录中源数据记录的摘录起始字节位置。1位置应该表示由sourceDataIdentifier引用的数据记录的第一个字节。 |
addressAndLengthFormatIdentifier 该参数是一个单独编码的单字节值: bit 7 - 4: memorySize参数的长度(字节数); bit 3 - 0: memoryAddress参数的长度(字节数); |
memoryAddress 此参数仅在sub-function = defineByMemoryAddress中出现。此参数指定了包含在动态数据记录中的信息的内存源地址。用于此地址的字节数由addressAndLengthFormatIdentifier的低位(Bit3 - 0)定义。memoryAddress参数中的字节#m始终是服务端中引用的地址中最低位字节。地址的最高位字节可用作内存标识符。 |
memorySize 该参数用于指定要包含在动态数据记录中的源数据记录/内存地址的总字节数。 在sub-function = defineByIdentifier的情况下,此外,还使用positionInSourceDataRecord参数指定源数据标识符中memorySize应用的起始位置。用于此大小的字节数是一个字节。 在sub-function = defineByMemoryAddress的情况下,这个参数反映了从指定的memoryAddress开始的动态定义的数据标识符中要包含的字节数。用于此大小的字节数由addressAndLengthFormatIdentifier的高位(位7 - 4)定义。 |
3、肯定应答报文
3.1 肯定应答报文格式定义
肯定应答报文的定义见下表。
字节序号 | 参数值 | 约定 | 字节值 |
---|---|---|---|
#1 | DynamicallyDefineDataIdentifier Response SID | M | 0x6C |
#2 | sub-function = [ definitionType ] | M | 0x00 - 0x7F |
#3 #4 | dynamicallyDefinedDataIdentifier[] = [ byte#1 (MSB) byte#2 (LSB) ] | C C | 0xF2/0xF3 0x00 - 0xFF |
C:如果请求消息中存在dynamallydefineddataidentifier参数,则需要此参数的存在,否则将不包含该参数。
3.2 肯定应答报文数据参数定义
肯定应答报文中报文数据参数的定义见下表:
Definition |
---|
definitionType 请求报文中子函数中的bit6-0。 |
dynamicallyDefinedDataIdentifier 请求报文中数据参数dynamicallyDefinedDataIdentifier。 |
4、支持的否定应答码(NRC_)
本服务应实施如下否定响应代码,下表记录了每个应答代码发生的情况,如果服务端在错误场景使用了该服务,则应使用如下列出的否定响应代码。
NRC | 描述 |
---|---|
0x12 | sub-functionNotSupported 子函数参数不支持,会发送该NRC |
0x13 | incorrectMessageLengthOrInvalidFormat 请求报文长度不正确,会发送该NRC |
0x22 | conditionsNotCorrect 服务端的运行条件不满足去执行请求的动作时,会发送该NRC。 |
0x31 | requestOutOfRange 如下情况发送该NRC: — 请求报文中任意一个数据标识符不支持或者无效时; — positionInSourceDataRecord参数不正确(小于1,或者超出最大值); — 请求报文中任意的内存地址在服务端中不支持时; — 指定的内存尺寸无效时; — 动态数据标识符中打包的数据总量超出了服务端所允许的最大值; — 指定的addressAndLengthFormatIdentifier无效; — 动态定义的periodicDataIdentifier的总长度超过了用于传输周期性响应消息的数据链路的单个帧所能容纳的最大长度; |
0x33 | SecurityAccessDenied 如下情况发送该NRC: — 请求报文中任何的数据标识符(动态定义数据标识符或者源数据标识符)是保密的,而服务端处理处于未解锁状态; — 请求报文中任何的内存地址是保密的,而服务端处理处于未解锁状态; |
5、0x2C服务(DynamicallyDefineDataIdentifier,动态定义数据标识符服务)案例说明
Assumptions:
假设如下案例中0x2C服务的前提条件都是满足的。
在第一个案例中,服务端支持两个字节的DID,其表示单个数据信息。该案例中使用defineByIdentifier方法构建一个动态数据标识符,然后发送一个ReadDataByIdentifier请求来读取刚刚配置的动态数据标识符。
在第二个案例中,服务端支持数据标识符,它引用了包含多个数据信息的复合数据块。该案例也使用defineByIdentifier方法构建一个动态标识符,并发送一个ReadDataByIdentifier请求来读取刚刚定义的数据标识符。
第三个案例使用defineByMemoryAddress方法构建动态数据标识符,并发送ReadDataByIdentifier请求来读取刚刚定义的数据标识符。
在第四个案例中,服务端支持数据标识符,它引用包含多个数据信息的复合数据块。该示例使用defineByIdentifier方法构建动态数据标识符,然后使用ReadDataByPeriodicIdentifier服务请求服务器定期发送动态定义的数据标识符。
第五个案例中演示了如何删除动态定义的数据标识符。
下表将用于下面的例子。在真实车辆上,报告的值可能会随着时间的推移而变化,但为了清晰起见,将其显示为常数。
复合数据块-数据标识符定义
数据标识符(Block) | 数据字节 | 数据记录内容 | 字节值 |
---|---|---|---|
0x010A | #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 | dataRecord [ data#1 ] = B+ dataRecord [ data#2 ] = ECT dataRecord [ data#3 ] = TP dataRecord [ data#4 ] = RPM dataRecord [ data#5 ] = RPM dataRecord [ data#6 ] = MAP dataRecord [ data#7 ] = MAF dataRecord [ data#8 ] = VSS dataRecord [ data#9 ] = BARO dataRecord [ data#10 ] = LOAD dataRecord [ data#11 ] = IAC dataRecord [ data#12 ] = APP | 0x8C 0xA6 0x66 0x07 0x50 0x20 0x1A 0x00 0x63 0x4A 0x82 0x7E |
0x050B | #1 #2 | dataRecord [ data#1 ] = SPARKADV dataRecord [ data#2 ] = KS | 0x00 0x91 |
元素数据记录 - DID定义
数据标识符(Block) | 数据字节 | 数据记录内容 | 字节值 |
---|---|---|---|
0x1234 | #1 #2 | EOT (MSB) EOT (LSB) | 0x4C 0x36 |
0x5678 | #1 | AAT | 0x4D |
0x9ABC | #1 #2 #3 #4 | EOL (MSB) EOL EOL EOL(LSB) | 0x49 0x21 0x00 0x17 |
内存数据记录 - 内存地址定义
内存地址 | 数据字节 | 数据记录内容 | 字节值 |
---|---|---|---|
0x21091968 | #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 | dataRecord [ data#1 ] = B+ dataRecord [ data#2 ] = ECT dataRecord [ data#3 ] = TP dataRecord [ data#4 ] = RPM dataRecord [ data#5 ] = RPM dataRecord [ data#6 ] = MAP dataRecord [ data#7 ] = MAF dataRecord [ data#8 ] = VSS dataRecord [ data#9 ] = BARO dataRecord [ data#10 ] = LOAD dataRecord [ data#11 ] = IAC dataRecord [ data#12 ] = APP | 0x8C 0xA6 0x66 0x07 0x50 0x20 0x1A 0x00 0x63 0x4A 0x82 0x7E |
0x13101994 | #1 #2 | dataRecord [ data#1 ] = SPARKADV dataRecord [ data#2 ] = KS | 0x00 0x91 |
Example #1: DynamicallyDefineDataIdentifier, sub-function = defineByIdentifier
下表中案例将会使用2个字节的DID作为所需数据的参考,来搭建动态数据标识符(DDDI 0xF301),其包含了发动机油温,环境空气温度,和发动机油液等级。
DynamicallyDefineDataIdentifier请求DDDDI 0xF301消息流案例 #1
请求报文由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
#5 #6 | sourceDataIdentifier#1 [ byte#1 ] (MSB) - Engine Oil Temperature sourceDataIdentifier#1 [ byte#2 ] | 0x12 0x34 |
#7 | positionInSourceDataRecord#1 | 0x01 |
#8 | memorySize#1 | 0x02 |
#9 #10 | sourceDataIdentifier#2 [ byte#1 ] (MSB) - Ambient Air Temperature sourceDataIdentifier#2 [ byte#2 ] | 0x56 0x78 |
#11 | positionInSourceDataRecord#2 | 0x01 |
#12 | memorySize#2 | 0x01 |
#13 #14 | sourceDataIdentifier#3 [ byte#1 ] (MSB) - Engine Oil Level sourceDataIdentifier#3 [ byte#2 ] | 0x9A 0xBC |
#15 | positionInSourceDataRecord#3 | 0x01 |
#16 | memorySize#3 | 0x04 |
下表定义了动态定义数据标识符DDDDI 0xF301的消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | sub-function = defineByIdentifier | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
下表定义了使用了0x22服务请求DDDDI 0xF301的消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x22 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
下表定义了使用了0x22服务请求DDDDI 0xF301的肯定应答报文消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x62 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
#4 #5 #6 #7 #8 #9 #10 | dataRecord [ data#1 ] = EOT dataRecord [ data#2 ] = EOT dataRecord [ data#3 ] = AAT dataRecord [ data#4 ] = EOL dataRecord [ data#5 ] = EOL dataRecord [ data#6 ] = EOL dataRecord [ data#7 ] = EOL | 0x4C 0x36 0x4D 0x49 0x21 0x00 0x17 |
Example #2: DynamicallyDefineDataIdentifier, sub-function = defineByIdentifier
下表中案例搭建了动态数据标识符(DDDI 0xF302),其包含了发动机冷却液温度(来源于数据记录0x010A),发动机转速(来源于数据记录0x010A),IAC曲轴销位(来源于数据记录0x010A)和爆震传感器(来源于数据记录0x050B)。
DynamicallyDefineDataIdentifier请求DDDDI 0xF302消息流案例 #2
请求报文由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
#5 #6 | sourceDataIdentifier#1 [ byte#1 ] (MSB) sourceDataIdentifier#1 [ byte#2 ] (LSB) | 0x01 0x0A |
#7 | positionInSourceDataRecord#1- Engine Coolant Temperature | 0x02 |
#8 | memorySize#1 | 0x01 |
#9 #10 | sourceDataIdentifier#2 [ byte#1 ] (MSB) sourceDataIdentifier#2 [ byte#2 ] (LSB) | 0x01 0x0A |
#11 | positionInSourceDataRecord#2 - Engine Speed | 0x04 |
#12 | memorySize#2 | 0x02 |
#13 #14 | sourceDataIdentifier#3 [ byte#1 ] (MSB) sourceDataIdentifier#3 [ byte#2 ] (LSB) | 0x01 0x0A |
#15 | positionInSourceDataRecord#3 – Idle Air Control | 0x0B |
#16 | memorySize#3 | 0x01 |
#17 #18 | sourceDataIdentifier#4 [ byte#1 ] (MSB) sourceDataIdentifier#4 [ byte#2 ] (LSB) | 0x05 0x0B |
#19 | positionInSourceDataRecord#3 – Idle Air Control | 0x02 |
#20 | memorySize#4 | 0x01 |
下表定义了动态定义数据标识符DDDDI 0xF302的消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | sub-function = defineByIdentifier | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
下表定义了使用了0x22服务请求DDDDI 0xF302的消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x22 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
下表定义了使用了0x22服务请求DDDDI 0xF302的肯定应答报文消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x62 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
#4 #5 #6 #7 #8 | dataRecord [ data#1 ] = ECT dataRecord [ data#2 ] = RPM dataRecord [ data#3 ] = RPM dataRecord [ data#4 ] = IAC dataRecord [ data#5 ] = KS | 0xA6 0x07 0x50 0x82 0x91 |
Example #3: DynamicallyDefineDataIdentifier, sub-function = defineByMemoryAddress
下表中案例搭建了动态数据标识符(DDDI 0xF303),其包含了发动机冷却液温度(来源于起始地址为0x21091969的内存块),发动机转速(来源于起始地址为0x2109196B的内存块),和爆震传感器(来源于起始地址为0x13101995的内存块)。
DynamicallyDefineDataIdentifier请求DDDDI 0xF302消息流案例 #3
请求报文由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByMemoryAddress, suppressPosRspMsgIndicationBit = FALSE | 0x02 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
#5 | addressAndLengthFormatIdentifier | 0x14 |
#6 #7 #8 #9 | memoryAddress#1 [ byte#1 ] (MSB) - Engine Coolant Temperature memoryAddress#1 [ byte#2 ] memoryAddress#1 [ byte#3 ] memoryAddress#1 [ byte#4 ] | 0x21 0x09 0x19 0x69 |
#10 | memorySize#1 | 0x01 |
#11 #12 #13 #14 | memoryAddress#2 [ byte#1 ] (MSB)- Engine Speed memoryAddress#2 [ byte#2 ] memoryAddress#2 [ byte#3 ] memoryAddress#2 [ byte#4 ] | 0x21 0x09 0x19 0x6B |
#15 | memorySize#2 | 0x02 |
#16 #17 #18 #19 | memoryAddress#3 [ byte#1 ] (MSB) - Knock Sensor memoryAddress#3 [ byte#2 ] memoryAddress#3 [ byte#3 ] memoryAddress#3 [ byte#4 ] | 0x13 0x10 0x19 0x35 |
#20 | memorySize#3 | 0x01 |
下表定义了动态定义数据标识符DDDDI 0xF302的消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = defineByMemoryAddress | 0x02 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
下表定义了使用了0x22服务请求DDDDI 0xF302的消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x22 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
下表定义了使用了0x22服务请求DDDDI 0xF302的肯定应答报文消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x62 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x02 |
#4 #5 #6 #7 | dataRecord [ data#1 ] = ECT dataRecord [ data#2 ] = RPM dataRecord [ data#3 ] = RPM dataRecord [ data#5 ] = KS | 0xA6 0x07 0x50 0x91 |
Example #4: DynamicallyDefineDataIdentifier, sub-function = defineByIdentifier
下表中案例搭建了动态数据标识符(DDDI 0xF2E7),其包含了发动机冷却液温度(来源于0x101A),发动机转速(来源于0x101A),和爆震传感器(来源于0x050B)。
动态数据标识符的值是从可用于周期请求数据的范围中选择的。根据动态数据标识符的定义,客户端请求定期(快速)发送数据标识符。
DynamicallyDefineDataIdentifier请求DDDDI 0xF2E7消息流案例 #4
请求报文由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF2 0xE7 |
#5 #6 | sourceDataIdentifier#1 [ byte#1 ] (MSB) sourceDataIdentifier#1 [ byte#2 ] (LSB) | 0x01 0x0A |
#7 | positionInSourceDataRecord#1- Engine Coolant Temperature | 0x02 |
#8 | memorySize#1 | 0x01 |
#9 #10 | sourceDataIdentifier#2 [ byte#1 ] (MSB) sourceDataIdentifier#2 [ byte#2 ] (LSB) | 0x01 0x0A |
#11 | positionInSourceDataRecord#2 - Engine Speed | 0x04 |
#12 | memorySize#2 | 0x02 |
#13 #14 | sourceDataIdentifier#3 [ byte#1 ] (MSB) sourceDataIdentifier#3 [ byte#2 ] (LSB) | 0x05 0x0B |
#15 | positionInSourceDataRecord#3- Knock Sensor | 0x02 |
#16 | memorySize#3 | 0x01 |
下表定义了动态定义数据标识符DDDDI 0xF2E7的消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = defineByIdentifier | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF2 0xE7 |
下表定义了使用了0x2A服务请求DDDDI 0xF2E7的消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByPeriodicIdentifier Request SID | 0x2A |
#2 | transmissionMode = sendAtFastRate | 0x04 |
#3 | PeriodicDataIdentifier | 0xE7 |
下表定义了使用了0x2A服务请求DDDDI 0xF2E7初始的肯定应答报文消息流案例
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByPeriodicIdentifier Response SID | 0x6A |
下面两个表定义了ReadDataByPeriodicIdentifier周期数据响应#1 DDDDI 0xF2E7消息流示例#4。
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | PeriodicDataIdentifier | 0xE7 |
#2 #3 #4 #5 | dataRecord [ data#1 ] = ECT dataRecord [ data#2 ] = RPM dataRecord [ data#3 ] = RPM dataRecord [ data#4 ] = KS | 0xA6 0x07 0x50 0x91 |
ReadDataByPeriodicIdentifier周期数据响应#n DDDDI 0xF2E7消息流示例#4。
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | PeriodicDataIdentifier | 0xE7 |
#2 #3 #4 #5 | dataRecord [ data#1 ] = ECT dataRecord [ data#2 ] = RPM dataRecord [ data#3 ] = RPM dataRecord [ data#4 ] = KS | 0xA6 0x07 0x55 0x98 |
Example #5: DynamicallyDefineDataIdentifier, sub-function = clearDynamicallyDefined-DataIdentifier
下表中示例演示了清除动态定义数据标识符,并假设DDDDI 0xF303在请求时存在。
DynamicallyDefineDataIdentifier请求清除DDDDI 0xF303消息流案例 #5
请求报文由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = clearDynamicallyDefinedDataIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x03 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x03 |
下表定义了清除动态定义数据标识符DDDDI 0xF303消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = clearDynamicallyDefinedDataIdentifier | 0x03 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x03 |
Example #6: DynamicallyDefineDataIdentifier, concatenation of definitions (defineByIdentifier / defineByAddress)
下表中案例使用两种定义类型搭建了动态数据标识符(DDDI 0xF301),下面的列表显示了动态定义的数据标识符中的数据顺序(定义动态数据标识符请求消息的隐式顺序):
—— 第一部分:2个字节DID表示发动机油液温度和环境空气温度;
—— 第二部分:内存地址表示的发动机冷却液温度和发送机转速;
—— 第三部分:2个字节DID表示发动机油液等级;
Step #1: DynamicallyDefineDataIdentifier, sub-function = defineByIdentifier (1 st portion)
下表定义了第一部分DynamicallyDefineDataIdentifier请求DDDI 0xF301的报文消息流案例#6,由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
#5 #6 | sourceDataIdentifier#1 [ byte#1 ] (MSB) - Engine Oil Temperature sourceDataIdentifier#1 [ byte#2 ] (LSB) | 0x12 0x34 |
#7 | positionInSourceDataRecord#1 | 0x01 |
#8 | memorySize#1 | 0x02 |
#9 #10 | sourceDataIdentifier#2 [ byte#1 ] (MSB) - Ambient Air Temperature sourceDataIdentifier#2 [ byte#2 ] (LSB) | 0x56 0x78 |
#11 | positionInSourceDataRecord#2 | 0x01 |
#12 | memorySize#2 | 0x01 |
下表定义了动态定义数据标识符DDDDI 0xF301消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = defineByIdentifier | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
Step #2: DynamicallyDefineDataIdentifier, sub-function = defineByMemoryAddress (2nd portion)
下表定义了第二部分(defineByMemoryAddress) DynamicallyDefineDataIdentifier请求DDDI 0xF301的报文消息流案例#6,由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByMemoryAddress, suppressPosRspMsgIndicationBit = FALSE | 0x02 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
#5 | addressAndLengthFormatIdentifier | 0x14 |
#6 #7 #8 #9 | memoryAddress#1 [ byte#1 ] (MSB) - Engine Coolant Temperature memoryAddress#1 [ byte#2 ] memoryAddress#1 [ byte#3 ] memoryAddress#1 [ byte#4 ] | 0x21 0x09 0x19 0x69 |
#10 | memorySize#1 | 0x01 |
#11 #12 #13 #14 | memoryAddress#2 [ byte#1 ] (MSB) - Engine Speed memoryAddress#2 [ byte#2 ] memoryAddress#2 [ byte#3 ] memoryAddress#2 [ byte#4 ] | 0x21 0x09 0x19 0x69 |
#12 | memorySize#2 | 0x02 |
下表定义了动态定义数据标识符DDDDI 0xF301消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = defineByMemoryAddress | 0x02 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
Step #3: DynamicallyDefineDataIdentifier, sub-function = defineByIdentifier (3 rd portion)
下表定义了第三部分(defineByIdentifier) DynamicallyDefineDataIdentifier请求DDDI 0xF301的报文消息流案例#6,由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = defineByIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
#5 #6 | sourceDataIdentifier#1 [ byte#1 ] (MSB) - Engine Oil Level sourceDataIdentifier#1 [ byte#2 ] (LSB) | 0x9A 0xBC |
#7 | positionInSourceDataRecord#1 | 0x01 |
#8 | memorySize#1 | 0x04 |
下表定义了动态定义数据标识符DDDDI 0xF301消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = defineByIdentifier | 0x01 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
Step #4:ReadDataByIdentifier - dataIdentifier = DDDDI 0xF301
下表定义了0x22服务(ReadDataByIdentifier)请求DDDDI 0xF301的消息报文流
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | ReadDataByIdentifier Request SID | 0x22 |
#2 #3 | dataIdentifier [ byte#1 ] (MSB) dataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
#4 #5 #6 #7 #8 #9 #10 #11 #12 #13 | dataRecord [ data#1 ] = EOT(MSB) dataRecord [ data#2 ] = EOT dataRecord [ data#3 ] = AAT dataRecord [ data#4 ] = ECT dataRecord [ data#5 ] = RPM dataRecord [ data#6 ] = RPM dataRecord [ data#7 ] = EOT(MSB) dataRecord [ data#8 ] = EOL dataRecord [ data#9 ] = EOL dataRecord [ data#10 ] = EOL | 0x4C 0x36 0x4D 0xA6 0x07 0x50 0x49 0x21 0x00 0x17 |
Step #5:DynamicallyDefineDataIdentifier - clear definition of DDDDI 0xF301
DynamicallyDefineDataIdentifier请求清除DDDDI 0xF301消息流案例 #6
请求报文由客户端发向服务端(ECU):
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x2C |
#2 | sub-function = clearDynamicallyDefinedDataIdentifier, suppressPosRspMsgIndicationBit = FALSE | 0x03 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |
下表定义了清除动态定义数据标识符DDDDI 0xF301消息流的肯定应答,应答报文由服务端发向客户端:
数据字节 | 描述 | 字节值 |
---|---|---|
#1 | DynamicallyDefineDataIdentifier Request SID | 0x6C |
#2 | definitionMode = clearDynamicallyDefinedDataIdentifier | 0x03 |
#3 #4 | dynamicallyDefinedDataIdentifier [ byte#1 ] (MSB) dynamicallyDefinedDataIdentifier [ byte#2 ] (LSB) | 0xF3 0x01 |