目录
前言
在学习完15765-2之后,已经能看懂各种帧类型,能从CAN报文中区分哪些是Can诊断传输层的东西了。

比如上面这张图,我们了解了传输协议(15765-2),知道了单帧、首帧是哪些,知道了图中单帧的数据长度是3个Byte。
但是,这单帧里面的3个数据(19 02 01)是代表啥意思呢?
所以,我们接下来,就是去看懂这些诊断应用层数据代表的含义(即解析14229-1)。
但在进入这些具体的服务学习之前,我们还需要先把一些每个诊断服务都会涉及到的通用知识点学习一下。
比如:
诊断请求的格式是怎么样的?
肯定响应、否定响应格式是怎么样的?
NRC概念。
等等。
搞清楚这些之后,再去学习具体的诊断服务,那么对各个诊断服务的学习就会清晰许多。
1、诊断请求
诊断请求共分2种:
①有子服务的诊断请求

(14229-1)
我们平时开发诊断的过程中,只会用到A_Data,其它的不用管它。
可以看到, A_Data分为3个部分:
SID:就是我们所说的诊断服务ID。
比如19服务。

Sub-function:就是我们所说的子服务。
比如19服务下的02子服务。

data-parameter:即参数。
比如19服务下的02子服务的功能是“根据状态掩码返回DTC”。
也就是说,你发完19 02之后,你只指定了功能,你还没告诉别人掩码是啥,所以它屁股后面还得再跟个掩码。
对于这里的19 02来说,掩码就是data-parameter。

②无子服务的诊断请求

(14229-1)
比如22服务,它是没有子服务的,它的诊断功能只有1个:读取指定DID的数据。

好了,诊断请求搞明白了,接下来我们看看诊断响应。
2、诊断响应
诊断响应也是只有2种:要么接受你的诊断请求(肯定响应),要么拒绝你的诊断请求(否定响应)。
①肯定响应

(14229-1)
(相信很多做诊断的朋友在工作中有常听到:肯定响应的首个字节是SID+0x40。而这话的出处,就是14229-1中上图的这个地方)
上图中的意思,简单来说就是:
所有诊断请求SID的bit6都是置0的,当返回肯定响应时,则肯定响应中SID的bit6需置1。
bit6置1,即0x40。
所以,总结来说,肯定响应的固定格式是:
(SID | 0x40 )+ 数据
我们使用19服务举例,如下图:
诊断请求:

(14229-1)
诊断响应:

(14229-1)
②否定响应

(14229-1)
这里我们也是只关心A_Data。
可以看到,否定响应的格式也是固定的:
0x7F + SID + NRC
其中,NRC(Negative Response Code),即,否定响应码,它内容稍微多一些,我们先放一放,在最后讲解。
否定响应举例如下:

3、抑制肯定响应位
首先,抑制肯定响应位是针对诊断请求的。
抑制肯定响应位,从字面上就很好理解:如果该位有效,则把肯定响应抑制。
但我们上面了解到,诊断请求可以分2为种:有子服务的诊断请求、没有子服务的诊断请求。
那么2种诊断请求都有抑制肯定响应位吗?
我们来看看14229-1中,关于抑制肯定响应位的描述:

(14229-1)
从图中可以看到,表格的标题为:Sub-function parameter structure
即,子服务参数结构。
也就是说,抑制肯定响应位,只针对于有子服务的诊断请求。
没有子服务的诊断请求是不存在抑制肯定响应位的。
原因也很好理解。
对于没有子服务的诊断请求,通常作用都是请求获取某些数据或写入数据。
比如22服务的目的就是为了读取某个东西的数据。
但是如果这个诊断请求被抑制肯定响应了,那这个诊断请求就没意义了。
别人目的就是要读数据,结果别人请求了,你却不给人家返回,那人家发这个诊断请求干啥。
而对于有子服务的诊断请求,通常作用都是实现某个功能。
比如10服务,它的子服务分别代表跳转不同的会话。10 01(默认会话)、10 03(扩展会话)。
因此,当发送10服务请求时,接收方可以不回复肯定响应,只需要完成请求的功能,即跳到指定的会话。
好了,接下来我们回到这张图,看看子服务参数的结构。

(14229-1)
bit0~bit6:代表的是子服务的值。
bit7:代表的是抑制肯定响应位。
图中关于抑制肯定响应位的功能,概括如下:
①诊断请求SID的bit7为1时代表抑制肯定响应,bit7为0时代表不抑制肯定响应
举例子如下:
抑制肯定响应位置1:应无肯定响应

