CAN通信(二) :协议介绍

  CAN 协议经 ISO 标准化后有 ISO11898 标准和 ISO11519-2 标准两种。ISO11898 和 ISO11519-2 标准对于数据链路层的定义相同,但物理层不同。

   在阅读完上文后,对CAN总线中的一个极其重要的知识点需要搞明白:回读机制。
  指的是节点在向总线上发送报文的过程中,同时也对总线上的二进制位进行“回读”。通过这种机制,节点就可以判断出本节点发出的二进制位与总线上当前的二进制位是否一致。

1.1 帧的种类

帧类型帧用途
数据帧 用于发送单元向接收单元传送数据的帧。
遥控帧 用于接收单元向具有相同 ID 的发送单元请求数据的帧。
错误帧 用于当检测出错误时向其它单元通知错误的帧。
过载帧 用于接收单元通知其尚未做好接收准备的帧。
帧间隔 用于将数据帧及遥控帧与前面的帧分离开来的帧

  另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有 11 个位的标识符(Identifier: 以下称 ID),扩展格式有 29 个位的 ID。

1.1.1 数据帧

 数据帧标准格式各个位的介绍
 SOF:联系前文可知,当数据帧发出第一位时(0为显性电位),总线就由空闲状态转为传输状态,同一时间只能允许一个节点传输数据。
 Identify:接下来的仲裁段有11位,即本数据帧的 ID 信息,决定着数据帧发送的优先级,也决定着其它设备是否会接收这个数据帧,禁止高 7 位都为隐性(禁止设定:ID=1111111XXXX), ID 信息的作用:① 如果同时有多个节点发送数据时,作为优先级依据(仲裁机制);② 目标节点通过 ID 信息来接受数据(验收滤波技术)。这些将在下文提出。
 RTR:(Remote Transmission Request BIT) 位用于标识是否是远程帧(0,数据帧;1,远程帧),在数据帧里这一位为显性(逻辑 0)。
 IDE:(Identifier Extension Bit),是用于区分标准格式与扩展格式,在标准格式中 IDE 位为显性,在扩展格式里 IDE 位为隐性。
 r0:保留位,必须以显性电平发送。
 DLC:由 4 位组成,MSB 先行(高位先行),它的二进制编码用于表示本报文中的数据段含有多少个字节,DLC 段表示的数字为0到8,若接收方接收到 9~15 的时候并不认为是错误。
 Data:数据帧的核心内容,它由 0~8 个字节(0 ~ 64位)组成,MSB 先行。
 CRC:该段用于检查帧传输错误,发送方以一定的方法计算包括:帧起始、仲裁段、控制段、数据段;接收方以同样的算法计算 CRC 值并进行比较,如果不同则会向发送端反馈出错信息,重新发送;计算和出错处理一般由 CAN 控制器硬件完成或由软件控制最大重发数。该段由 15 个位的 CRC 顺序和 1 个位的 CRC 界定符(用于分隔的位)组成,它为隐性位,主要作用是把CRC 校验码与后面的 ACK 段间隔起来。
 ACK:由 ACK 槽(ACK Slot)和 ACK 界定符 2 个位组成,在 ACK 槽位中,发送端发送的为隐性位,而接收端则在这一位中发送显性位以示应答。在 ACK 槽和帧结束之间由 ACK 界定符间隔开,为隐性位。(发送 ACK/返回 ACK这个过程使用到回读机制,即发送方先在 ACK 槽发送隐性位后,回读到的总线上的电平为显性0,发送方才知道它发送成功了,不用重发)
 EOF:由发送端发送 7 个隐性位表示结束。

在数据帧的拓展格式中,与标准格式不同处在于:

仲裁段为 29 位;
多出的SRR 位(Substitute Remote Request BIT),用于替代标准格式中的 RTR 位。SRR 位为隐性位,由于 RTR 在数据帧为显性位,所以在两个 ID 相同的标准格式报文与扩展格式报文中,标准格式的优先级较高;
控制段中的 r1 和 r0 一样都为保留位,默认设置为显性位;
扩展格式的 ID 有 29 个位。基本 ID 从 ID28 到 ID18,扩展 ID 由 ID17 到 ID0 表示。基本 ID 和标准格式的 ID 相同。禁止高 7 位都为隐性。(禁止设定:基本 ID=1111111XXXX)

1.1.2 遥控帧

  接收单元向发送单元请求发送数据所用的帧。遥控帧由 6 个段组成。遥控帧没有数据帧的数据段。举个例子,车钥匙需要知道车门的状态,一个远程帧过去,车门把自己的状态发回来了。

 

  遥控帧与数据帧的不同之处:

  • 遥控帧的 RTR 位为隐性位,没有数据段;
  • 没有数据段的数据帧和遥控帧可通过 RTR 位区别开来;
  • 遥控帧的数据长度码以所请求数据帧的数据长度码表示;

