【AutoSar】汽车诊断标准协议UDS详解
目录
- 一、基本概念
- 二、UDS诊断协议
- 2.1 诊断服务的概念
- 2.2常用的诊断服务
- 2.2.1 诊断会话控制服务(10服务)
- 2.2.2 会话访问0x27服务
- 2.2.3 用于读写的DID的0x22/0x2E服务
一、基本概念
车辆的诊断需要有Tester端和ECU段通过应答的方式进行通信,他们使用同一协议进行诊断通信,比如ISO 14229协议就是UDS协议。在协议里定义了诊断需求、诊断响应的报文格式等等。下图描述了UDS在OSI七层模型中的应用。我们可以看到UDS可以建立在CAN网络上,也可以建立在FlexRay或者以太网上。
二、UDS诊断协议
2.1 诊断服务的概念
诊断服务的基本概念是:请求是由Tester发给ECU的,其中请求报文中带有SID(Services Identifier),根据具体的服务内容和含义后增加具体的数据。Tester会发送SID给到ECU,而ECU的响应报文也很有意思:肯定报文会在SID的基础上加40后返回;而否定报文则固定式7F,然后加上SID后加上NRC(Negative Response Code)。常用的NRC有:
- 11表示服务不支持;
- 12 subfunction不支持;
- 13 请求的长度不正确,或者格式不正确
- 31 是请求超出范围;
- 7E 是在当前会话下subfunction不支持
- 7F 是在当前会话下服务不支持
在请求报文的SID后面,紧跟的有两种情况,第一种是紧跟一个Subfunction,此时一个请求报文的格式就是SID+Subfunction+具体内容,而对应的肯定响应报文就是(SID+40)+Subfunction+具体内容。而部分UDS是不支持Subfunction的,则会使用DID(Diagnosis ID),其请求报文的格式是SID+DID+内容,肯定响应报文则睡觉哦(SID+40)+DID+具体内容
在支持Subfunction的UDS中,规定Subfunction的最高位为响应抑制位,当这个位为1的我时候,就会抑制肯定响应,也就是ECU将不会发送肯定报文,当然,否定报文还是会发送的。
ECU是很繁忙的,有时候ECU在忙更高优先级的事情,来不及响应UDS请求怎么办。答案就是使用Pending报文。当ECU收到请求但是无暇响应的时候,将会在规定的P2Server时间内给出一个NRC为78的Pending报文,表示正忙,如果ECU还是没时间回复,则会在规定的P2Server/*时间内继续发送Pending报文,直到可以回复响应报文。
2.2常用的诊断服务
诊断服务通过SID区分,常用的诊断服务包括:10会话控制、14清除诊断信息、22通过DID读取数据、27安全界所服务、2E通过DID写入数据
2.2.1 诊断会话控制服务(10服务)
ECU会有不同的会话控制,比如说ECU在开发、生产、售后阶段会使用不同的会话,每个会话能够使用的服务类型也不尽相同,因此10服务主要是用于会话控制。比如说刷写相关的34,36,37服务,在默认会话下是不支持的,这也很好理解:当车辆完成生产之后我们不能随便对ECU进行刷写
肯定响应不再赘述,主要是否定响应,10服务下的否定响应有3中NRC:7F, 7E, 31
当ECU发现发来的UDS报文的SID是当前会话下不支持的服务,则会发送7F这个NRC,比如在Default Session下尝试使用34、36、37服务进行刷包。
此外还有一个7E NRC,表示的是当前会话下Subfunction不支持。比如说10 02服务表示跳转到编程会话(SID:10, Subfunction: 02),但是ECU只支持从扩展会话跳转到编程会话,如果此时位于默认会话下执行10 02服务则会返回7E NRC,表示虽然我支持10服务,但是02子服务在当前会话下不支持。
还有NRC 31,NRC 31常用的用法是请求超出范围,比如说22服务,发送的DID,是ECU不支持的,比如说发送的请求22 01 01 ,因为ECU不支持01 01这个DID,会发送NRC 31的否定响应
刚才顺带也介绍了ECU的三个会话,其实ECU还有不少其他会话,具体和厂家标定有关,但是答题可以分为默认会话和非默认会话。刚上电的时候处于默认会话,然后此时我们可以通过10服务来切换会话,比如10 03切换为编程会话。当ECU处于非默认会话的时候,会有一个计时器S3 time,当这个计时器超时后,会自动从非默认会话切换到默认会话。为了保持非默认会话状态,Tester端需要周期发送3E服务(Tester Present),让ECU一直保持在非默认会话。
2.2.2 会话访问0x27服务
常用的一些服务,比如说22/2E之类的需要和ECU交换数据的,都会影响一些内存里的数据,所以这些服务是一个被保护的服务。这些服务只有在ECU处于解锁状态下才能执行,而ECU上电默认是锁定状态的,Tester端和ECU端进行27解锁服务之后,ECU才能够处于解锁状态。
首先由Tester端给ECU发送请求报文来请求种子,ECU收到这个报文后,回复肯定响应,肯定响应里带有种子数;Tester端收到这个种子数,根据自己安全算法算出来一个K1发送给ECU,ECU也有自己对应的安全算法,他由这个Seed算出来一个密钥K2,当ECU收到这个K1后和自身计算的K2进行比较,如果两者是一致的,那么ECU发送肯定响应给Tester端,告诉Tester端ECU已经解锁。
一个ECU可以同时拥有多个安全等级,多个安全等级之间可以是相互独立的,也可以是有依赖关系的,比如说要求先解锁安全等级1才能解锁安全等级2。当ECU处于解锁状态的时候Tester端再去请求种子的时候,回复的种子全为0。
请求种子的响应报文是27+01,肯定响应则是67+01+四字节种子。当Tester端计算得到密钥之后,则会使用27+02+4字节密钥发送给ECU,ECU对比自己的密钥和收到的密钥之后,会给Tester发送67+02,表示认证通过,ECU处于解锁状态。
2.2.3 用于读写的DID的0x22/0x2E服务
22服务用于根据DID读内容,请其格式是”22+两个字节的DID“,肯定格式是"62+DID+所读取的数据"。比如说DID为F1 86的时候代表读取当前诊断会话状态
具体在22中会使用到的DID以及对应功能在14229-1 2013的附录C中有写,可以去看看这个附录C
此外22服务的否定报文中带有NRC,其中13是格式不正确,14是读取的数据超过了传输最大值,31是请求的DID不支持,33则表示ECU未解锁。
2E是根据DID写入内容,基本流程都一样