UDS 协议详解

基本概念

对于 UDS 协议,没法剥离出一个完全原子的概念出来理解,很多概念之间是相互穿插着的。

所以私以为一种比较好的理解思路便是,一股脑的介绍完所有的概念,

然后再通过一个简单的服务请求,或是 DTC 的报告,将这些概念逐个逐个的进行穿插和联系。

(TODO:后续可以画两个图,分别将 DCMDEM 的概念串联起来;实名 diss 一下公司的某讲师,一上来就把各种服务的参数怼新人的脸上,不知道的以为是在期末考试划重点。。。)


子服务

一个 Bit 有 8 个 b,其中的后 7 个 b 表示子服务的 id,而第 8 个 b 表示是否抑制肯定响应位。

抑制肯定响应位的含义有两层,第一层是如果当前需要回复的是消极响应,那么无论如何都需要回复出去;

第二层是,只有需要回复的是积极响应,并且没有发送过 0x78 的报文(也就是 p2 没有超时),那么则不需要回复该积极响应,否则都要回复。


积极响应与消极响应


常见的定时器

主要分为 p2、p2* 以及 s3。


DataIdentifier


RoutineIdentifier


Session


SecurityLevel


DiagnosticTroubleCode


DiagnosticTroubleCodeStatus

Bit Name Description
Bit0 TestFailed 表示 DTC 最近一次报告的结果是否为 Failed。
当最近一次报告的结果为 Failed 时,需要将当前 Bit 置为 1;
当最近一次报告的结果为 Passed、DEM 模块首次初始化、或者 ClearDiagnosticInformation 时,需要将当前 Bit 置为 0(老化成功并不会将当前 Bit 置为 0)
Bit1 TestFailedThisOperationCycle 表示 DTC 在当前的操作循环中,是否报告过 Failed。
在当前操作循环中,只要报告了 Failed,就需要将当前 Bit 置为 1;
当重启操作循环、DEM 模块初始化,或者 ClearDiagnosticInformation 时,需要将当前 Bit 置为 0
Bit2 PendingDTC 表示 DTC 在当前的操作循环,以及上一个操作循环中,是否报告过 Failed。
当报告 Failed 时,需要将当前 Bit 置为 1;
当此时的操作循环结束,并且在这个操作循环中没有报告过 Failed(Bit1 和 Bit6 都为 0)、或者 DEM 首次初始化、或者 ClearDiagnosticInformation 时,需要将当前 Bit 置为 0
Bit3 ConfirmedDTC 表示 DTC 经历了一定次数的操作循环,并且在这些操作循环中都报告过 Failed 时,需要将当前 Bit 置为 1
当 DTC 老化完成,或是 DEM 模块首次初始化,或是当前的数据因为存储的 overflow 而被移除,或是 ClearDiagnosticInformation 时,需要将当前 Bit 置为 0
Bit4 TestnotCompletedSinceLastClear 表示自从上一次 clear 之后,是否有报告过 Passed 或者 Failed。
当报告 Failed 或者 Passed 时,需要将当前 Bit 置为 0;
ClearDiagnosticInformation 或者 DEM 模块初始化时,需要将当前 Bit 置为 1;
需要注意的是,下游 dtc 报告的 preFailed 或者 prePassed 并不算是一次完整的报告
Bit5 TestFailedSinceLastClear 表示自从上一次 clear,当前的 DTC 是否有报告过 Failed。
当报告 Failed 时,需要将当前 Bit 置为 1;
ClearDiagnosticInformation 或者 DEM 模块初始化,或者老化成功,或者因为 overflow 将数据删除了,需要将当前 Bit 置为 0
Bit6 TestNotCompletedThisOperationCycle 表示在当前的操作循环中,是否没报告过 Failed 或者 Passed。
当报告 Failed 或者 Passed 时,需要将当前 Bit 置为 0;
当重启操作循环、DEM 模块初始化,或者 clearDiagnosticInformation 时,需要将当前 Bit 置为 1
Bit7 WarningIndicator 初始值为 0;当配置了 indicator,Bit3 变为 1(此时 Bit0 也一定为 1),并且也符合主机厂或者供应商的需求时,将当前 Bit 置为 1
当 healing 结束,0x14 服务,或者一些主机厂自定义的条件满足时,将当前 Bit 置为 0