1.1.3 错误帧

  用于在接收和发送消息时检测出错误通知错误的帧。错误帧由错误标志和错误界定符构成。

 

 (1) 错误标志
  错误标志包括主动错误标志和被动错误标志两种。
    ① 主动错误标志:6 个位的显性位。
    ② 被动错误标志:6 个位的隐性位。
 (2) 错误界定符
  错误界定符由 8 个位的隐性位构成。

 (3)错误标志之后还有0~6个错误标志重叠部分
  处于主动错误状态的节点检测到错误时会发送主动错误标志,6个连续显性位会违反位填充规则和位场的固定形式,进而造成其它节点也检测到错误并发送错误标志。所有节点所发送的显性序列叠加组成错误标志重叠部分,错误标志重叠部分的长度在6-12个显性位之间。

对主动错误和被动错误的通俗理解:
 
  首先建议把广泛使用的“主动错误”和“被动错误”概念换成“主动报错”和“被动报错”。
 
  1.主动报错站点
  只要检查到错误,它立即“主动地”发出错标识。所谓“出错标识“,它本身就是一个“错误的位序列”(连续的6 个显性位,不满足CAN协议的“最多5个连续的同性位”要求),
目的是“主动地”告诉大家:即使你们没有发现“刚才我已发现”的错误,现在我“以身作则”出错啦
!你们该看到这个错误了吧!     2.被动报错站点   如果检查到错误,它只能干瞪眼“被动地”等别人(主动报错站点)报错,等待的时候它可不能去动总线,直到识别出由主动报错站点发出的“错误的位序列”,
它才松了一口气:有人正式报错了
!然后他就可以去竞争总线,该干啥干啥。

1.1.4 过载帧

  过载帧是接收节点向总线上其它节点报告自身接收能力达到极限的帧,可以理解为:接收节点Node_A接收报文的能力达到极限了,于是Node_A就会发出过载帧来告诉总线上的其它节点(包括发送节点),我接收节点Node_A已经没有能力处理你们发来的报文了。过载帧由过载标志和过载界定符构成。

   (1) 过载标志
  6 个位的显性位。
  过载标志的构成与主动错误标志的构成相同。
 (2) 过载界定符
  8 个位的隐性位。
  过载界定符的构成与错误界定符的构成相同。

1.1.5 帧间隔

  帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。过载帧和错误帧前不能插入帧间隔。

 

 

(1) 间隔
  3 个位的隐性位。
(2) 总线空闲
  隐性电平,无长度限制(0 亦可)。
  本状态下,可视为总线空闲,要发送的单元可开始访问总线。
 (3) 延迟传送(发送暂时停止)
  8 个位的隐性位。
  只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。

1.2 位填充

  为防止突发错误而设定,CAN协议中规定,当相同极性的电平持续五位时,则添加一个极性相反的位。填充位的添加和删除是由发送节点和接收节点完成的,CAN-BUS只负责传输,不会操纵信号。

 

对于发送节点而言:
在发送数据帧和遥控帧时,对于SOF~CRC(除去CRC界定符) 之间的位流,相同极性的电平如果持续5位,那么在下一个位插入一个与之前5位反型的电平;
对于接收节点而言:
在接收数据帧和遥控帧时,对于SOF~CRC(除去CRC界定符)之间的位流,相同极性的电平如果持续5位,那么需要删除下一位再接收。如果这个第 6 个位的电平与前 5 位相同,将被视为错误并发送错误帧

1.3 错误的种类

 

  位错误(Bit Check Error):节点将自己发送到总线上的电平与同时从总线上回读到的电平进行比较,如果发现二者不一致,那么这个节点就会检测出一个位错误。

有三种例外情况不属于位错误:

  ① 在仲裁区,节点向总线发送隐性位却回读到显性位,不认为是位错误,这种情况表示该节点仲裁失败;

  ② 在ACK槽,节点向总线发送隐性位却回读到显性位,不认为是位错误,这种情况表示,该节点当前发送的这一帧报文至少被一个其它节点正确接收;

  ③ 该节点发送被动错误标志,节点Node_A向总线发送连续六个隐性位(被动错误标志)却回读到显性位,不认为是位错误。因为被动错误标志是六个连续的隐性位,所以在总线上按照线与机制,有可能这六个连续隐性位被其它节点发送的显性电平“吃掉”;

