1:经典CAN帧中的DLC
CAN诊断帧大家都是比较清楚的,一般设置一个常数=DLC。通常DLC=8。如果手动设置一个诊断帧DLC=7,即是PDU数据没有错误,ECU也是不响应的
数据如下,假设诊断请求ID的诊断ID=0x71B,DLC=7。诊断回复ID=0x72B,ECU也不会响应的
如果PDU的长度超过了7Byte,则会使用首诊(SF+CF)的组合,关于首诊,续帧,PCI(协议控制信息大家可自行参考ISO15765-2)
2:CANFD帧的诊断如何实现
2.1:CANFD帧的结构
当我们使用CANFD诊断时,一个很现实的问题就是如何选择CANFD帧的DLC,我们知道CANFD的DLC是可变的。这就带来了以下两个问题
1:CANFD诊断帧要如何决定,DLC的长度
2:CANFD的最长长度为是64,传统CAN诊断帧_(单帧)是以数据段的首个Byte0的低四位,这就带来另外一个问题,如果CANFD采用经典CAN的标准帧格式,就会导致4个bit位,不够用。
这事又有同学问了,CAN_FD帧的DLC不也4个bit,难道CAN_FD的SF的单帧不能采用这种方式表示N_PDU的数据长度?
那这就是有所只有所不知了,因为PCI中的低四位,诊断数据的长度判定就是根据PCI中的数据长度判定的。如果CAN_FD也采用Byte0的低4bit,且编码规则和CANFD帧的DLC保持一致,则会导致诊断读入大量的无效Byte。
所以存在以下规则(注意:此段规则是我根据项目经验总结而来),并不是具有强制性(我暂时还不知道,最新版本的ISO15765-2是否收录此规则)
首先看CANFD单帧 (SF)
1:从上图1/2行可以看出,CANFD帧的SF,PCI有两种格式,DLC<=8时,Byte1的低4bit表示N_PDU的长度
2:DLC>8时则采用Byte2字节表示N_PDU,长度,Byte1字节全部置0,。Byte2字节=十进制255,而CANFD单帧,最大则是64。也就是说Byte2最大值=64-1=63=0x3F。如果Byte2的长度>63>0x3F也就代表着此诊断帧是无效的,ECU不会响应。
再看CANFD首诊(FF)
这里又分为两种情况
1:N_PDU<=4095的情况,PCI的格式和CAN一样
2:N_PDU>4095的情况,Byte1和Byte2都=0,Byte3-Byte7用来表示N_PDU的数据长度最大能表示
4,294,967,295,也就是42亿个字节的数据,可以看到是非常大的。
续帧(CF)和流控(FC)的PCI和CAN帧是一样的
2.2:CAN诊断和CANFD诊断的自适应性
根据N_PDU的长度自适应选择SF
本文一开头我说了,CAN诊断帧一般DLC统一设置为8。但是我说了是一般,如果收发器和控制器支持,也可以配置(软件开发阶段配置)为自适应DLC,比如 我们发送一个02 10 01 ,如果采取自适应则发送此PDU的帧DLC=03即可。
CANFD的自适应有点不一样
1)当CANFD的DLC<=8时,它的自适应和CAN一样
2)当CANFD的DLC>8时,它的自适应和CAN一样,DLC会根据N_PDU的最小长度,设置一个DLC
举个例子
N_PDU ={ 09 22 F1 97 F1 32 F1 45 F1 47},一口气读了三个DID,此时DLC只能=0x09,也就是CAN_FD帧=十进制13个Byte。
也就是自适应,会选择一个最小的DLC,这个DLC保证了能发送出一个完整的N_PDU。
2.3:自适应的优点和缺点
优点也很明显,就是能够有效的降低总线的负载。
缺点:还是以2.2中的 N_PDU ={ 09 22 F1 97 F1 32 F1 45 F1 47},一口气读了三个DID为例,实际项目中我发现一个小问题
就是此能用两种方法实现,一种则是采用CANFD单帧发送,一种则是以CANFD FF(DLC==8)帧发送,这两种方法均能实现。看是如何实现
71B (DLC==8)10 09 22 F1 97 F1 32 F1
72B(DLC=3-8均可) 30 00 00 AA AA AA AA(AA是填充字节,具体数量与FC的DLC相关)
71B (DLC=3-8均可) 45 F1 47 AA AA AA AA(AA是填充字节,具体数量与CF的DLC相关)
72B (DLC必须>0x08)09 62 F1 97 F1 32 F1 45 F1 47 AA(填充字节固定为一个AA)
注意看,我标红的描述,如果72B依然采用DLC=08来的话,就会导致71B还要发送一个流控帧,就会导致总线负载率很高,导致带宽的浪费。