UDS 协议详解

基本概念

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

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

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

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

子服务

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

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

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


积极响应与消极响应


常见的定时器


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(TODO)




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 需要分为两部分理解:

它的高 4 位字节表示数据的压缩方法,低 4 位字节表示数据的加密方法。

如果为 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
常用的 gdb 指令bt # 查看的堆栈 f 1/2/3/4 # 查看具体第几个帧栈 p 变量名字 # 查看具体某个变量 print/x 变量名字 # 打印变量的数据,以十六进制的形式打印(默认的是 8 进制) thread app
2025-02-12
下一篇 
开发工具使用之 Catch2 开发工具使用之 Catch2
介绍目前使用的测试框架,好处就是只有头文件,方便无论是新人还是老人进行开发(gtest 需要编译成 静态库,使用上有点难度) CHECK 和 REQUIRECHECK 和 REQUIRE 用于检测当前括号中的表达式是否为真,常用于校验函数的
2024-05-04
  目录