Aging 与 Healing




Snapshot




ExtendedData

所有的数据都是 uint8 类型的(除了 FDC10),达到 255 之后都不会继续增加

名称 介绍
OCC1 +1 的条件:报告 failed 之后的每次操作循环重启都 +1
清零的条件:报告 failed 之后;0x14 服务清除 dtc 之后,老化成功之后
实现细节:
每次操作循环重启的时候,如果此时的 bit1 为一并且 occ1 为零,
或者 occ1 不为零并且 bit1 为零,则加一
每次报告 failed 、14 服务清除 dtc 时,或者老化成功清零时,清零
OCC3 +1 的条件:首次报告 failed 之后的每次操作循环重启都 +1
清零的条件:0x14 服务清除 dtc 之后,老化成功之后
实现细节:
每次操作循环重启的时候,如果此时的 bit1 为一,或者 occ3 不为零,则加一
14 服务清除 dtc 时,或者老化成功清零时,清零
OCC4 +1 的条件:当前操作循环首次报告 failed 之后,就 +1
清零的条件:0x14 服务清除 dtc 之后,老化成功之后
实现细节:
每次报告 failed 的时候,记录是否是第一次报告,如果是才 +1d]
14 服务清除 dtc 时,或者老化成功清零时,清零
FDC10 等价于当前 dtc 的 fdc 值
达到 127 的条件:当报告 failed 之后,值变为 127
达到 -128 的条件:当报告 passed 之后,值变为 128
达到 0 的条件:当 14 服务清除 dtc、老化成功、或者操作循环重启时



0x10

在 UDS 的规范中,定义了会话状态的概念。会话状态可以简单的理解为是当前的 ECU 处于某种会话模式下。

会话模式的作用,主要是为了限制服务的使用。比如说在做诊断应用的设计的时候,可以指定某个服务必须要在某些指定的会话状态下执行。

而会话状态如何进行切换呢?0x10 服务便是用来切换会话的。

根据 14229 的规范,0x10 的 request message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x10
#2,#3 会话 id 0x00-0xFF

会话可由用户自行在工具中配置,但规范规定了一些固有的会话类型

会话 id 会话名
0x01 defaultSession
0x02 ProgrammingSession
0x03 extendedDiagnosticSession
0x04 safetySystemDiagnosticSession

关于会话模式,有以下几点是需要注意了解的:

  1. 在一般的情况下, ECU 一上电,都是处于默认会话
  2. 在 ECU 中会维护一个名为 S3 的定时器,假如当前 ECU 的会话状态不是默认会话,那么就会启用该定时器。一旦有新的请求,便会刷新该定时器。如果在定时器到时的时候,依旧没有新的请求,那么 ECU 就会自动将会话切换到默认会话下
  3. 在 UDS 的概念中定义了定时器 p2p2 *。当一条服务从刚开始处理,到 p2 定时器超时,这个期间,如果服务还没有处理完,则需要给外部的诊断仪或者脚本发送 0x78 的报文,告知对方当前的服务超时了,后续还会将响应发来。紧接着就会启动 p2*的定时器,在 p2* 的定时器超时后,又会接着发送 0x78 的报文 (其中 p2 定时器的单位是 1ms,p2* 定时器的单位是 10ms)

根据 14229 的规范,0x10 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x50
#2,#3 会话 id 0x00-0xFF
#4,#5 p2 server 定时器 0x0000-0xFFFF
#6,#7 p2* server 定时器 0x0000-0xFFFF



0x11

该服务从字面意思上理解,就是用来重启 ECU 的。而重启有不同的类型,具体的重启类型可以参见子服务。

