前言
本系列can通信分享内容是对互联网上各种介绍can通信文章的整理,可以让读者更系统的了解can通信。参考的文章见文末。
can的报文种类及结构
CAN一共规定了5中类型的帧,帧也称为报文。
帧 | 帧用途 |
数据帧(Data Frame) | 用于发送单元向接收单元传输数据的帧 |
远程帧(Remote Frame) | 用于接收单元向具有相同ID的发送单元请求数据的帧 |
错误帧(Error Frame) | 用于检测当出错误时,向其他单元出错误的帧 |
超载帧(Overload Frame) | 用于接收单元通知其尚未做好接收准备的帧 |
帧间隔(Inter Frame Space) | 用于将数据帧及遥控帧与前面的帧分离开的帧 |
数据帧
数据帧在CAN通信中最主要,也最复杂。数据帧以一个显性位(逻辑0)开始,以7个连续的隐性位(逻辑1)结束。CAN总线的数据帧有标准格式(Standard Format)和扩展格式(Extended Format)的区分。
数据帧可以分为七段:
-
帧起始(SOF)
标识一个数据帧的开始,固定一个显性位。用于同步, 总线空闲期间的任何隐性到显性的跳变都将引起节点进行硬同步。只有总线在空闲期间节点才能够发送SOF。
-
仲裁段(Arbitration Field)
仲裁段的内容主要为本数据帧的ID信息。数据帧分为标准格式和扩展格式两种,区别就在于ID信息的长度:标准格式的ID为11位;扩展格式为29位。在CAN协议中,ID决定着数据帧发送的优先级,也决定着其他设备是否会接收这个数据帧。仲裁段除了报文ID外,还有RTR, IDE, SRR位。
CAN总线通信原理可简单描述为多路载波侦听+基于消息优先级的冲突检测和非破坏性的仲裁机制(CSMA/CD+AMP)。CSMA(Carrie Sense Multiple Access)指的是所有节点必须都等到总线处于空闲状态时才能往总线上发送消息;CD+AMP(Collision Detection + Arbitration on Message Priority)指的是如果多个节点往总线上发送消息时,具备最高优先级的消息获得总线。
多路载波侦听:网络上所有节点以多点接入的方式连接在同一根总线上,且发送数据是广播式的。网络上各个节点在发送数据前都要检测总线上是否有数据传输:若网络上有数据,暂时不发送数据,等待网络空闲时再发;若网络上无数据,立即发送已经准备好的数据。
冲突检测:节点在发送数据时,要不停的检测发送的数据,确定是否与其他节点数据发送冲突,如果有冲突,则保证优先级高的报文先发送。
非破坏性仲裁机制:通过ID仲裁,ID数值越小,报文优先级越高。
在CAN总线上发送的每一条报文都具有唯一的一个11位或29位数字的ID,当节点同时发送报文时CAN总线将按”线与“机制对ID的每一位进行判断,当有一个节点发送0则总线的状态就是0,所以ID的值越小优先级就越高,这也是为什么在整车上越重要的报文ID值越小。
如下图节点A,B,C同时发送报文,依次对比ID的每一位,节点C的ID值最小,最终取得了CAN总线的控制权。
发送低优先级报文的节点退出仲裁后,在下次总线空闲时自动重发报文。高优先级的报文不能中断低优先级报文的发送。
报文接收过滤:CAN控制器大多具有根据ID过滤报文的功能,即只接收某些ID的报文。节点对接收到的报文进行过滤:比较消息ID与选择器(Accepter)中和接受过滤相关位是否相同。如果相同,接收;如果不相同,则过滤。 -
控制段
在控制段,r1(reserved1)和r0(reserved0)为保留位,默认设置为显性位。最主要的是DLC(Data Length Code)段,它是用二进制编码表示本报文中的数据段包含多少个字节。DLC段由4位组成,DLC3−DLC0,表示的数字范围为0-8。
-
数据段
数据帧的核心内容,有0-8个字节长度,由DLC确定。 -
CRC段
为了保证报文的正确传输,CAN的报文包含了一段15位的CRC校验码,一旦接收端计算出的CRC码跟接收到的CRC码不同,就会向发送端反馈出错信息以及重新发送。CRC部分的计算和出错处理一般由CAN控制器硬件完成,或由软件控制最大重发数。
在CRC校验码之后,有一个CRC界定符,它为隐性位,主要作用是把CRC校验码与后面的ACK段隔开。
-
ACK段
包含确认位(ACK slot)和界定符(Delimiter, DEL)。ACK在发送节点发送时,为隐性位。当接收节点正确接收到报文时,对其用显性位覆盖。DEL界定符同样为隐性位,用于隔开。
-
帧结束段(End-of-Frame, EOF)
帧结束段由发送端发送7个隐性位表示结束。
同步
-
位时序
Time Quantum 时间份额tQ :CAN控制器工作的最小时间单位,通常对系统时钟分频得到。
波特率:单位时间内(1s)传输的数据位,公式:1/位时间。举个栗子,系统时钟频率36MHz,预分频因子为4,则CAN时钟频率9MHz,则Tq=1/9M。假设一个CAN位包含10个Tq,则一个位周期T=10Tq,从而波特率为1/T=0.9MHz.
为了实现位同步,CAN协议把每一位的时序分解成下图所示的四段。这四段的长度加起来即为一个CAN数据位的长度。一个完整的位由8-25个Tq组成。
-
同步段(SS,Synchronization Segment)
一个位的输出从同步段开始。若总线的跳变沿被包含在SS段的范围之内,则表示节点与总线的时序同步。节点与总线同步时,采样点采集到的总线电平即可被确定为该电平的电位。SS段的大小为1Tq. -
传播段(PTS,Propagation Time Segment)
用于补偿信号在网络和节点传播的物理延时时间,是总线上输入比较器延时和输出驱动器延时总和的两倍。通常1-8Tq。 -
相位缓冲段1(PBS1, Phase Buffer Segment 1)
主要用于补偿边沿阶段的误差,其时间长度在重新同步时可以加长。初始大小1-8Tq. -
相位缓冲段2(PBS2,Phase Buffer Segment 2)
也是用于补偿边沿阶段的误差,其时间长度在重新同步时可以缩短。初始大小2-8Tq.
CAN同步分为硬同步和重新同步。
-
同步规则
- 一个位时间内只允许一种同步方式
- 任何一个“隐性”到“显性”的跳变都可用于同步
- 硬同步发生在SOF阶段,所有接收节点调整各自当前位的同步段,使其位于发送的SOF位内。
- 重新同步发生在一个帧的其他阶段,即当跳变沿落在同步段之外。
-
硬同步
当总线上出现帧起始信号(SOF,即隐性到显性的边沿)时,其他节点的控制器根据总线上的这个下降沿对自己的位时序进行调整,把该下降沿包含到SS段内。这样根据起始帧来进行的同步称为硬同步。
可以看到在总线出现帧起始信号时,该节点原来的位时序与总线时序不同步,因而这个状态的采样点采集到的数据是不正确的。所以节点以硬同步的方式调整,把自己的位时序中的SS段平移至总线出现下降沿的部分,获得同步,这时采样点采集到的数据是正确数据。
-
重新同步
因为硬同步时只是在有帧起始信号时起作用,无法确保后续一连串的位时序都是同步的,所以CAN引入了重新同步的方式。在检测到总线上的时序与节点使用的时序有相位差时(即总线上的跳变沿不在节点时序的SS段范围),通过延长PBS1段或缩短PBS2段来获得同步,这样的方式称为重新同步。
分两种情况:
第一种, 节点从总线的边沿跳变中,检测到它的时序比总线的时序相对滞后2个Tq,这是控制器在下一个时序中的PBS1段增加2Tq的时间长度,使得节点与总线时序重新同步。
第二种,节点从总线的边沿跳变中,检测到它的时序相对超前2Tq,这时控制器在前一个位时序中的PBS2段减少2Tq的时间长度,获得同步。
在重新同步的时候,PBS1和PBS2段的允许加长或缩短的时间长度定义为,重新同步补偿宽度(SJW,reSynchronization Jump Width)。这里设置的PBS1和PBS2能够增减的最大时间长度SJW=2Tq,若SJW设置的太小则重新同步的调整速度慢,若太大,则影响传输速率。
远程帧
向其他节点请求发送具有同一标识符的数据帧,远程帧没有数据场,且RTR位为隐性电平。
错误帧
当节点监测到一个或多个由CAN标准所定义的错误时,就会产生一个错误帧。错误帧由错误标志和错误界定符两个部分组成。
错误标志分为主动错误标志和被动错误标志:主动错误标志由6个连续的显性位组成;被动错误标志由6个连续的隐性位组成,除非被其他节点的显性位覆盖;错误界定符由8个连续的隐性位组成。
节点的错误状态有三种,主动错误状态、被动错误状态、总线关闭状态。
主动错误状态:节点处于主动错误状态可以正常通信,处于主动错误状态的节点(可能是接收节点也可能是发送节点)在检测出错误时,发出主动错误标志。
被动错误状态:节点处于被动错误状态可以正常通信,处于被动错误状态的节点(可能是接收节点也可能是发送节点)在检测出错误时,发出被动错误标志。
总线关闭状态:节点处于总线关闭状态不能收发报文,只能一直等待,在满足一定条件时才能再次进入到主动错误状态正常收发报文。
根据CAN协议的规定,CAN节点内有两个计数器:发送错误计数器TEC和接收错误计数器REC,CAN节点就是根据这两个计数器值得大小来判断处于什么错误状态的。
-
当0<REC<=127且0<TEC<=127时,节点处于主动错误状态。在该状态下,节点检测到一个错误就会发送带有主动错误标志的错误帧,因为主动错误标志是连续六个显性位,所以这个时候主动错误标志将会覆盖总线上其他位信号,这样CAN总线上之前传输的报文就被这六个显性位破坏掉了。这就相当于发现错误的节点主动站出来告诉总线上其他节点,刚才的信号有问题,你们都不要接收处理,丢掉就好了。
-
如果某个节点发送错误帧次数较多,以至于REC>127或TEC>127,那么该节点就处于被动错误状态。在该状态下,节点检测到一个错误就会发送带有被动错误标志的错误帧,因为被动错误标志是连续六个隐性位,所以这个时候总线上传输的报文都不会受到该被动错误帧的影响,其他节点收发正常。
-
已经处于被动错误状态的节点,仍然多次发送被动错误帧,最终使得TEC>255,这样就进入总线关闭状态。在该状态下,节点无法收发报文,从总线上离线。只有等到检测到128次11个连续的隐性位时,TEC和TEC才会重新置0,节点回到主动错误状态。
CAN总线错误分类:
序号 | 错误类型 | 错误内容 |
1 | 位错误 | 发送的位值和总线监视的位值不符合时,监测到一个位错误。但在仲裁场的填充位或应答间隙发送一个隐性位时,有可能被显性覆盖,此时回读到显性不会被记为位错误。 |
2 | 填充错误 | 当出现6个连续相同的电平时,监测到1个填充错误。 |
3 | 形式错误 | 当一个固定形式的位域含有一个或多个非法位时,监测到一个形式错误。如CRC分隔符、ACK分隔符、帧结束、帧间隔中不允许出现显性位。 |
4 | 应答错误 | 在应答间隙所监测的位不为显性,则监测到一个应答错误。 |
5 | CRC错误 | 接收节点的CRC结果与发送节点的CRC结果不同,则监测到一个CRC错误。 |
CAN节点计数器如何计数:
序号 | 计数条件 | TEC计数值 | REC计数值 |
1 | 接收节点检测出错误时(发送错误标志或过载标志中检测出位错误时,接收错误计数值不累加) | - | +1 |
2 | 接收节点在发送完错误标志后检测到的第一个位为显性电平时。 | - | +8 |
3 | 发送节点在发送主动错误标志或过载标志时,检测出位错误。 | +8 | - |
4 | 接收节点在发送主动错误标志或过载标志时,检测出位错误。 | - | +8 |
5 | 各节点从主动错误标志、过载标志的最开始检测出连续14个显性位时,之后每检测出连续8个显性位 | +8 | +8 |
6 | 检测出在被动错误标志后追加的连续8个显性位时 | +8 | +8 |
7 | 发送节点正常发送数据结束时 | -1,若TEC=0则不变 | - |
8 | 接收节点正常接收数据结束时 | - | 1<=REC<127时-1,REC=0时不变,REC>127时REC=127 |
9 | 处于总线关闭状态的节点,检测到128次连续11个位的隐性位 | TEC=0 | REC=0 |
超载帧
超载帧用于在先前和后续的数据帧(或远程帧)之间提供一附加延时,超载标志由6个显性位组成,超载界定符由8个连续的隐性位组成。
参考
参考文献 |
---|
https://zhuanlan.zhihu.com/p/32262127 |
https://zhuanlan.zhihu.com/p/346696648 |