ACK错误(Acknowledgment Error):按照CAN协议的规定,在一帧报文(数据帧或者遥控帧)发出之后,如果接收节点Node_B成功接收了该帧报文,那么接收节点Node_B就要在该帧报文ACK槽对应的时间段内向总线上发送一个显性位来应答发送节点Node_A。这样发送节点Node_A就会在ACK槽时间段内从总线上回读到一个显性位。

  当发送节点Node_A在ACK槽时间段内没有回读到显性位,那么发送节点Node_A就会检测到一个ACK应答错误。这表示没有一个节点成功接收该帧报文。

填充错误(Fill Error):帧起始到CRC之间,接收节点检测到有6个连续相同的位电平时,也就是违反5位相同位插入1位相反位的“位填充”原则。

 CRC错误:发送节点Node_A在发送数据帧或者遥控帧时,会计算出该帧报文的CRC序列。接收节点Node_B在接收报文时也会执行相同的CRC算法,如果接收节点Node_B计算出的CRC序列值与发送节点Node_A发来的CRC序列值不一致,那么接收节点就检测到一个CRC错误。

格式错误:在一帧报文发送时,如果在必须发送预定值的区域内检测到了非法值,即与任何一种帧格式都不符;CAN报文中,有预定值的区域包括:

  • 数据帧和遥控帧的CRC界定符、ACK界定符、EOF;
  • 错误帧界定符
  • 过载帧界定符

1.4 错误通知

1.4.1 节点错误状态

对于错误界定,节点存在如下三种状态:

主动错误: 错误标志由6个连续的显性位组成(这种连续的6个显性位与常规的填充位和其它帧固定格式不相同,正因为如此,硬件才容易区别)

被动错误 :被动错误标志由6个连续的隐性位组成,当发送结束后,处于被动错误状态的节点在下一次再次发送时之前需要等待一些额外时间。

总线关闭: 处于总线关闭状态的节点不允许发送和接收任何形式的帧报文。且只能通过用户请求进行恢复。

1.4.2 错误状态的转换

  一个CAN节点在什么情况下处于主动错误状态,什么情况下处于被动错误状态呢?

  在CAN节点内,有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)

  错误界定并非是依据错误的类型去界定CAN节点的错误状态,而是依据错误计数器【TEC/REC】的值来界定CAN节点的错误状态;当该节点检测到错误后,内部REC/TEC计数器会相应的增加,基于REC/TEC的值判定节点状态。

 

  需要注意的是:这两个计数器计得不是收发报文的数量,也不是收发错误帧的数量。TEC和RCE计数值的变化,是根据下表的规定来进行的。

 

  节点错误状态的转换就是一个 “量变”到“质变” 的过程:

 

主动错误状态:【REC<127 且TEC<127】
  初步可判定该节点相对稳定可靠,该错误计数很可能是由于某个节点异常导致的,那么其他节点很可能也会触发该错误,那么允许该节点破坏CAN总线的异常报文并告知其他节点;
  节点检测到一个错误就会发送带有主动错误标志的错误帧,因为主动错误标志是连续六个显性位,所以这个时候主动错误标志将会“覆盖”掉总线上其它节点的发送,而之前在CAN总线上传输的报文就被这“六个连续显性位”破坏掉了。

  如果发出主动错误帧的节点是发送节点,这个情况下就相当于:刚刚发送的那一帧报文我发错了,现在我破坏掉它(发送主动错误帧),你们不管收到什么都不算数;
  
  如果发出主动错误帧的节点是接收节点,这个情况就相当于:刚刚我收报文的时候发现了错误,不管你们有没有发现这个错误,我现在主动站出来告诉大家这个错误,并把这一帧报文破坏掉(发送主动错误帧),刚才你们收到的东西不管对错都不算数了。

被动错误状态:【REC>128 或TEC>128】
  节点发送错误帧的次数较多,初步可判定该节点相对不可靠,该错误计数很可能是由于自身节点问题导致,即该错误很可能仅有该节点才有,对于其他节点而言是可以正常交互的,总线不信任该节点提供的错误标识,将不允许破坏总线数据,那么允许该节点发送错误帧“6个连续隐性位”至CAN总线,仅告知其他节点异常;

  如果发出被动错误帧的节点为报文的发送节点,那么在发送被动错误帧之后,刚刚正在发送的报文被破坏,并且该节点不能在错误帧之后随着连续发送刚刚发送失败的那个报文。随之而来的是帧间隔,并且连带着8位隐性位的 “延迟传送” 段;这样总线电平就呈现出连续11位隐性位,总线上的其它节点就能判定总线处于空闲状态,就能参与总线竞争。
  
  此时如果该节点能够竞争成功,那么它就能接着发送,如果竞争不能成功,那么就接着等待下一次竞争。这种机制的目的正是为了让其它正常节点(处于主动错误)优先使用总线。