规范中并没有定义在发送了 0x11 的 positive response 之后,到真正重启之间,ECU 的行为。但推荐在这个期间 ECU 不要解说任何的 request 或是发送任何的 response。

根据 14229 的规范,0x11 的 request message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x11
#2 子服务 id 0x00-0xFF

而其中具体的子服务,在 14229 的规范中,有定为以下几种:

子服务 id 含义
0x01 HardReset,硬件复位,模拟通常在服务器与其电源断开后执行的通电/启动顺序。简单的理解为就是整个 ECU 重启了。有可能会导致易失性存储和非易失性存储失效
0x02 keyOffOnReset,点火循环复位,模拟关机顺序(即中断开关电源)。有点类似于驾驶员用钥匙给汽车关闭后又重新点火的过程。其中非易失性存储将会被保存,易失性存储会被重置
0x03 softReset,软复位,简单理解就是将应用程序重启
0x04 enableRapidPowerShutDown,适用于非点火供电而仅为电池供电的ECU。因此,关机会迫使睡眠模式关闭,而不是关闭电源。睡眠意味着关闭电源,但仍准备唤醒(电池供电)。子功能的目的是减少在点火开关进入关闭位置后的ECU的备用时间。
0x05 disableRapidPowerShutDown,关闭 0x04 服务

根据 14229 的规范,0x11 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x51
#2 子服务 id 0x00-0x7F
#3 powerDownTime 0x00-0xFF 当子服务为 0x04 的时候才会有该项



0x27

该服务是用来解锁安全等级的。安全等级和会话等级是类似的概念,都是用来限制服务需要在指定的环境下执行。但与会话等级不同的是,会话等级一问一答便可以切换会话,而安全等级则需要先请求安全种子,计算key,比较key,之后再判断是否可以解锁安全等级。

0x27 是带有子服务的 UDS 服务,其中子服务为 0x01-0x41 之间的奇数的,都是 requestSeed 请求种子的服务;子服务为 0x02-0x42 之间的偶数的,都是 sendKey 发送 key 值。

其实,这里的子服务是一一对应的。比如说 子服务id 为 0x01 的 requestSeed 服务,那么就需要对应子服务id 为 0x02 的 sendkey 服务,即 requestSeed 的子服务 id,是其对应的

根据 14229 的规范,0x27 的 request message ,其中子服务为 requestSeed 的报文结构

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x27
#2 子服务 id 0x01,0x03,0x05,0x07-0x7D
#3…#n 具体数据 0x00-0xFF

根据 14229 的规范,0x27 的 request message ,其中子服务为 sendKey 的报文结构

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x27
#2 子服务 id 0x02,0x04,0x06,0x08-0x7E
#3…#n securityKey 0x00-0xFF

根据 14229 的规范,0x27 的子服务 requestSeed 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x67
#2 子服务 id 0x01,0x03,0x05,0x07-0x7D
#3…#n securitySeed 0x00-0xFF

根据 14229 的规范,0x27 的子服务 sendKey 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x67
#2 子服务 id 0x02,0x04,0x06,0x08-0x7E



0x28

0x28 服务是用来打开或者关闭某类报文信息的发送和接收功能。

根据 14229 的规范,0x28 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x28
#2 子服务 id 0x00-0xFF
#3 communicationType,消息类型 0x00-0xFF
#4 nodeIdentificationNumber 0x00-0xFF 否,当 communicationType 是 04 或者 05 的失火,才需要填写该参数
#5 nodeIdentificationNumber 0x00-0xFF 否,当 communicationType 是 04 或者 05 的失火,才需要填写该参数

根据 14229 的规范,目前支持的 subfunction 有