抑制肯定响应位置0:应返回肯定响应

②抑制肯定响应位,它是抑制“肯定”。因此,它跟否定响应没关系。
如果是否定响应,无论诊断请求的抑制肯定响应有没有置位,都得正常回复否定响应。
③诊断请求的抑制肯定响应位如果置位了,它只是把肯定响应抑制了,不是把要实现的诊断功能抑制了。它该干的活还是得干。
比如领导跟你说:“你干完这个活不用回复我了”。你理解要到位啊:他是让你干完不用回复,不是让你不干活。
④所有有子服务的都要支持抑制肯定响应位。(关于这一点不用管它,一般开发时,客户需求会说清楚哪些服务要实现抑制肯定响应位)
那么,为啥要抑制肯定响应呢?
好好的诊断肯定响应,抑制它干啥?
我们前面的文章学过,诊断请求有物理请求和功能请求。
物理请求是一对一,功能请求是一对多。
而抑制肯定响应,它主要是针对功能请求(一对多)的情况
举个栗子,领导在好几十个人的群里发通知:大家填一下周报。
大家填完之后,如果一个个都在回复:
已完成
已完成
已完成
...
那这群不直接炸锅嘛。
而对于实车CAN总线来说,CAN总线上挂了有好几十个ECU节点。
如果诊断仪发送诊断功能请求时没有抑制肯定响应,则会导致跟上面领导发通知时类似的问题:
1、CAN总线的负载会被拉高
2、返回这么多没有用的肯定响应,增加了开发或测试人员查看关键诊断数据的负担。
4、NRC
Negative Response Code,即否定响应码。

①NRC的概念
举个栗子理解NRC。
比如你去参加面试,面试结束就被拒了,结束时面试官告诉你说,你长的太帅了,公司不要这么帅的,这个“太帅了”就是一个否定原因。
对于诊断请求也是一样的,诊断请求如果被接收方否定了,接收方会返回一个否定原因,告诉请求方为什么否定这个诊断请求。
NRC的大小占1个Byte,不同的NRC代表不同的否定原因,举例如下:

这里要注意的是,大部分NRC的含义,在14229-1里面已经规定好了,比如,0x13,代表长度不正确。

(14229-1)
另外,各个诊断服务请求除了常见的NRC外(如长度错误NRC),还有些专门针对特定服务的NRC。
比如27安全访问,发送密钥错误超过n次(如3次),则需返回否定响应,其中NRC含义为发送密钥错误次数超过限制。
②NRC优先级
根据我们上面了解到的否定响应知识,否定响应的格式是固定的(共3个字节)。

(14229-1)
因此,当接收方返回否定响应时,如果有2个或2个以上的NRC,则只能有1个NRC返回。
于是,不同的NRC就有优先级之分,优先级高的先返回。
举个栗子,如下图:

这条10服务诊断请求有2个错误的地方(假设10服务的子服务0x04需求不要求实现)
①子服务不支持(NRC: 0x12):因为子服务为0x04,代码中并没有实现。
②数据长度不正确(NRC:0x13):10服务的诊断请求数据长度应该是0x02,但却发了个0x03。
但从图中可以看到,接收方只返回了长度错误NRC 0x13。
因此,这里的NRC13的优先级就高于NRC 0x12,只有当NRC13的错误解决,才会报出NRC 0x12。
关于常用NRC的优先级,14229-1里面是有要求的。
如下图:

(14229-1)
我们只看Mandatory这部分。
可以看到,首先是NRC 0x11,即判断SID(服务)是否支持。
然后再是判断当前会话下是否支持该SID(服务)
即优先级:NRC 0x11 > NRC 0x7F
在判断完上面2个NRC后。
对于有子服务的诊断服务,14229-1中规定的NRC优先级如下:

(14229-1)
但是实际开发中,不同的项目对于NRC优先级的要求会有差异,项目需求不一定完全按照14229-1里面规定的来。
因此这种情况,软件工程师就需要根据项目需求去实现NRC优先级了。
结语
当使用Autosar工具链开发时,我们这里面讲的很多的内容Autosar静态代码实际上已经实现好了。
比如抑制肯定响应位、常用的NRC,以及14229-1里要求的的NRC优先级,这些内容都不需要软件工程师去实现。
软件工程师需要做的,是实现特殊的NRC以及实现项目需求的NRC优先级。
比如,执行某个诊断服务的条件是车速等于0,类似于这些条件则需要软件工程师手写代码去实现。
具体如何开发,我们在下篇文章进行讲解。
返回目录:
2668

被折叠的 条评论
为什么被折叠?