总线关闭状态:【TEC>255】
  一个处于被动错误状态的节点,仍然多次发送被动错误帧,使该节点转为总线关闭态;
  该节点不能向总线上发送报文,也不能从总线上接收报文,整个节点脱离总线。等到检测到128次11个连续的隐性位时,TEC和REC置0,重新回到主动错误状态。

由于存在实现方式的不同,CAN总线关闭状态存在只允许用户请求恢复和检测到128个11位连续的隐性位时自恢复两种不同的恢复形式。

  如果总线上只有一个节点,该节点发送数据帧后得不到应答,TEC最大只能计数到128,即这种情况下节点只会进入被动错误状态而不会进入总线关闭状态。

 

1.4.3 错误帧的发送

 按照CAN协议的规定:
  发生位错误、填充错误、格式错误、ACK错误时,则在错误产生的那一位的下一位开始发送错误帧。
  发生CRC错误时,紧随ACK界定符后的位发送错误帧。

  错误帧发送完成后,总线空闲时自动重发出错的数据帧。

 

1.4.4 仲裁机制与位时序

仲裁存在于当同时有多个节点竞争总线发送权时,关键词是同时,比如节点1和节点2两者同时向总线发送一个位,是同时发送的,总线只是导线(理解成自带线与功能),如果节点1发送的是1,节点2发送的是0,线与后总线的状态则为0;  与此同时,这里运用到回读机制,即:节点发送位的同时会回读总线的状态并与自身相比较,可知节点1本身状态与总线状态一致,则节点1仲裁胜利。(可查阅【CAN通信(一) 3.2.3】)

  理解位时序,重点在于同步,分为硬同步和重新同步,在重新同步中,通过设置SJW来调整PBS段的长度(PBS1增长,PBS2缩短),以达到调整一个位中Tq的个数,即长度。(可查阅【CAN通信(一) 3.2.4】)

 关于波特率的计算:
  总线上的各个通讯节点只要约定好 1 个 Tq 的时间长度以及每一个数据位占据多少个Tq,就可以确定 CAN 通讯的波特率。例如,假设1Tq=1us,而每个数据位由 19 个 Tq 组成,则传输一位数据需要时间 T(1bit) =19us,从而每秒可以传输的数据位个数为:1x10^6/19 = 52631.6 (bps),这个每秒可传输的数据位的个数即为通讯中的波特率。

1.4.5 举个栗子

 【位错误】举例(情况1):

  • 设总线上所有节点处于主动错误状态;
  • 当一个发送节点监控到总线上的位数值与发送的位数值不一致时,检测为位错误,并发送主动错误标志(6个连续的显性位);
  • 接收节点接收到发送节点发送的6个连续的显性位时,会检测为位填充错误,也会发送主动错误标志;
  • 发送节点发送完主动错误标志后,开始监控总线是否为隐性位,当总线为隐性位时,开始发送错误界定符(8个连续的隐性位);
  • 当接收节点发送完主动错误标志后,开始向总线发送错误界定符; 等待错误帧发送完成,总线空闲后,发送节点重新发送出错的报文.
由于发送节点发送6个连续的显性位会破坏位填充规则,触发接收节点发送主动错误标志,发送节点和接收节点的结合是形成错误标志叠加部分的原因。

 

 【位错误】举例(情况2):

 
  • 假设发送节点处于被动错误状态,接收节点处于主动错误状态;
  • 当发送节点监控到总线上的位数值与发送的位数值不一致时,检测为位错误,并发送被动错误标志(6个连续的隐性位);
  • 接收节点接收到发送节点发送的6个连续的隐性位时,会检测为位填充错误,并会发送主动错误标志;
  • 发送节点发送完被动错误标志后,开始监控总线是否为隐性位,当总线为隐性位时,开始发送错误界定符(8个连续的隐性位);
  • 接收节点发送完主动错误标志后,开始监控总线是否为隐性位,当总线为隐性位时,开始发送错误界定符(8个连续的隐性位);

 

1.5 CAN的特性总结

1) 多主控制
  在总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元同时开始发送消息时,根据标识符(Identifier 以下称为 ID)决定优先级。ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息 ID 的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。

 2) 系统的柔软性
  与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。

 3) 通信速度较快,通信距离远。最高 1Mbps(距离小于 40M),最远可达 10KM(速率低于 5Kbps)。

 4) 具有错误检测、错误通知和错误恢复功能。所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。

 5) 故障封闭功能。CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。

 6) 连接节点多。CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。

posted @ 2023-06-08 15:50  码好每一天  阅读(203)  评论(0编辑  收藏  举报