子服务 id 含义
0x00 enableRxAndTx,启用对某种消息的发送和接收
0x01 enableRxAndDisableTx,启用对某种消息的接受,禁用对某种消息的发送
0x02 disableRxAndEnableTx,禁用对某种消息的接收,启用对某种消息的发送
0x03 disableRxAndTx,禁用对某种消息的接收和发送
0x04 enableRxAndDisableTxWithEnhancedAddressInformation,表示寻址总选需要切换到诊断调度模式
0x05 enableRxAndTxWithEnhancedAddressInformation,表示寻址总线需要切换到应用程序调度模式

而对于 communicationType,具体在 14229 中表 B.1 中有详细的赘述,更多细节可以关注 ISO 14229 的规范

根据 14229 的规范,0x28 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x68
#2 子服务 id 0x00-0x7F



0x29

认证主要分为 APCE 和 ACR,a 核上的协议栈一般只支持 APCE。而其中 APCE 又分为单向认证和双向认证

APCE 的全称 Authentication with PKI Certificate Exchange

ACR 的全称 Authentication with Challenge-Response


按照 14229 的规范,支持的子服务如下所示:

子服务名称 作用
0x00 deAuthenticate 主动结束认证状态
0x01 verifyCertificateUnidirectional 单向认证(为 APCE 下的子服务)
0x02 verifyCertificateBidirectional 双向认证(为 APCE 下的子服务)
0x03 proofOfOwnership 所有权证明(为 APCE 下的子服务)
0x04 transmitCertificate 传输证书(为 APCE 下的子服务)
0x05 requestChallengeForAuthentication (为 ACR 下的子服务)
0x06 verifyProofOfOwnershipUnidirectional (为 ACR 下的子服务)
0x07 verifyProofOfOwnershipBidirectional (为 ACR 下的子服务)
0x08 authenticationConfiguration 表示当前协议栈支持的认证,是 APCE 还是 ACR

单向认证:

0x01 服务,传递 client certificate 和 client challenge;server 回复 server challenge 和 server ephemeral public key

再使用 0x03 服务,传递 client proofOfOwnershipClient 和 client ephemeral public key;server 回复 SessionKeyInfo




0x3E

该服务适用于保持外部的 client(上位机或是诊断脚本)与诊断 server 之间的活跃状态。而在实际的作用中,更多的是为了保持当前诊断会话的状态。(因为我们知道 s3 timer 如果在这个时间内都没有新的连接进入,那么就会导致会话切换回默认会话状态)

根据 14229 的规范,0x3E 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x3E
#2 子服务 id 0x00/0x80

注:在子服务 id 中,其中的 Bit7,也就是第八位,当为 0 的时候,表示为需要发送肯定响应,而为1的时候,则需要抑制肯定响应

根据 14229 的规范,目前支持的 subfunction 有

子服务 id 含义
0x00 zeroSubFunction

根据 14229 的规范,0x3E 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x7E
#2 子服务 id 0x00



0x85

该服务用于表示是否开启 DEM 模块的报告。需要注意的是,按照 14229 的规范,如果切换到了默认会话,是需要开启 DEM 模块的报告的

根据 14229 的规范,0x85 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x85
#2 子服务 id 0x01/0x02

根据 14229 的规范,0x85 的 positive response message 格式为:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0xC5
#2 子服务 id 0x01/0x02



0x86

Todo:很少看到有客户使用这个服务,后续需要用到的时候,再进行深入的了解。




0x22

该服务是用来读取一个或者多个 did 对应的数据的。did 的全程是 dataIdentifier,它是由一个 uint16 和一连串二进制数据组成的,可以简单的理解为键值对的关系。此处的 uint16 为 did 号。

而读取 did 的这个服务,可以理解是,外部的诊断仪传入 did 号,诊断 server 便根据报文中的 did 号,返回对应的数据。

根据 14229 的规范,0x22 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x22
#2,#3 did 0x00-0xFF 是(每次 22 服务的请求中,至少要有一个 did)
.. #n-1,#n did 0x00-0xFF

