转载来自知乎:https://zhuanlan.zhihu.com/p/35143680 张丁
在关于UDS的第二篇文章中,我提到过UDS定义的服务从逻辑上分为6类,在第二至第六篇中已经讲解了前五类,在本文中将介绍最后一类UDS服务,即Upload Download functional unit ,数据的上传下载。
从成本等角度考虑,汽车ECU中用于缓存诊断服务数据的buffer大小有限,所以当我们需要读取或写入超过buffer大小的数据时,就无法简单地使用2E和22服务了,UDS据此定义了几个将大块数据写入或读出的服务,即数据下载和上传。
Upload Download functional unit总共定义了5个诊断服务,分别是:
- RequestDownload (0x34):客户端向服务器请求下载数据
- RequestUpload (0x35)客户端向服务器请求上传数据
- TransferData(0x36) 客户端向服务器传数据(下载),或者服务器向客户端传数据(上传)
- RequestTransferExit(0x37)数据传输完成,请求退出
- RequestFileTransfer(0x38) 传输文件的操作,可以用于替代上传下载的服务。
下图是数据下载的简略过程,用到了34,36,37这三个服务,如果是上传的话,34服务被35服务替换,数据传输方向变一下,就可以了。
Tester向ECU刷写数据的大概过程
RequestDownload (0x34):
0x34服务用于启动下载传输,作用是告知ECU准备接受数据,ECU则通过0x74 response告诉诊断仪自己是否允许传输,以及自己的接受能力是多大。
0x34服务的请求格式
0x34服务的请求格式包括5个部分
第一部分:1个byte的SID
第二部分:1个byte的dataFormatIdentifier,这里面标识了数据格式相关的信息,比如数据是否有压缩,是否有加密,用的什么算法加密等,应该由主机厂与供应商约定好,用哪个bit来表示压缩、加密等信息。
第三部分:1个字节的addressAndLengthFormatIdentifier,用于指示后面两个部分所占用的字节,高4bit表示memorySize所占的字节长度,低4bit表示memoryAddress
所占的字节长度。在这个例子中我将这两个值分别设置为n和m。
第四部分:m个字节的memoryAddress,由addressAndLengthFormatIdentifier中的低4bit指示。含义是要写入数据在ECU中的逻辑地址。
第五部分:n个字节的memorySize,由addressAndLengthFormatIdentifier中的高4bit指示。含义是要写入数据的字节数。
ECU收到请求之后,如果允许传输的话,会给出如下response
0x34服务的响应格式
第一部分:1个byte的 Response SID
第二部分:1个byte的dataFormatIdentifier作为echo
第三部分:maxNumberOfBlockLength,长度不定,表示可以通过0x36服务一次传输的最大数据量。
TransferData(0x36):
如果34服务得到了正确响应,tester就要启动数据传输过程了,使用的就是36服务。36服务的格式如下。
0x36服务的请求格式
第一部分:1个byte的 SID
第二部分:1个byte的blockSequenceCounter,标识当前传输的是第几个数据块,或者简单地说就是第几次调用36服务。
第三部分:transferRequestParameterRecord,传输的数据。第次传输数据量的上限就是34服务响应中的maxNumberOfBlockLength。
举例:如果ECU告知tester,maxNumberOfBlockLength = 20,也就是说tester每次通过36服务只能发送最多20个字节,其中还包括了SID和blockSequenceCounter,所以实际上每次可传的数据信息只有18个字节。如果tester要传的数据为50个字节,则需要传输三次,每次分别传输18,18,14个字节,即调用3次36服务。
36的响应很简单,就是一个字节的Response SID再加一个字节的blockSequenceCounter作为echo。
RequestTransferExit(0x37):
37服务用于退出上传下载,如果之前的34和36服务都顺利执行完成,那么37服务就可以得到ECU的positive response。
格式很简单,请求就是37,正确响应就是77,都是一个字节。
如果前面的36服务没有执行完成,以我前面举的例子来说,比如这个数据块有50个字节,但是tester只发了两次36服务传了36个字节,那么这次传输对于ECU来说是失败的,所以ECU应该给出NRC 0x7F 37 24,表示诊断序列执行有错误。