UDS服务总结

手册导读 2 UDS协议 2 UDS介绍 2 一、常见的诊断协议OBD&UDS 2 1.1两种常见的诊断协议:OBD & UDS 2 二、相关术语介绍 3 2.1 Service ID 3 2.2 诊断请求(Diagnostic Request) 4 2.3 正响应/负响应(Positive/Negative Response) 5 2.3.1 正响应报文格式 6 2.3.1 负响应报文格式 7 3.1 SID大类 10 三、服务的详细介绍 10 3.1诊断和通信管理类 10 3.1.1 0x10 诊断会话控制 10 3.1.2 0x11 ECU复位服务 14 3.1.3 0x27 安全访问服务 17 3.1.4 0x28 通信控制服务 22 3.1.5 0x3E 待机握手服务 26 3.1.6 0x85 控制DTC的设置 27 3.2数据传输类 30 3.2.1 0x22 通过ID读数据 读DID 30 3.2.2 0x2E 通过ID写数据 写DID 36 3.3存储数据类 38 3.3.1 什么是DTC 39 3.3.2 0x14 清除诊断信息 47 3.3.3 0x19 读取DTC数据 51 3.4IO控制类 63 3.4.1 0x2F 通过ID控制输入输出 63 3.5例程控制类 70 3.5.1 0x31 例行程序控制 71 3.6上传下载类 76 3.6.1 0x34 请求下载 76 3.6.2 0x36 数据传输 80 3.6.3 0x37 请求退出传输 83 ISO-TP协议 87 UDS网络层/TP层(ISO 15765-2)的解读 87 专业术语 88 ISO-TP传输协议格式详解 89 特殊帧定义 89 通信实例 90 手册导读 一、手册导读 针对UDS服务的学习, 原文链接:《UDS协议从入门到精通(UDS速查手册)》(完结撒花版)_obdonuds-CSDN博客 UDS协议 UDS介绍 UDS是一种应用层协议,由多种服务类型组成,基础的状态机为会话状态机 一、常见的诊断协议OBD&UDS 1.1两种常见的诊断协议:OBD & UDS OBD和UDS是两种常见的诊断协议,它们在目标和应用领域上存在一些区别。OBD协议主要用于监测车辆的排放情况,通过读取车辆的故障码来判断是否符合排放标准。而UDS协议则更加全面和灵活,在各个ECU上是一种通用型的协议。 OBD(On-Board Diagnostic):   主要用于跟汽车排放系统相关的ECU(电子控制单元,汽车上的板级控制器)的诊断。OBD协议分为两种:OBD-I和OBD-II。OBD-I是由美国为当时制造的加州汽车所制定的排放法规,随后这套法规被逐渐标准化,于是又提出了OBDII标准,包括:标准化的车载ECU数据诊断接口(SAE-J1962,也就是现在常说的OBD接口)、标准化的诊断解码工具(SAE-J1978)、标准化的诊断协议(ISO 9141-2、ISO 14230-4、ISO 15765-4)、标准化的故障码定义(SAE-J2012、ISO 15031-6)、标准化的维修服务指南(SAE-J2000),OBD-II在1996年开始实施,目前已经成为全球汽车行业的标准。因此,OBD标准可以看作一系列标准的集合,是具有强制标准需要参照的,是由法规要求的,其最初目的是环保,用于汽车排放系统相关的ECU上。 UDS(Unified diagnostic services):   UDS(Unified Diagnostic Services)是一种通用的汽车诊断协议,由欧洲汽车制造商协会(ACEA)和日本汽车制造商协会(JAMA)共同制定。它与OBD最大的区别就在于“Unified“上,是面向整车所有ECU的。单就UDS而言,它只是一个应用层协议(ISO 14229-1),不关心应用层以下的实现,比如执行该协议的应用层程序不关心通过何种物理传输方式实现与ECU硬件的通信,因此它既可以基于CAN线通信去实现,也能在Ethernet上实现。并且,UDS提供的是一个诊断服务的基本框架,定义了一系列的诊断服务和通用化的诊断流程,主机厂和零部件供应商可以根据实际情况选择实现其中的一部分或是自定义出一些私有化的诊断服务来,所以基于UDS协议的诊断又常常被称为Enhanced diagnosic(增强型诊断)。可见,UDS不是法规要求的,没有统一实现标准,可以基于该协议提供的诊断请求及响应格式进行二次开发。    简言之,UDS服务主要用于诊断设备Tester(Client)和ECU(Server)之间的诊断通信,诊断设备(Tester)发送诊断请求(request),ECU给出诊断响应(response),通过这种“一问一答”的形式让目标ECU执行一些期望的操作,而UDS就是为不同类型诊断功能的request和response定义了统一的内容和格式。 二、相关术语介绍 2.1 Service ID(SID)   在UDS协议中,Service ID(SID)是指服务标识符,用于标识要执行的服务。每个服务都有一个唯一的SID,在诊断会话中通过SID来区分要执行/响应哪种服务请求。14229-1中定义了26种服务并将这些服务分为6大类:诊断和通信管理类、数据传输类、存储数据传输类、输入输出控制类、例程功能类、上传下载类 2.1 Service ID 服务,是对话方式的多种组合,主要分为诊断类,数据传输类,存储数据类,IO控制,上传和下载(Boot) Tip📌:表格中标黄部分为常用的服务,其他的不常用。 2.2 诊断请求(Diagnostic Request) 诊断请求是指诊断工具向车辆发送的请求消息,用于请求执行某个服务。诊断请求消息由三个部分组成:SID、子功能和实际数据。其中,SID用于标识要执行的服务,至于子功能:指的是这个服务还能更进一步的划分或者具有启动/暂停之类的子功能。   尽管服务类型不尽相同,但UDS针对这些服务定义了统一的诊断请求包的格式,每个诊断请求由1个Byte的SID + 1个Byte的 sub-function(实际上是1bit spr + 7bit sub-function,具体解释看下文)+ 不定长的实际数据构成,其格式如下所示: Req协议格式 Tip📌:spr存在的目的是告诉ECU针对某个服务请求是否需要发送正响应数据,用于减少ECU发送不必要的响应,节约系统资源: spr=1, 抑制正响应,即ECU不给出正响应;(REQ中不要求回应,RSP不要回应) spr=0, 需要ECU给出正响应,如果某个服务没有sub-function,即没有第二个字节,那默认是要发正响应的(REQ中要求回应,RSP要回应) 2.3 正响应/负响应(Positive/Negative Response)   诊断工具向车辆发送服务请求后,如果服务执行成功,则返回的响应消息称为正响应,反之返回的响应消息称为负响应。 2.3.1 正响应报文格式 RSP回复格式 SID 诊断会话控制服务 字节1 SID(服务请求) + 0x40 = 0x10 + 0x40 = 0x50 字节2 子服务(只存在响应有子服务的SID) SID 读DID(Data数据)0x22 字节1 SID(服务请求) + 0x40 = 0x22 + 0x40 = 0x62 字节2 DID 高字节 字节3 DID 低字节 字节4 DID 的值 01 2.3.1 负响应报文格式 负响应消息由两部分组成:SID和负响应码(NRC)。SID用于标识响应的服务,负响应码指示服务执行失败的原因。   负响应报文的字节组成格式如下所示: SID 诊断 0x05子服务 字节1 7F 错误响应 字节2 回复SID服务 字节3 错误码 0x12 没有子服务错误 2.3.1.1负响应错误代码列表 3.1 SID大类 三、服务的详细介绍 3.1诊断和通信管理类 诊断和通信管理类是UDS服务的核心部分,它提供了与ECU进行通信以及执行诊断操作的基本功能。这些功能包括诊断会话的建立和终止、ECU的重置和诊断通信的管理。通过诊断和通信管理类,技术人员可以与ECU进行交互,获取ECU的状态信息,并执行各种诊断操作。主要包括如下服务: 3.1.1 0x10 诊断会话控制 《UDS协议从入门到精通》系列——图解0x10:诊断会话控制_uds 0x10 p2-CSDN博客 3.1.1.1诊断会话控制介绍 会话模式是诊断领域非常重要的一个状态机,不同的会话模式是用来区分诊断服务执行权限的,而该服务正是为了实现会话模式的切换。即该服务可以通过控制ECU在不同的会话模式之间切换从而为ECU使能一组特定的服务以及功能,至于每种会话模式下使能哪些服务/功能,由遵循该协议标准的用户去决定。   UDS协议定义了三种会话模式:默认会话、编程会话、扩展会话。不同会话模式间可以互相切换,但在一个ECU中应该始终只有一个诊断会话处于活动状态。 ECU在上电时应始终启动默认会话。如果没有启动其他会话则默认会话将在ECU通电期间一直运行。举例来说: ECU通常处于默认会话状态(Default Session),但很多服务需要切换到扩展会话模式中才能执行(Extended Session),当需要进行软件刷写时,则需要切换到编程会话模式(Programming Session)。 此外,当ECU处于非默认会话时,如果一段时间没有诊断操作,将会回退到默认会话,这时候如果想要保持在某种会话状态,可以通过0x3E会话保持服务实现。 3.1.1.2会话模式切换时,ECU要做什么? 会话模式类似于CanOpen中的NMT节点状态,初始化状态和工作状态支持的pdo和sdo索引是不一样的,但是在UDS中每个会话模式支持的服务是可以前期定义的 3.1.1.3协议数据格式 Tips:黄色部分常用的是子服务中对会话模式的切换 REQ请求格式 SID + SF (子服务类型) RSP回复格式 分为正响应和负响应 通信实例 3.1.2 0x11 ECU复位服务 该服务请求ECU根据请求消息中的ResetType参数的值执行不同类型的ECU重置。重置成功后(ECU正响应该服务请求),进入Default Session(默认会话模式)。    2020版的ISO14229-1标准中指出,当Client向Server发送0x11服务请求时,Server可在复位行为完成之后或者开始复位行为之前给到Client诊断响应,但14229-1强烈推荐的一种做法是:“当Server接收到来自Client的0x11服务请求时,Server应当先给出诊断响应然后开始重启行为“。   (原因举例:一方面,几乎所有ECU软件设计中一旦走复位重启流程,已经不记得之前发生过什么,不知道收到什么请求,又要给谁发响应;另一方面,如果请求11诊断服务时未抑制正响应,在复位完成之前,一般都会先回复NRC 0x78让Client进行等待,那么Client需要根据不同的ECU节点的回复做超时监控,这无疑增加了Client的负担,对于Client而言,最为简单的方法就是发送完请求,各ECU节点回复正响应,然后各自完成复位操作即可。)    此外,建议在复位操作执行期间,ECU不要接受任何请求消息以及不要发送任何响应消息,避免发生意料之外的问题。 3.1.2.1 ECU复位应用场景 一般而言,对于11诊断服务,主要应用场合如下:  ECU被刷写新的软件后,此时需要通过11服务重启该ECU使其恢复到初始状态;(固件刷写)  在产线下线标定的过程中,对于KL30供电的ECU存在一些仅在下电时存储的数据,此时需要通过11诊断服务使ECU走下电流程进而完成相应数据的保存;(掉电进行数据写入)  为满足特定功能的需要,输入相关标定参数给到ECU后,只有通过发送服务11才能使得标定参数生效的场景;(标定参数写入)  对于KL30供电的ECU节点,可以使用诊断服务11使ECU快速进入休眠的场景。(某些节点的休眠) 3.1.2.2协议数据格式 REQ请求格式 Tips:一般固件刷写完成后会使用子功能的01,进行硬复位 RSP回复格式 通信实例 3.1.3 0x27 安全访问服务 3.1.3.1什么是安全访问服务 车载ECU中的一些数据或者操作是比较重要的,对于这种企业敏感的数据或者操作肯定不是人人都能访问的,诊断服务0x27应运而生。它主要用于车载ECU数据上传或者下载,传递重要信息以及敏感操作等过程中。即对请求执行操作的人进行鉴权,只有正确解锁对应的安全等级,才能访问该安全等级的数据,否则无法访问。 3.1.3.2应用场景有哪些 通常在向Flash中写数据时,都需要先执行0x27安全解锁之后才能进行安全写入,最常见的就是对ECU进行软件刷写时,需要先通过0x27安全解锁才能进行后续重编程操作,否则将对ECU造成极大的安全风险; 使用0x31服务执行十分重要的routine时,需要优先执行0x27进行安全解锁之后才能够执行对应的routine; 在产线写入较为重要的版本或者标定等信息过程中,需要先使用0x27服务才能使用写操作的诊断指令,如0x2E服务; 3.1.3.3实现安全访问的基本原理 第一回合: Tester向目标ECU请求种子(“种子“:简单理解它就是个随机数) 目标ECU向Tester发送种子 第二回合: Tester基于接收到来自目标ECU的种子计算出对应的key并发送给目标ECU 目标ECU接收来自Tester算出来的key并与内部算出的key比较,如果一致则解锁成功,否则解锁不成功   请求+响应为一组,共两个来回,用图示方式看起来更直观一些: 3.1.3.4 数据协议格式 REQ格式 由于安全访问服务一般由 请求种子和根据种子计算密钥两部分组成,所以是两个请求格式 Tips📌:两个请求中sub-function: securityAccessType的含义 “请求种子“数据包中,该字段必须为奇数;“发送key“数据包中该字段必须为偶数,不同的数字代表不同的安全等级 每一次完整的0x27服务流程中,“请求种子“和“发送key“两个数据包中该字段数值必须存在一个定量关系,即: 请求的子功能和回复密钥的子功能是 +1的关系 “请求种子“ 的securityAccessType + 1 == “发送key“ 的securityAccessType 例如: “请求种子“ 的securityAccessType= 0x01 ——> “发送key“ 的securityAccessType= 0x02 Tips📌:两次请求携带的数据含义 securityAccessDataRecord: 传输到目标ECU端的标识性信息,一般不使用 securityKey: Tester通过安全算法根据随机数种子计算出来的密钥值,发送给目标ECU RSP格式 Tips📌:  ECU上电后,保持上锁状态,一般进入扩展会话才能请求0x27服务,而编程会话的安全等级与扩展会话的安全的等级不一致。所以如果想进行ECU软件刷写操作flash,那进入编程会话后一般还需要再请求0x27服务进入另一个安全等级。  若已成功解锁安全等级,再请求相同层级的解锁服务,ECU一般会回复的种子(随机数)为0。而未解锁的安全等级下,27服务中目标ECU发送来的随机数种子是不允许为0的。因此,可以通过判断种子的值得知当前安全等级是否处于解锁状态。  同一时刻,只允许有一个安全等级处于解锁状态。  安全等级的值没有特别的含义,不存在高低之分,比如解锁level3并不需要先处于level2。 通信实例 3.1.4 0x28 通信控制服务 Tips:总结主要用于关闭或开启某个节点的发送或者接收功能 首先了解如下信息:整车网络中各个ECU之间存在大量的通信报文,这些报文从功能上可以划分为不同的类型,总的来说可以分为应用报文和网络管理报文,通常情况下,各类报文充斥在整个通信网络中。   0x28就是一个通信控制的服务,你可以用它决定让什么类型的报文进行通信或者不让其进行通信。举个常见的例子:用UDS进行软件升级刷写时需要传输大量的软件镜像数据,这时需要将can总线资源让出来,降低CAN总线的负载率和MCU的负载,减少CAN总线的通信报文数量,提高传输效率。就可以通过0x28服务功能寻址关闭某类通讯发送报文到can总线上,待下载升级或传输数据完成后再通过0x28服务将通讯开启即可。   当然,有时候为了排查问题或者满足特殊的测试场景,也需要使能或者失能某类报文的首发,这时候也需要使用0x28服务。总之,0x28就是一个通信控制的服务,根据需求可以通过该服务开关ECU对特定类型报文的传送和接收。 3.1.4.1 简介 首先了解如下信息:整车网络中各个ECU之间存在大量的通信报文,这些报文从功能上可以划分为不同的类型,总的来说可以分为应用报文和网络管理报文,通常情况下,各类报文充斥在整个通信网络中。   0x28就是一个通信控制的服务,你可以用它决定让什么类型的报文进行通信或者不让其进行通信。 举个常见的例子:用UDS进行软件升级刷写时需要传输大量的软件镜像数据,这时需要将can总线资源让出来,降低CAN总线的负载率和MCU的负载,减少CAN总线的通信报文数量,提高传输效率。就可以通过0x28服务功能寻址关闭某类通讯发送报文到can总线上,待下载升级或传输数据完成后再通过0x28服务将通讯开启即可。   当然,有时候为了排查问题或者满足特殊的测试场景,也需要使能或者失能某类报文的首发,这时候也需要使用0x28服务。总之,0x28就是一个通信控制的服务,根据需求可以通过该服务开关ECU对特定类型报文的传送和接收。 3.1.4.2 数据格式 REQ格式 RSP格式 通信实例 Tip📌:除正常的响应规则外,当目标ECU已经处在被请求的状态,如已经停止了网络管理报文发送,此时又被请求停止网络管理报文发送,服务端应当也给予肯定响应。 3.1.5 0x3E 待机握手服务 Tips: 用于诊断仪维持服务端的会话模式,防止超时切换会话模式 3.1.5.1简介 该服务可以说是众多服务中最简单的一个了,目的是告诉服务端(目标ECU):“客户端(诊断设备)目前还处于连接状态,请不要切换会话状态”。大多情况下用于保持当前的非默认会话,通过周期地发送请求帧来阻止自动跳转回默认会话模式。   一般在实际应用中,比如在通过0x2E服务写DID时,可能会要求进入用户自定义的session,还有可能会通过0x27服务进入一定的安全等级,为了使这些服务在写DID的时候是处于激活状态,就可以使用该服务。 3.1.5.2数据格式 通信实例 Tips:一般情况下,请求时会在子服务中触发抑制响应,减少总线带宽占用,实例中没有抑制响应 3.1.6 0x85 控制DTC的设置 3.1.6.1 简介 首先需要了解DTC是什么,DTC是对故障的具体描述,一般会存储在每个模块中; 关于DTC(diagnostic trouble code,诊断故障码)的具体含义可以先浏览0x19服务。在正常情况下,服务端(目标ECU)的故障检测功能模块会根据故障检测结果实时更新每个DTC的状态。而该服务就是让目标ECU停止或者恢复DTC状态位的更新。 常见应用场景: 总结:典型案例在刷写固件过程中一般会关闭总线设备的数据流,如果不进行DTC关闭设置,会存储很多误触发通信超时的DTC进行存储 这个服务通常和0x28服务(通信控制)一起使用,比如在开始写参数之前,为了获得更快的传输速度我们使用0x28服务把所有ECU的通信给关闭了,但此时很多ECU由于收不到相关报文,会没必要地存储很多DTC,这时如果我们使用0x85服务把ECU存储DTC的功能暂时性地禁用掉,则不会产生这种麻烦。   最常见的应用场景就是在用UDS进行ECU软件刷写时,由于刷写通常是针对某一个ECU单独进行的,此时其他ECU正常工作,因此应当通过功能寻址发送给其他各个ECU请求他们停止更新/记录DTC状态,待刷写完成后再启用状态更新即可。 注意事项: ① 当目标ECU接收到0x85请求后,如果控制信息是请求关闭DTC状态更新,则目标ECU应该立即停止DTC的状态更新。即从此刻起,DTC的状态信息保持不变,无论是发生了新的故障,还是已有的故障有了新的状态,目标ECU中的DTC数量、状态信息都不会更新。如果控制信息是启用更新,那么如果先前是关闭状态,就立即恢复到正常的状态,如果先前就是启用更新的状态,则保持状态不变。 ② 无论是启用还是禁用状态更新,目标ECU在正确处理请求之后都要给出肯定响应,如果无法正确处理,需要给出否定响应并明确响应失败的NRC。 >>>>>>>>>>>>>>> 一些使用提示 <<<<<<<<<<<<<<<: 该服务需在非默认会话状态下才受支持,当ECU重回到默认回话模式时,该服务的功能就会恢复到默认状态,即恢复启用DTC更新状态。 虽然该服务控制DTC状态更新的使能/失能,但并不影响通过0x14服务(ClearDTCInformation)请求清除故障信息。 如果某event没有对应DTC(没有mapping DTC),那0x85请求不会对这个event做任何处理,因为该服务基本对象是DTC 。 如果某event触发安全行为,这时执行0x85请求以及0x14请求清除了DTC,那这个安全行为可能就失效了,这种情况下建议触发的安全行为不应该被同步抑制。 3.1.6.2 数据协议格式 3.2数据传输类 数据传输类是用于在ECU和诊断工具之间传输数据的UDS服务类别。它提供了可靠的数据传输机制,确保数据的完整性和准确性。数据传输类包括数据的读取和写入功能,允许技术人员读取和修改ECU中的数据。此外,数据传输类还支持数据的块传输,以提高数据传输的效率。主要包括如下服务: 3.2.1 0x22 通过ID读数据 读DID 3.2.1.1 简介 DID是什么: Data Identifier简称DID,顾名思义其实就是数据标识符,用来标识数据的一个代号。这个数据通常是某一存储在ECU非易失性存储器(Non-Volatile Memory,NVM)里、表示汽车或者一些软件信息的ID,最为大家熟知的比如 汽车的VIN码 ,还有软件版本、发布时间等等。   至于具体有哪些DID,存储的相应数据又是什么,一般由车辆制造商或系统供应商决定。因此,数据的格式和定义应符合车辆制造商或系统供应商的特定要求,可能包括模拟输入和输出信号、数字输入和输出信号、内部数据以及系统状态信息。 3.2.1.2 服务的作用和注意事项 该服务的作用就是通过DID读取ECU中的相关信息,允许客户端通过一个或多个DID从目标ECU中请求对应数据。   至于读取的方式,既可以是上面提到的从NVM中读取这种静态的数据记录:  也可以是实时读取车辆的一些动态数据,Tester发送Service 22 + DID,ECU芯片获取该DID对应的数据信息内容,该内容由传感器采样处理获得(比如温度传感器): >>>>>>>>>>>>>>> 一些使用提示 <<<<<<<<<<<<<<<:  ECU可以根据车辆制造商和系统供应商的约定限制同时请求的DID数量。  在接收到读DID请求后,目标ECU应访问由DID绑定的相应数据,并将其值在一个单独的读DID正向响应中传输。  请求消息可以多次包含相同的DID,而目标ECU应将每个DID视为单独的参数,并根据请求的次数为每个DID提供数据响应。 3.2.1.3 数据格式 3.2.1.4 通信实例  第一个例子读取一个包含单个信息的2字节DID(其中DID 0xF190对应数据为车辆的VIN号)。  第二个示例演示了用一个请求请求多个DID(其中DID 0x010A包含:发动机冷却剂温度、油门位置、发动机速度、流形绝对压力、空气质量流量、车辆速度传感器、气压、计算负载值、空闲空气控制和加速踏板位置;DID 0x0110包含电池正极电压)。 3.2.2 0x2E 通过ID写数据 写DID 3.2.2.1 简介 该服务与0x22服务是成对的,推荐先阅读0x22-通过DID读数据。客户端根据提供的DID将信息写入目标ECU,常用场景如下: 将配置信息(例如VIN码)编程到ECU中; 清除非易失性存储器; 重置已写入flash中的值; 设置一些可配置字段的值。   Tip📌:目标ECU可能限制或禁止对某些DID的写入访问(由系统供应商/车辆制造商定义为只读标识符等。 3.2.2.2 数据格式 NRC的处理流程如下所示(即推荐的错误情况检查顺序): 3.2.2.3 通信实例 3.3存储数据类 存储数据传输类是一种特殊的数据传输类别,用于在ECU和诊断工具之间传输存储数据。存储数据可以是ECU的配置信息、故障码或日志文件等。通过存储数据传输类,技术人员可以读取和清除ECU中的存储数据,以便进行故障诊断和维修。所涉及的两个服务都是常用服务类型。主要包括如下服务: 3.3.1 什么是DTC 简介 DTC(Diagnostic Trouble Code,诊断故障码)是指车辆电子控制单元(ECU)存储的车辆故障代码,它是一种数字编码,用于标识车辆的故障问题。每个DTC都与特定的故障相关联,这些故障可能会导致车辆的某些系统无法正常工作。   车辆在运行过程中ECU会持续监控车辆运行状态,检测到故障时,它会记录相应的DTC,并将其存储在车辆的故障存储器中。通过读取故障存储器中的DTC,可以快速确定车辆的故障问题,并采取相应的修复措施(涉及DTC的读取和清除:0x14服务和0x19服务)。 DTC数据格式解析 DTC的格式定义是依据几个标准来的,比如ISO-14229-1,SAE J2012 OBD DTC和SAE J1939-73(在J1939中有详细介绍)等。就学习DTC来说,我们不必关注各个标准间的异同和细节,只需了解DTC分为non OBD和OBD两种格式(非OBD和OBD模式),具体格式如下所示: 可以清晰地看到DTC由四个字节组成,最高字节均保留未使用,剩下三个字节我们标记为:DTC HighByte、DTC MiddleByte、DTC LowByte。  DTC HighByte和DTC MiddleByte两个字节表示故障内码,对应5位标准故障码(一位字母+四位数字)。  DTC LowByte描述了故障的种类和子类型(可以参考ISO 15031-6以及SAE J2012-DA,比如常见的timeout应该用0x87,信号无效为0x81等等),简单理解就是对故障类别作进一步的区分/描述,未使用这个字节的可以用0x00填充,比如OBD格式的最低字节未使用,默认为0x00。 ——举例 DTC:B100016 (B1000表示5位,这里的位不是Bit的意思,所以5位对应的是第一位B(占2Bit),第二位1(2bit)第三位0(4bit)第四位0(4bit)第五位0(4bit))   其中"B1000"表示故障内码,对应5位标准故障码;"16"是DTCLowByte的内容。故障内码与5位标准故障码的对应关系如下: 看完上面的DTC五位标准故障码的构成,再来看个例子:   DTC-P010016:第一位是P代表此故障码和动力系统相关;第二位是0,是ISO标准中定义的故障类型;第三位是1,表示燃油和空气供应的测量相关;第四位和第五位是都是0,是具体的故障对象和类型的一个编码;第六位和第七位16则是DTCLowByte的内容。   在车载操作系统的代码中,DTC码通常作为十六进制数处理,将P010016转换为16进制数如下所示:   二进制表示为:P(00) 0(00) 1(0001) 0(0000) 0(0000) 1(0001) 6(0110)   十六进制表示:0x10016 Tip📌:不必疑惑有些位到底表示什么故障类型,更具体的含义是什么,通常制造商会提供他们每个编码的具体含义。   完成上面对DTC码的学习后,我们可以根据DTC大致知道是哪个系统什么类型的故障,但不能清晰得知故障是什么时候发生的,是什么原因触发的这个故障、现在是否已经恢复、发生过几次,恢复过几次等细节性信息,因此还需要其他信息:比如DTC状态(DTC status)、DTC快照信息(Snapshot)和DTC扩展数据信息(Extended data)。只有发生故障的时候存储下了这些关键信息,才能有助于故障的解决。下面将具体介绍这些DTC的关键附属信息。 DTC附属信息 DTC status DTC状态为1个字节,其8个bit位含义各不相同,如下表所示: Tips: 一般 testFailed 该位表示的是时时监测阈值是否触发,但并不是最终确认报警的状态位 testFailed 位通常是实时的,在最近的一次监测周期中,如果某个ECU监测的参数不在预期的范围内,就会将这一位设置为 1。这表明在最近的检测周期中,该ECU监测到了一个故障。但这并不意味着故障会立即被记录下来,因为它可能是暂时的或偶发的。 pendingDTC 位则是在故障符合一定条件后才被置为 1,通常是在故障在一个或多个操作周期中被检测到。pendingDTC为1意味着故障已经被记录下来,但还未达到confirmedDTC(确认DTC)的标准。    testFailed位被置为1并不会自动导致pendingDTC置为1。pendingDTC的置位通常需要故障在连续的操作周期中持续出现。具体的置位条件由制造商根据监测策略和法规要求定义。 ——举个例子:   假设有一个监测策略,它要求一个故障必须在两个连续的操作周期检测到才能将pendingDTC置为1。 第一个操作周期:故障首次被检测到,testFailed被置为1,但pendingDTC保持为0,因为我们还没有达到故障记录的条件。 第二个操作周期:故障再次被检测到,testFailed仍然为1。因为这个故障现在已经在连续两个操作周期中被检测到了,pendingDTC将被置为1,表明故障已经被记录下来,但还未确认。 第三个操作周期:如果故障未被检测到,testFailed位将被清除(置0),但pendingDTC可能仍然保持为1,因为它通常需要多个操作周期的故障消失来清除。   因此,pendingDTC的置位是一个基于监测策略的累积过程,而不是简单地跟随testFailed位的状态。 DTC 快照(snapShot) DTC 与Event的关系 DTC是某类故障的统称,能够大体定位到某个模块的故障,而Event则是故障监控的基本单元,能够定位某个模块中的某个具体故障;Event可以由基础模块自行定义监控策略,当发生故障Event时,需要完成这个Event的上报、去抖(防止故障误报)、存储等过程,这些处理流程由DEM模块负责管理(Diagnostic Event Management)。 Tips: 事件基本是由一个监测流程最后触发的事件,比如Mos过流,可能是负载过大导致,也有可能是Mos损坏带来的,这是两种事件但指向了同一个DTC 快照信息内容 DTC快照信息(Snapshot Record)就类似照相机一样,在故障发生的时刻,对整车信息按下快门,做个记录,以便后续分析问题。其所记录ECU发生故障时运行状态信息可以包括多个方面的数据,笼统的说比如故障码、故障条件、传感器数据、控制单元状态等。常见一些数据有:故障发生时的时间戳、ECU电压值、电流值、温度或者由故障Event引起的相应DTC等等。 Tip📌:快照信息存在的意义   由于一个DTC可由多种故障Event触发(多个Event可以mapping 同一个DTC),因此需要通过快照信息进一步区分这个DTC具体是由哪个Event触发的。 DTC&SnapShot&Event&DID的关系 整车系统中可能存在各种故障Event,比如电池低压/过压事件、通信丢失事件、胎压故障事件等。为了更好的区分故障类型,整车制造商会将这些事件关联(mapping)到不同的DTC。同时,为了维修人员更快、更准确的识别故障事件,还需要提供一些额外的辅助信息,比如故障发生时的时间、ECU供电电压、相关传感器数据等。为了获取这些信息,可以将这些信息设置一个快照信息组(Snapshot Group),为了区分不同的Snapshot Group,可以为每个Snapshot Group分配一个识别号,即DTCSnapshotRecordNumber。   UDS要求,DTCSnapshotRecordNumber由1 byte组成,0x00一般预留给OBD协议使用,0xFF表示ECU一次将所有的快照数据上报,0x01~0xFE由OEM自行设定。 Tip📌:每个DTCSnapshotRecordNumber包含一组快照信息,一组快照信息中可以包含多个DID,每个DID则包含具体的信息。 DTC扩展数据信息 Tip📌:这些DTC信息、状态位信息、快照信息、扩展帧信息都可以通过UDS协议中的0x19服务读取。 和DTC快照信息的功能类似,由于DTC中8bit位可以承载的信息是有限的,仅能说明故障是当前故障还是历史故障。故障发生时的其他重要信息还需要额外的数据存储,常见的一些扩展数据如下所示: 3.3.2 0x14 清除诊断信息 3.3.2.1 简介   Tester可以通过该服务清除一个或多个目标ECU中的的DTC信息。目标ECU完成清除操作后,应发送一个正响应。即使没有存储任何DTC,也应发送正响应(回复服务码)。   通过此服务重置/清除的DTC信息包括但不限于以下内容:  DTC状态字节(DTCStatus),  捕获的DTC快照数据(DTCSnapshotData),  捕获的DTC扩展数据(DTCExtendedData),  与DTC相关的其他数据,例如第一个/最近的DTC、标志、计数器、定时器等。    常用的一个场景是:ECU刷写新软件后,会通过该服务清除下DTC然后再读取,从而查看是否存在异常的DTC,保证系统监控正常。 3.3.2.2 数据格式 0x14 + 你想清楚的DTC组 Tip📌:该服务不存在sub-function   该服务请求消息包含一个参数:groupOfDTC,这个参数允许客户端清除一组DTC(例如动力总成、车身、底盘等)或特定的DTC。其取值及相应含义如下表所示: 3.3.2.3 通信实例 3.3.3 0x19 读取DTC数据 3.3.3.1 简介 0x19服务是子服务类型最多(SF),也是最复杂的以及最重要诊断服务之一,同时也是最能体现“诊断”一词的服务。通过对DTC相关内容的学习我们知道:通过DTC及其附属信息,我们可以了解到目标ECU何时何地何种场景下发生了什么样的错误,这些信息存储在目标ECU的故障存储器中,0x19服务存在的意义就是可以通过不同的子功能来读取目标ECU中存储的这些故障信息(可以理解为通过各种过滤规则读取这些故障信息)。 Tip1📌:该服务目的是从目标ECU中读取故障信息,一般不抑制响应 3.3.3.2 常用子功能 3.3.3.2.1 0x19 01(reportNumberOfDTCByStatusMask) 反馈符合DTC状态掩码(过滤参数)的数量 DTC状态(DTC status)是DTC的关键附属信息之一,如果我们想知道符合特定的DTC状态的DTC数量,就需要通过sub-function为01的请求,所说的这个特定的DTC状态就叫做DTC状态掩码(DTC Status Mask)。   在该子服务中,该掩码作为请求参数给到目标ECU,目标ECU将其与自身存储的DTC的Status进行“与”运算,并返回"与"运算之后结果不为0的DTC的数量(比如某故障码的实际状态位为“1”,请求信息的DTC状态掩码中的相应位也为“1”,与运算得1,认为两者匹配,此时符合DTC状态的DTC数量+1)。通过该子功能,Tester能够得知目标ECU中DTC状态与DTC状态掩码相匹配的DTC个数。 数据格式定义 ——请求格式 DTCStatusMask(1Byte):DTC状态掩码,Server收到该请求后,将筛选符合该掩码的DTC数量。 ——肯定响应 DTCStatusAvailabilityMask(1Byte):用于表示目标ECU支持的状态位,跟DTCStatusMask结构一样,8个bit,bit值为0表示目标ECU不支持这个状态位,为1则表示支持。跟请求中的DTC状态掩码没有关系!!   DTCFormatIdentifier(1Byte):指示了目标ECU所用的DTC的格式,一个ECU只能使用一种格式。具体有以下几种: DTCCount(2Byte):表示符合请求中DTC状态掩码的DTC数量。 ——否定响应 可能出现的NRC及其含义如下,该服务其他子功能对应的否定响应也都是一样的,后面就不再赘述了: 通信实例 3.3.3.2.2 0x19 02(reportDTCByStatusMask) 检索匹配状态掩码的DTC列表,01是返回数量,02是返回符合的DTC 该子功能用于读取符合特定条件的DTC列表,这个特定条件仍然是DTC状态掩码(参见对19 01的描述),该掩码作为请求参数给到目标ECU,目标ECU将其与自身存储的DTC的Status进行“与”运算,并返回"与"运算之后结果不为0的DTC列表(回复匹配的DTC本身而非数量)。 数据格式定义 ——请求格式 ——肯定响应 相对于19 01,新增了一种参数类型:   DTCAndStatusRecord(不定长:n*4Byte):包含一条条DTC及其状态。对于大部分定义DTC格式的标准来说,每条记录的格式为 “DTC高字节+DTC中字节+DTC低字节+DTC相应状态”。 通信实例 3.3.3.3 0x19 04(reportDTCSnapshotRecordByDTCNumber) 为了方便快速定位故障,目标ECU会记录故障发生时候的快照信息(也称冻结帧)。DTC快照信息(Snapshot Record)就类似照相机一样,在故障发生的时刻,对整车信息按下快门,做个记录,以便后续分析问题。常见一些数据有:故障发生时的时间戳、ECU电压值、电流值、温度或者由故障Event引起的相应DTC等等   通过04子功能,目标ECU根据请求中指定的故障码(DTC),查找并返回其对应的快照信息,来分析故障原因。 数据格式定义 ——请求格式 DTCMaskRecord(1Byte):DTC掩码(实际上就是某个具体DTC),目标ECU会查找跟这个值匹配的DTC。(注意该参数跟DTCStatusMask没有任何关系,别看花眼了)   DTCSnapshotRecordNumber(1Byte):表示特定的DTC快照数据记录编号。DTC快照可以分为不同的组,每个组包含不同的快照信息,并使用快照记录编号区分每个组。这个参数就是表示请求的是哪组快照。例如当我们需要记录某个DTC第一次发生(假设编号为1)和最近一次发生的快照数据时(假设编号为2);那么当DTCSnapshotRecordNumber为1时,则表示请求该DTC第一次发生时的快照信息。   这个编号需要目标ECU提前定义,比如该参数设置为0xFF,则表示读取所有的快照数据组。取值情况及对应含义在标准中的预定义情况如下所示: ——肯定响应 相对于之前的子功能,在响应的最后,携带了一个或多个快照数据(比如请求中的DTCSnapshotRecordNumber为0xFF,则表示读取所有的快照数据组,这里就会返回所有的快照数据),每个快照数据组的构成如上图大方框所示,这里我们把它称为DTCSnapshotData(标准中没有这个称呼),他由以下三部分组成:   DTCSnapshotRecordNumber(1Byte):第几组快照记录数据,其取值符合19 04请求中的第六个字节含义。   DTCSnapshotRecordNumberOfIdentifiers(1Byte):对应快照信息中记录的信息条目的数量。   DTCSnapshotRecord(不定长):每个信息条目成员的ID信息(DID)及其相应数据。 Tips📌:   ① 如果诊断仪请求的DTC或快照数据编号是目标ECU不支持的,属于参数错误,目标ECU应回NRC 0x31;   ② 如果DTC和快照记录编号都受支持,但目标ECU中当前没有存储这个DTC的快照信息(例如这个DTC对应的故障没有发生),那么ECU应返回肯定响应,但响应只包含59 04+DTC+DTC状态,不包含后面携带的快照记录信息。 通信实例 3.3.3.4 0x19 06(reportDTCExtDataRecordByDTCNumber) 除了前面的快照信息,一般还会再定义一个扩展信息,用于记录故障的一些其他信息,比如故障发生的次数、老化次数、已老化次数等。通过06子功能,目标ECU根据请求中指定的故障码(DTC),查找并返回其对应的扩展信息,来分析故障原因。 数据格式定义 ——请求格式 此时parameter为4个byte,前三个byte用于标识我们要读取的DTC,第四个byte用于标识要读取的环境数据的范围,UDS规定使用0xFF来表示读取所有的扩展帧数据,各厂家可以要根据自己的需求定义其他的值来代表要读取的扩展数据的范围。环境数据包括DTC状态,优先级,发生次数,老化计数器,时间戳,里程等,厂家还可以根据自己的需求定义一些此DTC产生时的其他测量数据。   DTCExtDataRecordNumber(1Byte):扩展数据记录码,该参数用于指定要获取的特定扩展数据记录。取值情况及对应含义如下所示: ——肯定响应 与前面的19 04十分类似,在响应的最后,携带了一个或多个扩展数据(比如请求中的DTCExtDataRecordNumber为0xFF,则表示读取所有的扩展数据记录,这里就会返回所有的扩展数据),每个扩展数据记录(扩展帧)的构成如上图所示,这里我们把它称为DTCExtData(标准中没有这个称呼),他由以下两部分组成:   DTCExtDataRecordNumber(1Byte):标识是哪一个扩展记录数据,其取值符合19 06请求中的第六个字节含义。   DTCExtDataRecord(不定长):每个信息条目成员的ID信息(DID)及其相应数据。 通信实例 3.3.3.5 0x19 0A(reportSupportedDTC) 检索目标ECU所有支持的DTC信息(3字节的DTC标识符+1字节的DTC状态位),其响应报文与02服务一致;但要区分,该服务返回的是所有DTC的信息;而02服务是返回与请求时状态掩码相与不为0 的DTC信息。   注意:不论DTC状态如何,故障是否发生,都要返回。通常用来测试ECU中实际支持的DTC和预定义的DTC列表是否相符。 数据格式定义 ——请求格式 ——肯定响应 通信实例 通信示例可以直接参考19 02通信示例。 3.4IO控制类 IO控制类是用于控制ECU输入输出(IO)功能的UDS服务类别。它提供了对ECU输入输出功能的访问和控制,包括读取和设置ECU的输入输出状态。通过IO控制类,技术人员可以与ECU的IO功能进行交互,实现对车辆系统的控制和监控。主要包括如下服务: 3.4.1 0x2F 通过ID控制输入输出 简介 在车载ECU控制功能中,有很多复杂的控制,比如控制发动机转速,归零标定方向盘角度等;也有很多简单的控制,比如风扇的开关、车窗的升降、后视镜的调节,车内灯光的开关控制等等。当我们想让ECU执行这些控制的时候,既可以通过0x31-例程控制功能(在ECU中设置一段执行逻辑,输出控制信号让执行器执行相应操作),也可以通过我们今天要阐述的0x2F服务。两者的区别在于,0x31服务通常用于一些复杂控制逻辑,而2F服务用于控制简单的IO 通断,不涉及复杂的流程。   举个简单的例子:”踩刹车,刹车尾灯亮“,在实车上,这个简单的逻辑由车载ECU控制,传感器检测是否踩了刹车,作为输入信号传输到ECU,ECU输出控制信号控制刹车尾灯亮灭。通过0x2F服务,我们可以通过Tester直接跟ECU通信,跳过硬件电路的检测,直接改变ECU输出的控制信号,让刹车尾灯亮起。 ——这里大家可能有两个疑问:    Q1:上面例子中放到实车上是实际可见的,对于一块独立的ECU板子或者是台架环境(模拟实车搭建出来的用于测试的硬件环境),如何判断这条IO控制请求真的起作用了呢? A1:还记得数据传输类中的0x22-通过ID读数据服务吗,当通过0x2F服务控制IO的输出信号后,可以通过0x22再读取出来,比较结果以判断是否成功完成控制。因此,通常一个ECU支持0x2F服务的话,也会支持0x22服务。 Q2:既然是直接跳过硬件检测电路控制IO的输出信号,这样做的意义是什么,毕竟在实车上不会这样,而且既跳过了硬件检测电路的检查,又跳过了ECU中软件逻辑的检查? A2:可以用于与该IO输出相关的其他功能的检测,实现自动化测试,比如需要依据刹车灯控制信号做一些其他的控制算法,如果没有这个服务,测试时不容易直接控制刹车灯的控制信号。 数据格式协议 ————请求格式 该服务不支持sub-function。部分参数的含义如下所示:   dataIdentifier(2Byte):参数用于标识目标ECU待受控的信号,在0x22服务中描述过DID相关内容。   controlOptionRecord(不定长):该参数标识控制模式以及所需的控制参数,由inputOutputControlParameter和多个controlState组成。控制模式有以下几种: Tip📌:当控制模式取值为0x00,0x01,0x02时,请求报文中不需要加入“其他参数2”中的controlState以及“其他参数3”,只需执行诊断请求 2F + DID +控制模式值即可。   controlEnableMaskRecord(不定长):该参数由一个或多个ControlMask(1Byte)构成,当要控制的DID由多个参数组成时,才支持该参数;对于只由单个参数组成的DID,不支持该参数。(注意,DID中的每个参数可以是任意数量的位)   该参数中的每个位的值将决定该请求是否会影响DID中的相应控制参数。参数中每个ControlMask都是1个字节,字节中某个位值为’0’表示该请求不会影响相应控制参数,位值为’1’表示该请求会影响相应控制参数。可以简单理解为将对应控制参数与该参数的bit位进行映射,若bit位为1,则对应参数将受控,若为0,则对应参数不受控。   读起来可能有些晦涩难懂,举个例子并加以图解:假设该参数由两个ControlMask组成,ControlMask1的最高有效位应对应于controlOptionRecord中的第一个控制参数,ControlMask1的第二高有效位应对应于controlOptionRecord中的第二个控制参数,依此类推。ControlMask2的最低有效位将对应于controlOptionRecord中的第16个控制参数。(需要确保controlEnableMaskRecord中每个参数的屏蔽位位置与controlState中对应参数的位置完全匹配) ————肯定响应  dataIdentifier(2Byte):跟请求消息中的保持一致。   controlStatusRecord(不定长):参数由多个字节(InputOutputControlParameter和controlState#1至controlState#m)组成,其实就是请求报文中的controlOptionRecord,也跟请求保持一致就行。需要注意的只不过是:这里返回的controlState参数是目标ECU的反馈值,可能跟请求中的不一样,看后面的例子就明白了。 ————否定响应 通信实例 单个参数控制 以控制发动机进风门位置为例,通过DID(0x9B00)控制该参数,在目标ECU中应当实现一些转化关系,即将接收到的参数值通过一定的数学运算转换为实际用来控制的数值,假设这个例子中的转换关系为:进风门位置% = 参数值(Hex) × 1%。,通信流程如下所示(该例子中涉及到0x22服务): 多个参数实例 控制参数只有5个,controlEnableMaskRecord参数中使用1个字节的ControlMask(8个bit位)即可,ControlMask将使用5个bit位对应这5个参数的控制使能。如下所示: 3.5例程控制类 例程功能类是一种特殊的UDS服务类别,它允许技术人员调用ECU内部预置的函数。这些函数可以执行特定的操作,如执行自检、执行校准或执行特殊功能。通过例程功能类,技术人员可以利用ECU内部的功能来进行诊断和维修。主要包括如下服务: 3.5.1 0x31 例行程序控制 简介  所谓“例程”,简单理解你可以认为就是个函数或者一段执行逻辑,而“例程控制”就是控制这段执行逻辑的启动、停止或者获取其执行结果,这就是0x31-例行程序控制服务的作用。每个“例程”都有一个唯一的标识,称为Routine ID(RID),以便在0x31服务的请求中区分请求执行的是哪一个”例程“。   该服务具有很大的灵活性,但典型的使用方式有擦除内存、重置或学习自适应数据、运行自检、控制目标ECU值随时间变化等。通常情况下,该服务用于更复杂类型的输出控制,而0x2F-通过ID控制输入输出用于相对简单的输出控制,大多情况下0x2F服务的功能都能够通过0x31服务来实现,不过一般不这么做,属于杀鸡用牛刀的做法。 数据格式定义 ————请求格式  各个参数的含义如下所示:   routineControlType(1Byte):表示要对routine进行何种控制(启动、停止、获取执行结果),取值及相应含义如下所示: routineIdentifier(2Byte):该参数和数据传输类服务中的DID参数类似,我们可以称它为RID,也是用来标识具体的功能的,可以理解为给各种要执行的操作(routine)一个代号。有个别RID在标准中是有明确定义的,RID相关取值如下表所示:  routineControlOptionRecord(不定长):该参数是可选的,需要根据routine的具体设计决定,比如有些routine需要额外的数据,就可以通过这个参数来传递,比如routine是用来进行数据校验的,需要把标准值告诉目标ECU,这样目标ECU就可以根据自身计算结果和接收到的标准值进行比较,来判断校验结果。 ————肯定响应 outineControlType和routineIdentifier的定义跟请求消息中的保持一致。   routineInfo(1Byte):该参数是可选的,用于在执行相应routine后,返回routine相关信息,具体该参数用做什么由制造商做决定。   routineStatusRecord(不定长):该参数也是可选的,用于在执行相应routine后,返回目标ECU相关信息(比如通过31 02服务请求目标ECU停止routine时,目标ECU可以通过该参数返回该routine运行时间等信息),可根据实际需要进行使用,很少用到。 ————否定响应 通信实例 3.6上传下载类 上传下载类是用于在ECU和诊断工具之间进行数据上传和下载的UDS服务类别。它提供了将数据从ECU上传到诊断工具或将数据从诊断工具下载到ECU的功能。上传下载类可用于备份和恢复ECU配置、更新ECU软件或执行其他数据传输操作。主要包括如下服务: 3.6.1 0x34 请求下载 简介   例如用于缓存ECU诊断数据的那块buffer通常是有限的,为了向ECU中写入数据,可以使用我们前面提到过的0x2E服务(通过ID写数据)。但当要写入的数据块很大时(最常见的就是升级ECU软件,通常数据量是要上KByte甚至MByte的),为诊断数据定义的buffer已经不能满足使用需求。于是,上传下载类服务应运而生,他们主要用于大块数据的读取或写入 该服务用于启动数据传输服务,传输方向是Tester(Client)→ 目标ECU(Server),向目标ECU发送该请求的主要作用就是告知目标ECU“我(Tester)准备向你传输数据了,请你(目标ECU)准备接收数据”。   目标ECU正确收到该请求消息后,可以发送响应告诉Tester自己是否允许传输数据,以及自己的接受能力是多大,如果可以传输,目标ECU应采取一切必要措施接收数据,然后再发送肯定响应消息。 数据格式定义 ————请求服务 该服务不支持sub-function。部分参数的含义如下所示:   dataFormatIdentifier(1Byte):数据压缩方法(4-7bit)| 数据加密方法(0-3bit) 这个单字节里面标识了数据格式相关的信息,每半个字节分别编码,高半字节指定 “数据压缩方法”,而低半字节则指定“数据加密方法”。如果该字节取值为0x00,则表示既不使用加密方法也不适用压缩方法,其他取值情况有整车制造商或者供应商决定,可以用约定好用不同的取值代表数据是否有压缩,是否有加密,用的又是什么算法等等。   addressAndLengthFormatIdentifier(1Byte): 该参数含义在图中标识的已经比较清晰,不再赘述。比如memoryAddress参数占用m个字节,memorySize参数占用n个字节,则该参数取值为0x(nm)。   memoryAddress(mByte):对于即将启动的数据传输,该参数指明了向ECU内存写入数据的逻辑地址。比如Tester请求将数据写入ECU内存地址为0x12345678的地方(该地址占4个字节),则memoryAddress值为0x12345678,对应addressAndLengthFormatIdentifier参数低4Bits值为0x04。   memorySize(nByte):对于即将启动的数据传输,该参数指明了向ECU内存写入数据的字节数。比如Tester请求写入ECU数据的字节数为0x01234567(即memorySize占4字节),则memorySize值为0x01234567,对应的addressAndLengthFormatIdentifier高4Bits值为0x4。 ————肯定响应 lengthFormatIdentifier(1Byte):该字节每半个字节单独编码,高4Bits为maxNumberOfBlockLength有效字节长度,低4Bits保留为0。   maxNumberOfBlockLength:字节长度不定,取值长度取决于lengthFormatIdentifier的高半字节,表示0x36服务一次传输一个block的最大的字节数。比如该参数取值为0x202,则使用0x36服务时,一次最多发送字节数为0x202(字节数:0x202 >= 36 (1Byte)+ parameter(x个Bytes))。 ————否定响应 通常0x34、0x36、0x37三个服务是放在一起使用的,学习完这三个服务之后将做一个详细的通信示例,以便更好地了解整个数据传输过程。 3.6.2 0x36 数据传输 简介 该服务用于在Tester和目标ECU之间传输数据,可以是从Tester向目标ECU传输(下载)或从目标ECU向Tester传输(上传)。数据传输方向由前面的0x34-RequestDownload或0x35-RequestUpload服务定义。即0x36服务必须在0x34或0x35服务之后才能正常执行。  如果Tester发起了0x34-RequestDownload请求,则要下载的数据包含在该服务请求消息中的transferRequestParameter参数中;  如果Tester发起了0x35-RequestUpload请求,则要上传的数据包含在该服务响应消息中的transferResponseParameter参数中。 数据格式 ————请求格式 该服务不支持sub-function。部分参数的含义如下所示:   blockSequenceCounter(1Byte):参数的初始值为0x01,从RequestDownload (0x34)或RequestUpload (0x35)服务后的第一个TransferData请求开始。每个后续的TransferData请求,blockSequenceCounter的值递增1。当blockSequenceCounter的值达到0xFF时,它将重新变为0x00,然后随着下一个TransferData请求继续递增。 以数据下载过程中该服务的使用为例,可以看到该参数的作用:  如果下载数据的TransferData请求在目标ECU中已经被正确接收和处理,但目标ECU发出的正响应消息未能到达Tester,则Tester会检测到超时,并重复相同的请求(包括相同的blockSequenceCounter)。于是目标ECU会接收到重复的TransferData请求,并根据包含的blockSequenceCounter确定这是一个重复的请求。这是目标ECU会立即发送正响应消息,而无需再次写入数据到其内存中。  如果下载数据的TransferData请求在目标ECU中未能正确接收,则目标ECU不会发送正响应消息。于是Tester端会检测到超时,并重复相同的请求(包括相同的blockSequenceCounter)。目标ECU会接收到重复的TransferData请求,并根据包含的blockSequenceCounter确定这是一个新的请求。服务器会处理该服务,并发送正响应消息。   transferResponseParameterRecord(不定长):这个参数记录包含目标ECU需要支持数据传输的参数。这些参数的格式和长度是由车辆制造商指定的。例如,在下载操作中,transferRequestParameterRecord包含要传输的数据。 ————肯定响应 blockSequenceCounter(1Byte):跟请求消息中的保持一致。   transferResponseParameterRecord(不定长):这个参数的格式和长度是由车辆制造商指定的。例如,在下载操作中(上一条请求是0x34),那么该参数可能包含目标ECU根据请求下载的数据计算得出的校验和。在上传操作中(上一条请求是0x35),该参数包含要上传的数据。在下载操作中,该参数不应与transferRequestParameterRecord重复。 ————否定响应 3.6.3 0x37 请求退出传输 简介 不管是数据上传还是下载过程,该服务由Tester发起,用于终止Tester和目标ECU之间的数据传输。 数据格式 ————请求格式 其中transferRequestParameterRecord参数应包含目标ECU需要支持数据传输所需的参数。该参数的格式和长度是是由车辆制造商决定的 ————肯定响应 ————否定响应 通信实例 基于对0x34、0x36、0x37三个服务的学习,这里举一个完整的例子,该示例实现:通过Tester将数据下载到目标ECU中,该示例最为常用的场景就是在车载ECU软件升级过程中更新目标ECU flash中的软件。数据下载到目标ECU的过程分三步: Tester通过0x34-请求下载服务向目标ECU发送请求,该请求消息中将包括数据的格式信息(是否压缩、加解密信息)、数据要往哪个地址写、要写入多少字节的数据。目标ECU收到该请求后将通过响应告诉Tester:“我(目标ECU)每次最多能接收多少自字节”,即目标ECU会表明自己每次的接收能力。 Tester得知目标ECU每次接收能力后,将要传输过去的数据按照目标ECU接收能力拆分成一个个数据块(block),通过0x36-数据传输服务将数据一块块的传输到目标ECU。 Tester端数据传输完成后,通过发送0x37-退出传输服务请求来终止数据传输过程。   在钥匙电开启,发动机关闭,车速为0的背景下,Tester和目标ECU间的通信过程如下图所示: ISO-TP协议 UDS网络层/TP层(ISO 15765-2)的解读 UDS网络层,又称为TP层(Transport Protocol Layer)。其存在的目的是为了解决ISO 11898协议中定义的经典CAN数据链路层与ISO 14229协议中定义的应用层,彼此之间数据长度不统一的问题。经典CAN数据链路层最大能够支持8个字节,但ISO 14229并不仅仅是为了CAN总线设计的,最大容量达到4095个字节。比如VIN码是17个字节,CAN总线必然需要传递3帧才能传完VIN码,那么如何科学、快捷、安全地将多个字节通过经典CAN来进行传输,就成了一个需要解决的问题。ISO 15765-2 协议由此诞生 专业术语 ISO-TP传输协议格式详解 特殊帧定义 Tips: SingleFrame用于下面这种简单的场景:当诊断报文长度小于等于7时,再加上一个字节的PCI控制信息就是小于等于8,可以在一帧CAN报文上传输,所以不需要进行分包。此时数据域的第一个字节高4bit值为0000,标识这是一个帧SingleFrame,低4bit是SF_DL,即DataLength,描述后面有几个字节。如果有没有使用的字节,通常要用0x55或0xAA来填充,因为这两个值的二进制表述其实就是01010101和10101010,这样在CAN总线上可以让信号跳变得更频繁一些,不会出现长时间电平不变的情况。 根据第一个字节的高4Bit,可以区分帧的定义 特殊帧: SF 0x01 单个帧,当应用层下发数据小于7个字节时会使用单个帧。 FF 0x01 首帧,当应用层下发数据大于7个字节时会使用首帧,在第一包数据时会进行首帧发送 其中第一个字节的低四位和第二个字节组成本次通讯的总字节数,最大14Bit,4095个字节 后续是应用层下发数据 FC 0x03 流控帧,在发完首帧后,会有流控帧确认发送间隔,和准备接收包数 前三个字节为3(4bit)+流状态(FS,4bit)+块大小(BS,8bit)+最小间隔时间(STmin,8bit),控制信息共占用三个字节 CF 0x02 连续帧, 通信实例 TIPS 需要提一下的是,BS和STmin等于0时,表示接收端可以以最快的速度来接收数据,发送端可以一次发送的ConsecutiveFrame数量不受限制。
posted @   catleeee  阅读(877)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示