根据 14229 的规范,0x22 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x62
#2,#3 did 0x00-0xFF 是(每次 22 服务的请求中,至少要有一个 did)
#4..#(k-1)+4 Did record,为 did 对应的数据 0x00-0xFF 是(did 对应的数据至少为一个字节)
#n-(0-1)-2,#n-(o-1)-1 did 0x00-0xFF 否(至少有一个 did 可读就可以了)
#n-(o-1)..#n Did record,为did对应的数据 0x00-0xFF 否(至少有一个 did 可读就可以了)



0x2A

该服务允许外部的诊断仪发送周期性读取一个或是多个 did 的请求。

在 14229 的规范中,每次 2A 服务传入的 did 数据只包含低两位。其中的高两位固定为 0xF2。

根据 14229 的规范,0x2A 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x2A
#2 transmissionMode,表示传输的速率 0x00-0xFF
#3 periodicDataIdentifier 0x00-0xFF 否(可以传入任意数量的 did;如果 transmissionMode 为 stopSending,且后续没有 did 存在时,则表示 client 需要将所有的定时读取的 did 都给取消)

根据 14229 的规范,0x2A 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x6A

而周期性返回数据的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 periodicDataIdentifier 0x00-0xFF
#2..#k+2 Did record,为 did 对应的数据 0x00-0xFF 是(did 对应的数据至少为一个字节)



0x2C

对于 did 而言,在工具界面配置了当前支持哪些 did,但是存在一种名为 dynamic define by identifier 的 did。这种 did 在工具界面配置,说当前支持这种类型的 did,但是它具体的组成需要由 0x2c 服务来定义。

比如说,已有 did1,did2,did3。其中 did3 是动态 did,那么通过 2c 服务指定,did3 是由 did1 的前四位,加上 did2 的中间四位组成的。

注:在 autosar ap 的规范中,仅支持子服务 id 为 0x01 和 0x03 这两个子服务

根据 14229 的规范,0x2C 的 request message ,子服务为 0x01 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x2C
#2 SubFunction 0x01(defineByIdentifier)
#3,#4 dynamicallyDefinedDataIdentifier 0xF2/0xF3,0x00-0xFF
#5,#6 sourceDataIdentifier,表示源 did 0x00-0xFF 是(至少要由一个 did 组成)
#7 positionInSourceDataRecord,表示在源头 did 上的偏移量 0x01-0xFF 是(至少要由一个 did 组成)
#8 memorySize 0x01-0xFF 是(至少要由一个 did 组成)
#n-3,#n-2 sourceDataIdentifier,表示源 did 0x00-0xFF
#n-1 positionInSourceDataRecord,表示在源头 did 上的偏移量 0x01-0xFF
#n memorySize 0x01-0xFF

根据 14229 的规范,0x2C 的 request message ,子服务为 0x03 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x2C
#2 SubFunction 0x03(clearDynamicallyDefinedDataIdentifier)
#3,#4 dynamicallyDefinedDataIdentifier 0xF2/0xF3,0x00-0xFF 否(如果没有该项,则表示需要清除所有的 ddid;否则则表示删除某个具体的 ddid)

根据 14229 的规范,0x2C 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x6C
#2 subfunction 0x00-0x7F
#3,#4 dynamicallyDefinedDataIdentifier 0xF2/0xF3,0x00-0xFF 否(如果 request 中有 ddid,那么就需要填写此参数,否则则不需要)



0x2E

该服务是用来写 did 对应的数据的。而对于动态定义的 did 来说,是不能够写入的。

根据 14229 的规范,0x2E 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x2E
#2,#3 dataIdentifier 0x00-0xFF
#4..#m+3 dataRecord 0x00-0xFF 是,最少应为一个字节

根据 14229 的规范,0x2E 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x6E
#2,#3 dataIdentifier 0x00-0xFF



0x14

clearDiagnosticInformation,该服务是用于删除一个或者多个 DTC 对应的数据。当完全删除 DTC 对应的数据,或者不存在对应 DTC 时,需要返回积极响应,如果在 server 中存在多份 DTC 的数据(比如说可能存在备份的情况),那么同样也要将其删除。

