目录
8.1 ReadDataByIdentifier(0x22)service
前面的文章我们介绍了诊断与通信管理单元中包含的几个服务,分别是0x10(DiagnosticSessionControl)服务、0x11(ECUReset)服务、0x27(SecurityAccess)服务、0x28(CommunicationControl)服务、0x3E(TesterPresent)服务、0x83(AccessTimingParameter)服务、0x84(SecuredDataTransmission)服务、0x85(ControlDTCSetting)服务、0x86(ResponseOnEvent)服务、0x87(LinkControl)服务。那么这些服务有些是我已经接触过的,用过的,所以在描述的时候我自己的理解会多一些,有些服务我也没有用过,所以描述基本上都是标准翻译过来的解释。
那么本章我们介绍下一个单元,数据传输功能单元。
如果您认真看完之前写的文章就会发现,第七章的部分实在是太多了,这么多的内容整合到一篇文章属实是有点让人感觉到厌烦,所以本章开始,每个服务我都会单独写一篇文章来描述,不会出现一章就是一大坨,这样看起来会比较轻松。
8 数据传输功能单元
图1中是数据传输功能单元中包含的服务:
![](https://i-blog.csdnimg.cn/blog_migrate/7ceffcbb60aed7b1e0b06a36515eaec9.png)
一共有7个服务,分别是:
0x22(ReadDataByIdentifier):通过标识符读取数据):客户端请求读取由所提供的数据标识符所标识的记录的当前值;
0x23(ReadMemoryByAddress):客户端请求读取所提供的内存范围的当前值;
0x24(ReadScalingDataByIdentifier):客户端请求读取由所提供的数据标识符标识的记录的缩放信息。
0x2A(ReadDataByPeriodicIdentifier):客户端请求调度服务器中的数据以进行周期性传输;
0x2C(DynamicallyDefineDataIdentifier ):客户端请求动态定义数据标识符,该数据标识符随后可以由readDataByIdentifier服务读取;
0x2E(WriteDataByIdentifier):客户端请求写入由所提供的数据标识符所指定的记录;
0x3D(WriteMemoryByAddress ):客户端请求覆盖提供的内存范围。
很惭愧,这些服务我只接触过22服务和2E服务,下面就一个一个来看吧。
8.1 ReadDataByIdentifier(0x22)service
ReadDataByIdentifier服务允许客户端从由一个或多个数据标识符标识的服务器请求数据记录值,意思就是请求消息中包含一个或多个数据标识符,每个数据标识符呢都对应着一些信息,比如说0x1234这个数据标识符对应着车速信息和里程信息,那么如果请求消息中包含0x1234这个数据标识符,肯定响应消息就会返回车速和里程值。
客户端请求消息包含一个或多个双字节dataIdentifier值(以下简称DID),用于标识服务器维护的数据记录(有关允许的DID数值,请参阅C.1)。数据记录的格式和定义应特定于车辆制造商或系统供应商,并可能包括模拟输入和输出信号、数字输入和输出信息、内部数据和系统状态信息(如果服务器支持)。
根据车辆制造商和系统供应商的约定,服务器可以限制可以同时请求的数据标识符的数量。
在接收到ReadDataByIdentifier请求后,服务器应访问DID参数指定的记录的数据元素,并在包含相关dataRecord参数的单个DID肯定响应中传输其值。请求消息可以多次包含相同的数据标识符。服务器应将每个数据标识符视为一个单独的参数,并根据要求经常使用每个数据标识符的数据进行响应。
8.1.1 请求消息定义
图2是0x22服务的请求消息定义,图3是比较好理解的格式:
![](https://i-blog.csdnimg.cn/blog_migrate/9594a88d7f87e57f2ce560d63d7e6c08.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3f556adda221cf9e5a4cca64520f3378.png)
22服务的请求消息只有两个部分,不要看标了这么多颜色,其实真的只有两个部分,第一部分是SID(1字节),在这里是0x22;第二部分是参数DID,注意了,这可不是子功能参数,这只是一种普普通通的参数,这个参数就是数据标识符了,可以有一个,也可以有多个,那么长度就是2*n字节啦,其中n=DID的个数,每个DID是两个字节。
8.1.2 肯定响应消息
22服务的肯定响应消息的标准格式如图4所示,易理解的格式如图5所示:
![](https://i-blog.csdnimg.cn/blog_migrate/736381180f947cf4578c36af09d7ccc6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b92245fe5312352075aedfd87ad3ea7e.png)
22服务的肯定响应消息就分为三个部分啦,第一部分是SID+0x40(1个字节),在这里就是0x62;第二部分是DID(2个字节);第三部分是参数dataRecord,那么这个参数就是对应的DID所表示的数据了。其中第二部分和第三部分是一一对应的,有一个DID,就会有一个相应的dataRecord,那么同样的,请求消息中有多少个DID,肯定响应消息中就会有多少个DID以及对应的参数dataRecord。
8.1.3 支持的否定响应码(NRC)
22服务的否定响应消息的格式如图6所示:
![](https://i-blog.csdnimg.cn/blog_migrate/d973045b0fcfc275f9b9c06b7cb8876b.png)
22服务支持的NRC如图7所示:
![](https://i-blog.csdnimg.cn/blog_migrate/0e32d54db72485048107ebf015026917.png)
那么14229-1中还给出了回复NRC的场景,或者应该说是服务器执行22服务的流程图,如图8所示:
![](https://i-blog.csdnimg.cn/blog_migrate/c714936184c8f23051958f97767faa34.png)
下面我们对此流程图进行解读:当服务器收到22服务的请求后,首先检查请求消息的长度是否符合要求,检查项有两个,一个是检查请求消息的长度是否大于最小长度,如果小于最小长度,那么返回NRC13,另一个是将请求消息的长度做模2除法,如果余数为1,说明长度不符合要求,此时返回NRC13。之后检查最大长度,如果请求消息的长度大于最大长度,同样返回NRC13(关于最大长度是多少,我认为应该是车厂或者供应商自定义的)。接下来就是一个循环检查每个DID的过程,在这个循环的过程中,首先检查一个DID在当前会话下是否支持被读取,如果不支持,可能需要先记录下来,再继续检查下一个DID,如果支持,那么下一步检查DID对应的安全等级是否已解锁,如果未解锁,直接返回NRC33,如果以解锁,执行下一步判断,下一步的判断条件是可选的,可能读取某些DID时需要有一些前提条件,这一步就是检测前提条件是否满足,如果不满足,直接返回NRC22,如果满足,检查是否还有下一个DID,如果有,执行上述的判断步骤,如果没有,则结束这个循环。循环结束后,判断是否至少有一个DID在当前会话中支持读取,如果没有,直接返回NRC31,如果有,执行下一步判断,下一步判断肯定响应的总长度是否超过了最大的数据长度,如果超过了,返回NRC14,如果没超过,并且所有的DID在当前会话中均支持读取,那么返回肯定响应消息。
8.1.4 消息流示例
假设:
第一个示例读取包含单个信息的单个2字节DID(其中DID 0xF190包含VIN号)。
第二个示例演示了使用单个请求请求多个数据标识符(其中数据标识符0x010A包含发动机冷却液温度、节气门位置、发动机转速、歧管绝对压力、空气质量流量、车速传感器、大气压、计算的负载值、怠速空气控制和油门踏板位置,数据标识符0x0110包含蓄电池正极电压)。
示例1:读取DID 0xF190(VIN码)
读取F190的请求消息如图9所示,肯定响应消息如图10所示:
![](https://i-blog.csdnimg.cn/blog_migrate/ee339fbd62f7323ef0750ae89fac7d39.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0ac2d0fc24343b7e5af0a3246f8b21c6.png)
图11是此消息流的易理解版本:
![](https://i-blog.csdnimg.cn/blog_migrate/2d020f643b523a6f9dd0515bd20bec5d.png)
简单来对此示例做个解释吧,请求消息就是SID+DID,SID是0x22,DID就是0xF190,肯定响应消息的话,先是一个SID+0x40,这里就是0x62,紧接着是0xF190,和请求消息中的DID保持一致,最后就是0xF190这个DID所表示的数据--VIN码了,一共有17个字节。这就是ReadDataByIdentifier服务的请求单个DID的示例。
示例2:读取DID 0x010A 和 0x0110
该例是同时请求两个DID,请求消息和肯定响应消息分别如图12和图13所示:
![](https://i-blog.csdnimg.cn/blog_migrate/ea5fa3f97c1f9b27db1291514992b99b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/08deab4cd0406543dfe48b75a253ec24.png)
同样的,给出易理解的版本如图14所示:
![](https://i-blog.csdnimg.cn/blog_migrate/bc64e75278d233f72c77fc4bee03c23c.png)
那么这个和示例1不同的地方就是读取的DID不同,并且该示例是同时读取2个DID,我们可以看到,同时请求多个DID和只请求一个DID的情况大致相同,只是请求多个DID时需要依次返回每个DID及对应记录的数据。
那么22服务到这里就结束了,我们回忆一下,22服务的功能就是通过DID来读取数据,看完了易理解的格式,看一看标准格式也有一定的好处,下个服务我们介绍0x23(ReadMemoryByAddress)服务,加油!