3.1数据帧和遥控帧
数据帧和遥控帧都有标准格式和扩展格式,这2种格式都具有相同的帧结构。
数据帧由7个段构成,遥控帧由6个段构成。先看数据帧:
图13 数据帧结构及其两种格式(引自[4])
引自[6]
这里结合实际采集的CAN总线电压信号来看下标准格式的数据帧。
图14 标准(格式)数据帧的CAN总线电压(引自[5])
再看遥控帧(也叫远程帧):
图15 遥控帧的两种格式(引自[4])
通过图13和15对比数据帧和遥控帧有:
通过对数据帧和遥控帧有了基本认识,下面我们再具体了解下每个段。
1) 帧起始(SOF, Start of Frame)
表示帧开始的段,1个位的显性位。(总线空闲时为隐性位,故帧起始以显性位非常好识别),对于数据帧和遥控帧的标准/扩展格式均如此。
引自[4]
2) 仲裁段(Arbitration field)
表示数据的优先级的段,起作用就是根据报文ID来确定其发送优先级。标准格式和扩展格式在此的构成有所不同。
引自[4]
这里对比数据帧与遥控帧各自的两个格式,其不同为:
针对上表的这种设计,后面会具体分析其在仲裁过程的作用。
3) 控制段(Control field)
表述数据段的字节数,由6个位构成,标准格式和扩展格式的构成有所不同。
引自[4]
图16 控制段与数据段的关系(引自[5])
4) 数据段(Data Field)
数据段可包含0-8个字节的数据,从MSB(最高位)开始输出。遥控帧没有此段。
引自[4]
5) CRC段(Cyclic Redundancy Check Field)
检查帧传输错误的帧,由15个位的CRC顺序和1个位的CRC界定符(用于分隔位)构成。CRC界定符恒为隐性。
引自[4]
这里CRC顺序是根据多项式生成的CRC值,CRC的计算范围包括帧起始,仲裁段,控制段和数据段。
图17 CRC序列计算方法
附2:en.wikipedia.org/wiki/C , 如何通俗的理解CRC校验并用C语言实现, zhuanlan.zhihu.com/p/77
6) ACK段(Acknowledge Field)
用来确认是否正常接收。由ACK槽(ACK Slot)和ACK界定符2个位构成。
引自[4]
图18 发送与接收时的ACK槽状态(引自[3])
7) 帧结束(End of Frame)
表示该帧的结束的段。由7个位的隐性位构成。
引自[4]
3.2 错误帧
用于在接收和发送消息时检测出错误通知错误的帧,错误帧由错误标志和错误界定符构成。
图19 错误帧结构(引自[4])
上图的错误标志包括主动错误标志(6个位的显性位)和被动错误标志(6个位的隐性位)两种。主动错误标志处于主动错误状态下的单元检测出错误时输出的错误标志。被动错误标志处于被动错误状态的单元检测出错误时输出的错误标志。错误界定符由8个位的隐性位构成。
注意上图0~6位的错误标志重叠,这段怎么确定呢?需先介绍2个概念:位填充和错误类型。
1)位填充(Bit Stuffing)
位填充是为防止突发错误而设定的功能。当同样的电平持续5位则添加一个位的反型数据位:
图20 位填充示意(引自[4])
注意:位填充作用范围为SOF-CRC段机间的数据。
2)错误类型
引自[4]
图21 CRC匹配示意(引自[6])
图22 CRC错误(引自[6])
针对上述 位错误再做说明(引自[3]):所谓“发出的电平与从总线上回读的电平不一致”,指的就是 节点向总线发出隐性位,却从总线上回读到显性位或者 节点向总线发出显性位,却从总线上回读到隐性位这两种情况。有三种例外情况不属于位错误:在仲裁区,节点向总线发送隐性位却回读到显性位,不认为是位错误,这种情况表示该节点仲裁失败;在ACK槽,节点向总线发送隐性位却回读到显性位,不认为是位错误,这种情况表示,该节点当前发送的这一帧报文至少被一个其它节点正确接收;一个节点发送被动错误标志,该节点向总线发送连续六个隐性位(被动错误标志)却回读到显性位,不认为是位错误。因为被动错误标志是六个连续的隐性位,所以在总线上按照线与机制,有可能这六个连续隐性位被其它节点发送的显性电平覆盖。
3)错误处理
错误状态的种类有:主动错误状态,被动错误状态和总线关闭态3种状态。单元始终处于3种状态之一。
(1)主动错误状态:可以正常参加总线通信的状态,处于主动错误状态的单元检测出错误时,输出主动错误标志。
(2)被动错误状态:是易引起错误的状态。处于被动错误状态的单元虽能参加总线通信,但为不妨碍其他单元通信,接收时不能积极地发送错误通知;处于被动错误状态的单元即使检测出错误,而其它处于主动错误状态的单元如果没发现错误,整个总线也被认为是没有错误的。处于被动错误状态的单元检测出错误时,输出被动错误标志。另外,处于被动错误状态的单元在不能马上再次开始发送。在开始下次发送前,在间隔帧期间内必须插入“延迟传送”(8个位的隐性位)。
(3)总线关闭态是不能参加总线上通信的状态。信息的接收和发送均被禁止。
以上这些状态依靠发送错误计算和接收错误计数来管理,根据计数值决定进入何种状态。错误状态和计数值的关系如下表:
图23 单元的错误状态(引自[4])
发送错误计数值和接收错误计数值根据一定的条件发送变化。错误计数值的变动条件如下表,一次数据的接收和发送可能同时满足多个条件。错误计数器在错误标志的第一个位出现的时间点上开始计数。
引自[4]
4)错误帧发送
检查到错误后,什么时候发送错误帧呢?按照CAN协议的规定:
- 位错误、填充错误、格式错误、ACK错误。在错误产生的那一位的下一位开始发送错误帧。
- CRC错误。紧随ACK界定符后的位发送错误帧。
具体来看一个例子:
图24 错误帧(引自[3])
- 1)发送节点Node_A发送一个显性位,但是却从总线上听到一个隐形位,于是Node_A节点就会检测到一个位错误;
- 2)Node_A检测到位错误之后,立即在下一位开始发送主动错误帧:6个连续显性位的主动错误标志+8个连续隐性位的错误界定符;
- 3)对应Node_A发出的主动错误标志,总线上电平为6个连续显性位;
- 4)接收节点Node_B和Node_C从总线上听到连续6个显性位,那么就会检测到一个填充错误,于是这两个节点都会发送主动错误帧;
- 5)对应Node_B和Node_C发出的主动错误标志,总线电平又有6个连续显性电平,对应Node_B和Node_C发出的错误界定符,总线电平有8个连续的隐性电平。
- 6)在间歇场之后,Node_A节点重新发送刚刚出错的报文。
在了解了错误帧的发送后,回到之前提到错误标志重叠部分是怎样形成的,再看一个例子:
图25 (引自[3])
在这个例子,我们知道位错误的错误标志与填充错误的错误标志重叠2位,剩下部分还有4位:
引自[4]