根据 14229 的规范,0x14 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x14
#2,#3,#4 groupOfDTC 0x00-0xFF
#5 Memory selection 0x00-0xFF 否(为用户自定义的内存序)

根据 14229 的规范,0x14 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x54



0x19

readDTCInformation,该服务是用于读取处于某个状态的所有 DTC 对应的数据。

根据 14229 的规范以及 autosar ap 的规范,目前支持的 subfunction 有

子服务 id 含义
0x01 reportNumberOfDTCByStatusMask,需要传入 statusMask(一个字节),返回处于当前状态的 DTC 的数量
0x02 reportDTCByStatusMask,需要传入 statusMask(一个字节),返回处于当前状态的 DTC 的列表
0x03 reportDTCSnapshotIdentification,不需要传入数据,返回所有 DTC 的所有快照号(即冻结帧的 recordnumber)(具体的格式应该是 dtc 号,freeze.recordNumber + dtc )
0x04 reportDTCSnapshotRecordByDTCNumber,需要传入 DTC 码以及其对应的快照信息的 recordNumber,然后去读对应快照信息的数据(如果此处的 recordNumber 是 FF,就会读取所有的数据)
0x06 reportDTCExtDataRecordByDTCNumber,需要传入 DTC 码以及其对应的拓展数据的 recordNumber,然后返回数据(如果此处的 recordNumber 是 FE 或者 FF,就会读取所有的数据)
0x07 reportNumberOfDTCByServerityMaskRecord,需要传入状态码和严重程度,然后返回对应 DTC 的数量
0x0A reportSupportedDTC,不需要传入数据,返回当前支持的所有的 DTC 及其状态
0x14 reportDTCFaultDetectionCounter,不需要传入数据,返回当前所有处于 preFailed 的 DTC
0x17 reportUserDefMemoryByStatusMask
0x18 reportUserDefMemoryDTCSnapshotRecordByDTCNumber
0x19 reportUserDefMemoryDTCExtDataRecordByDTCNumber



0x31

该服务的全称为 routineControl。在介绍这个服务之前需要介绍 routineIdentifier,为一个 uint16 的值,表示某一个 routine。

而服务 routineControl 表示的是外部的诊断仪或是脚本,想让诊断 server(或是 ECU)执行一段此前已经定义好了的代码逻辑,比如常见的擦除内存,重置或是修改某个参数等。

如果从常见的网络模型上看,可以简单的立即为 routine 就是某个函数,当传入 0x31 0x01 的时候,就是让程序执行某段代码;当传入 0x31 0x02 的时候,就是让程序停止执行某段代码;当传入 0x31 0x03 的时候,就是获取这段代码执行结果的返回值。

根据 14229 的规范,0x31 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x31
#2 subFuntcion 0x00-0xFF
#3,#4 routineIdentifier 0x00-0xFF
#5..#n routineControlOptionRecord 0x00-0xFF 否(该部分的内容由用户自行定义)

根据 14229 的规范,目前支持的 subfunction 有

子服务 id 含义
0x01 startRoutine,该服务是用于启动某个 routine
0x02 stopRoutine,该服务是用于停止某个 routine
0x03 requestRoutineResults,该服务是用于获取某个 routine 运行得到的结果

根据 14229 的规范,0x31 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x71
#2 routineControlType,为对应的子服务 0x00-0x7F
#3,#4 routineIdentifier 0x00-0xFF
#5 routineInfo 0x00-0xFF 否(该参数由不同的协议及车厂共同实现)
#6…#n routineStatusRecord 0x00-0xFF



0x34

服务名为 requestDownload。此处需要注意的是,UDS 提供了服务用于数据的传输,而在具体数据的传输上,是需要先告知当前的数据流走向的。

requestDownload 表示数据是从 client 传输到 server 上,即上位机传输给 ECU。

