前言
CANTP层(15765-2协议)存在的意义
普通CAN格式诊断帧类型详解
四种诊断报文类型
单帧SingleFrame(SF)
首帧:FirstFrame(FF)
流控帧:FlowControl(FC)
连续帧:ConsecutiveFrame(CF)
中间小结
CANFD格式诊断帧类型详解
差异点:单帧SingleFrame(SF)
差异点:首帧FirstFrame(FF)
结束
前言
我们先来看一下诊断报文数据Log:
上面图中,红色为诊断仪(Canoe或Canpro)发,蓝色为ECU发。
我刚开始接触诊断的时候。
看着这些密密麻麻的数据一脸茫然,由于经常能听到同事们在说19服务,所以我知道19服务读DTC,但Canoe发出的19 0A前面为啥还有个0x02?为什么ECU先返回了一帧然后再返回后面的多帧?为什么中间还夹这一帧Canoe发出来的?30 00 14又是啥意思?多帧的数据要怎么看啊,全部数据都是跟DTC故障有关吗?
真的是小小的脑袋大大的问号。
...
后来我才知道,这一切的由来都是15765-2协议。上面这个流程中,诊断仪和ECU间为什么是这样交互,所有数据中与诊断服务无关的其它数据分别代表什么意思,15765-2中全都有详细的定义。
CANTP层(15765-2协议)存在的意义
先看一下在Autosar架构中,CANTP层在诊断链路中的位置:
要理解为什么诊断报文的链路需要CANTP层(15765-2协议)。
我们可以先看一下普通应用报文的链路:
应用报文链路:CAN->CANIF->PDUR->COM->APP
你会发现,应用报文其实很简单。它没有什么协议,收到什么就直接解读就好了。
比如,车企定义了0x123报文中的Byte0的8个字节为电池的温度,那么当ECU收到0x123报文的时候,直接把Byte0的8个字节读取出来就直接是电池的温度了。换句话说,应用报文的发送和接收是没有什么协议的。
由于应用报文没有什么协议,因此,应用报文传输数据就完全受限制于物理层的CAN协议(11898),一帧CAN报文的长度最大是CANFD的64Byte,再多就不行了。
因此,15765-2协议的主要目的就是实现多帧传输。
普通CAN格式诊断帧类型详解
四种诊断报文类型
我们先来看一下诊断报文都有哪些类型:
这个图简单一眼看过去,初学者肯定不是那么好理解,所以我们提取一些关键信息来看。(先把普通CAN格式的诊断报文提取出来看一下,下图没框出来的就是CANFD格式的,后面再讲)
从上面图中红色框出来的地方可以看出。诊断报文的类型共有4种。分别叫做:
单帧:SingleFrame(SF)
首帧:FirstFrame(FF)
连续帧:ConsecutiveFrame(CF)
流控帧:FlowControl(FC)
我们暂时先不管他们具体的意义以及什么情况下才发出来。先从上面图中看看每种诊断报文的类型都有什么不同的地方。(注意,上面标准规范里面的图中的Byte#1是起始字节,对应我们口头常说的报文的Byte0起始字节。)
以下面这张图为栗子,接下来分别讲解各个帧类型的差异。再次注意,下面图中Tx表示诊断仪(Canpro或Canoe)发出去,Rx表示ECU接收到诊断仪请求后ECU返回的数据。
单帧SingleFrame(SF)
如下图:
另外说明,后面的无效数据“AA AA ...”叫做填充字节(具体我们后面再讲,现在只要知道它是无效数据就好了。
单帧:Byte#1的低4位填写要发送的有效数据长度(SF_DL),Byte#1的高4位固定为0。
首帧:FirstFrame(FF)
如下图:
这里它要发送23个Byte的有效数据,但很明显,这一帧里只跟着6个有效Byte。因此还剩下17个Byte的有效数据没发完,它后面要发的数据叫做连续帧。
首帧:Byte#1的高4位固定为1。Byte#1的低4位和Byte#2的8位共同填写要发送的诊断有效数据长度(SF_DL)。
流控帧:FlowControl(FC)
如果流控帧这一部分看不懂,大家可以先看下面的连续帧,然后再反回来看这里流控帧。因为所谓流控,就是控制连续帧的发送。
如下图:
下面我们依次讲解FS、BS、STmin这3个的含义
FS:FlowStatus,即流控状态。它只有3个值:
FS=0:允许对方继续发送
FS=1:等待
FS=2:溢出
一般来说,我们只会看到FS为0的状态。知道FS等于0表示能继续发送就好了。(其它两个值我到目前为止还没看到出现这种情况)
关于FS的官方标准如下(大家随便看看就好了):
BS:BlockSize,即允许对方一次发送连续帧的数量。
如果发送流控帧的这方发送的BS为0x00,则表示发送流控帧的这方可以接收无穷多的数据,对方只需要把所有要发送的数据全部发过来就好了。
比如下面这里:
我们另外再举一个BS不等于0x00的例子。如下面这里,BS=0x01,表示一次对方只能发送1帧数据过来:
关于BS的官方解释如下(大家也随便看看就好了):
STmin:SeparationTime minimum,即要求对方发送连续帧的最小时间间隔。
如下面这张图,STmin=0x0A,即10ms。也就是说,对方发送的连续帧每帧的时间间隔最小是10ms。
官方解释如下(也是随便看看就好了)
连续帧:ConsecutiveFrame(CF)
如下图:
Byte#1的低四位叫做SN。Byte#1的高4位固定为2。
SN:SequenceNumber,即当前连续帧的帧数。该值从0-15循环,但是第一帧连续帧的值是从1开始。
官方解释如下:
说人话其实就是,叫做SN的这4个Bit,发出第一帧连续帧的时候是1,如果连续帧的数据量很大,比如由上百个Byte,那么,当SN等于15之后的下一帧,就再从0开始,然后不断循环,并且中间不受流控帧的影响。
中间小结
看完上面普通CAN格式的诊断报文类型
我们另外再补充一个与协议无关的知识点:诊断仪与ECU的关系
在诊断交互中,诊断仪永远是主动方,ECU永远是被动方。
理解起来也很简单:ECU不可能能主动发数据给诊断仪说:“诊断仪,你快来读读我的DTC故障状态吧。诊断仪,你快来给我升级下软件吧...”。要是真这样,那真的是智能觉醒了。
所以,在诊断交互中,第一帧肯定是诊断仪发出去的。
好了,补充了这个知识点。我再贴一遍一开始那张密密麻麻数据的图
这次,虽然里面诊断服务的数据的具体含义你不理解,但是你是不是已经能看懂整个交互流程了?
讲完15765-2中普通CAN格式帧的诊断报文类型,我们接下来再看看CANFD格式帧的诊断报文类型。
虽然普通CAN和CANFD的诊断报文格式差异其实不大。
但是大家做Autosar诊断开发的时候,一定要知道诊断报文要有CANFD格式的。
我之前做CANFD格式的诊断报文的时候,我感觉明明已经完成了整个CANFD诊断报文的开发链路,但是我用CANoe发送诊断请求的时候,ECU死活没有反应,然后各种调试,最后才发现,原来CANFD格式的诊断报文跟CAN格式的诊断报文的发送数据内容是不一样的。
也就是说,对于CANFD诊断格式的ECU,如果你还用诊断仪按照普通CAN格式的方式发送诊断请求报文,ECU就不会响应你,这并不是ECU坏了或没开发对,而是你没按照人家的协议要求发数据。
这可真的坑死我了。
好了,话不多说,我们接下来看下CANFD格式的诊断报文类型。
从上面图中可以看到,CAN格式和CANFD格式的差异是SF(单帧)、FF(首帧)的差异,连续帧和流控帧是没有差异的。
关于CANFD格式的诊断报文类型就不详细讲了,只讲于普通CAN有差异地方对比。
再次说明:上面标准规范里面的图中的Byte#1是起始字节,对应我们口头常说的报文的Byte0起始字节。
差异点:单帧SingleFrame(SF)
普通CAN:Byte0的高4位固定为0,低4位表示有效数据长度
CANFD(DLC>8):Byte0的高4位、低4位都固定为0,Byte1表示有效数据长度
差异点:首帧FirstFrame(FF)
普通CAN:Byte0的高4位固定为1。Byte0低4位和Byte1的8位是一个整体,表示要发送的有效数据长度。
CANFD(DLC>8):Byte0的高4位固定为1、Byte0低4位和Byte1的8位固定为0、Byte2、3、4、5是一个整体,表示要发送的有效数据长度。
另外注意:如果是CANFD格式的诊断报文,但是诊断报文的长度小于等于8,则仍然是按照标准CAN的方式传输数据。也就是说,15765-2这里它不管你是CAN还是CANFD,只管诊断报文长度是否大于8。
结束
关于诊断报文CANTP层的存在意义和诊断报文的类型就讲到这里了,下一章我们讲一下诊断仪和ECU的交互流程中的帧类型使用情况