根据 14229 的规范,0x34 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x34
#2 dataFormatIdentifier 0x00-0xFF
#3 addressAndLengthFormatIdentifier 0x00-0xFF
#4..#(m-1)+4 memoryAddress 0x00-0xFF 是(最少需要有一个字节)
#n-(k-1)..#n memorySize 0x00-0xFF 是(最少需要有一个字节)

dataFormatIdentifier 需要分为两部分理解:

Bit7-4 表示数据的压缩方法;Bit3-0 表示数据的加密方法。

如果为 0x00,则表示传输的数据既不需要加密,也不需要压缩。具体的压缩和加密方法,由主机厂自行定义。


adderssAndLengthFormatIdentifier 也需要分两部分来理解:

Bit7-4 表示的是 memorySize 所需的字节数;Bit3-0 表示的是 memoryAddress 所需的字节数。


memoryAddress 表示的是当前的数据具体要写在哪一个内存地址开始的位置。


memorySize 表示传输数据块的大小。

ECU 需要使用该参数进行判断,最后返回给用户每次可以传输数据的最大大小,如果用户使用了数据压缩,那么此处的大小是压缩前还是压缩后的,需要厂商自行决定。


根据 14229 的规范,0x34 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x74
#2 lengthFormatIdentifier 0x00-0xF0
#3,#n maxNumberOfBlockLength 0x00-0xFF

lengthFormatIdentifier 需要分为两部分理解:

Bit7-4 表示后续 maxNumberOfBlockLength 的长度;Bit3-0 为 0,具体的内容为 ISO 保留。


maxNumberOfBlockLength 表示后续的 0x36(transferData)需要传输数据内容的大小最大为多少。




0x35

服务名为 requestUpload。此处需要注意的是,UDS 提供了服务用于数据的传输,而在具体数据的传输上,是需要先告知当前的数据流走向的。

requestUpload 表示数据是从 server 传输到 client 上,即从 ECU 传输给上位机。

根据 14229 的规范,0x35 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x35
#2 dataFormatIdentifier 0x00-0xFF
#3 addressAndLengthFormatIdentifier 0x00-0xFF
#4..#(m-1)+4 memoryAddress 0x00-0xFF 是(最少需要有一个字节)
#n-(k-1)..#n memorySize 0x00-0xFF 是(最少需要有一个字节)

其中关于 dataFormatIdentifieraddressAndLengthFormatIdentifiermemoryAddressmemorySize 的描述,可以完全参见0x34中的描述。


根据 14229 的规范,0x35 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x75
#2 lengthFormatIdentifier 0x00-0xF0
#3,#n maxNumberOfBlockLength 0x00-0xFF

lengthFormatIdentifier 需要分为两部分理解:

Bit7-4 表示后续 maxNumberOfBlockLength 的长度;Bit3-0 为 0,具体的内容为 ISO 保留

而 maxNumberOfBlockLength 则表示后续的 0x36(transferData)需要传输数据内容的大小最大为多少。




0x36

在介绍完了 0x34 和 0x35 这两个服务之后,可以发现这两个服务都是用来表示后续具体传输数据流的走向,而具体数据的传输,就是用服务 0x36 进行传输的

根据 14229 的规范,0x36 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x36
#2 blockSequenceCounter 0x00-0xFF
#3..#n transferRequestParameterRecord 0x00-0xFF 否(如果此时是 0x34 对应的数据传输,就必须要有该参数)

blockSequenceCounter 是从 01 开始计数的,是用来计算当前已经传输数据的大小的。该值是为了保证数据的顺序及完整性传输。

如果循环至 0xFF,则会回到 0x00。


根据 14229 的规范,0x36 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x76
#2 blockSequenceCounter 0x00-0xFF
#3,#n transferResponseParameterRecord 0x00-0xFF 否(如果此时是 0x35 对应的数据传输,就必须要有该参数)



0x37

requestTransferExit 是用于表示当前数据传输的终止的。

根据 14229 的规范,0x37 的 request message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x37
#2..#n transferRequestParameterRecord 0x00-0xFF 否(为用户自定义数据)

根据 14229 的规范,0x37 的 response message 的报文结构如下所示。

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x77
#2..#n transferResponseParameterRecord 0x00-0xFF 否(为用户自定义数据)



0x38

RequestFileTransfer,该服务是用来传输文件或者文件夹。

根据 14229 的规范,0x38 的 request message 的报文结构如下所示:

数值位 参数名字 可选值 是否为必选项
#1 服务 id 0x38
#2 modeOfOperation 0x01-0x06 是(表示当前对文件处理的操作)
#3,#4 filePathAndNameLength 0x00-0xFF
#5…#5+n-1 filePathAndName 0x00-0xFF 是(文件路径和名字至少为一个字节)
#5+n dataFormatIdentifier 0x00-0xFF 否(与具体的 modeOfOperation 有关)
#5+n+1 fileSizeParameterLength 0x00-0xFF 否(与具体的 modeOfOperation 有关)
#5+n+2..#5+n+2+k-1 fileSizeUnCompressed 0x00-0xFF 否(与具体的 modeOfOperation 有关)
#5+n+2+k..#5+n+1+2k fileSizeCompressed 0x00-0xFF 否(与具体的 modeOfOperation 有关)


根据 14229 的规范,0x38 的 request message 的报文结构如下所示:

数值位 参数名字 可选值 是否为必选项
#1 服务 id + positive 偏移量 0x78
#2 modeOfOperation 0x01-0x06 是(表示当前对文件处理的操作)
#3 lengthFormatIdentifier 0x00-0xFF
#4…#4+m-1 maxNumberOfBlockLength 0x00-0xFF
#4+m dataFormatIdentifier 0x00-0xFF
#4+m+1..#4+m+2 fileSizeOrDirInfoParameterlength 0x00-0xFF
#4+m+3..#4+m+3+k-1 fileSizeUncompressedOrDirInfoLength 0x00-0xFF
#4+m+3+k..#4+m+3+2k-1 fileSizeCompressed 0x00-0xFF

filePathAndNameLength 表示的是后续文件路径及名字的长度


filePathAndName 表示后续的文件路径和名字(如果当前的 modeOfOperation 是 0x05 readDir,那么此处就应该是文件夹)


dataFormatIdentifier 的具体功能,需参考此前的赘述(如果当前的 modeOfOperation 是 0x02 或者 0x05,那么则不应该有该参数)


fileSizeParameterLength(或者 fileSizeOrDirInfoParameterlength) 记录了后续 fileSizeUncompressedfileSizeCompressed 的大小也一样) 的大小(如果当前的 modeOfOperation 是 0x02,0x04,0x05,则不应该有该参数)


fileSizeUncompressed 表示当前文件未压缩的长度(如果当前的 modeOfOperation 是 0x02,0x04,0x05,则不应该有该参数)


fileSizeCompressed 表示当前文件被压缩的长度(如果当前的 modeOfOperation 是 0x02,0x04,0x05,则不应该有该参数),如果传输的文件未被压缩,那么值应该和 fileSizeUncompressed 相等


 上一篇
开发工具使用之 Gdb 开发工具使用之 Gdb
多线程调试# 查看所有线程的堆栈 thread apply all bt # 切换到指定线程的堆栈 t 线程号 # 进入正在运行的程序查看堆栈(一般用于排查死锁或者进程卡死的问题) gdb attach 进程号 # 查看当前所有线程的
2025-02-12
下一篇 
开发工具使用之 Catch2 开发工具使用之 Catch2
介绍目前使用的测试框架,好处就是只有头文件,方便无论是新人还是老人进行开发(gtest 需要编译成 静态库,使用上有点难度) CHECK 和 REQUIRECHECK 和 REQUIRE 用于检测当前括号中的表达式是否为真,常用于校验函数的
2024-05-04
  目录