CAN协议简明总结及要点解析

之前总结的,趁有时间上传保存以下…
一、总体概述
1.1、基本概念
CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议。在北美和西欧,CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以 CAN 为底层协议专为大型货车和重工机械车辆设计的 J1939 协议。
比如下图中,每个部分的多个器件都挂载在CAN总线上(一个CAN总线上的所有器件通讯速率必须相同),各个部分再汇集到网关,由网关分配实现各个不同速率的部分之间通讯,这样就很方便轻松实现了对汽车整体电控部分的检测与控制。

1.2、通讯方式
CAN总线通信系统是串行通信的一种,要优于RS485总线,是目前比较常用的一种工业总线,如汽车的电气部分就采用CAN总线实现通信。
与I2C、SPI等具有时钟信号的同步通讯方式不同,CAN通讯并不是以时钟信号来进行同步的,它是一种异步半双工通讯。(同步即在同一个时钟驱动下数据通信,半双工即接受与发送不能同时进行)

1.3、CAN的协议即组成
CAN协议经过ISO标准化后有两个标准ISO11898标准和IS011519-2标准。其中ISO11898是针对通信速率为125Kbps~1Mbps的高速通信标准(闭环),而IS011519-2是针对通信速率为125Kbps以下的低速通信标准(开环)。
Kbps:总线的通信速率,指的是位速率,或称为比特率(和波特率不是一回事),表示的是:单位时间内,通信线路上传输的二进制位的数量,其基本单位是bps或b/s (bit per second)。
CAN的组成一般有两种方式:
1:CPU与CAN控制器集成到一起、再外接CAN收发器,如下图1.3.1所示;
2:CPU与CAN控制器分开的,使用的时候需要配置CAN接口电路,比较麻烦。

CAN收发器是用于TTL电平与差分电压信号相互转换的,TTL电平即单片机引脚直接提供的电平,逻辑0代表低电平,逻辑1代表高电平;而差分电压信号则为固定的电压值。

图1.3.1

二、通讯过程
以ISO11898 标准的高速、短距离闭环网络为例,总线最大长度为 40m,通信速度最高为 1Mbps。在 CAN 总线的起止端有一个120Ω的终端电阻,是用来来做阻抗匹配,以减少回波反射。

2.1、数据传输原理实现

图2.1.1
由上图2.1.1可知,CAN通信是通过两根线完成传输的: CAN_High和CAN_Low。
按照协议定义,如下图2.1.2所示:
①CAN_High – CAN_Low < 0.5V 时候为隐性的,逻辑信号表现为"逻辑1",即高电平。
②CAN_High – CAN_Low > 0.9V 时候为显性的,逻辑信号表现为"逻辑0",即低电平。

图2.1.2

下图2.1.3为CAN的收发器:CAN_Rx和CAN_Tx分别是从MCU中接出来的引脚,比如MCU要发送一个逻辑1,则只要将CAN_Tx设置为1,经过CAN收发器转换,CAN_High和CAN_Low 线上的电压均为 2.5v,即传到总线的电压差 Vh-Vl=0V,总线上的状态则就是逻辑1。
同样,当CAN_High和CAN_Low 读取到 CAN总线电压分别3.5V和1.5V,即压差为2V,经过收发器转换,MCU则可通过CAN_Rx读取到信号0。

图2.1.3

CAN使用的是差分信号,差分信号稳定性更好,因为即使环境问题导致CAN_High电压发生变化,则CAN_Low也会发生同等变化,两者做差即可抵消由于这个环境引起的变化,如图2.1.4所示。

图2.1.4

隐形、显性之间存在天然的优先级特性:显性(逻辑0)的优先级比隐性(逻辑1)高;该优先级的特性,可以用来进行多主机的仲裁。
在总线上显性电平具有优先权,只要有一个节点输出显性电平,总线上即为显性电平。而隐形电平则具有包容的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平(显性电平比隐性电平更强)。

2.2、通信的整个过程
CAN通过对数据或操作命令进行打包来实现节点之间的通信,所以协议就搞的复杂了。

2.2.1、空闲状态
先规定空闲状态,所谓的空闲状态就是指没有节点正在传输数据的时候。

在CAN协议中,当总线上的上出现连续的11位隐性电平(两根线电压差小于0.5V),表示总线就处于空闲状态。也就是说对于任意一个节点而言,只要它监听到总线上连续出现了11位隐性电平,那么该节点就会认为总线当前处于空闲状态。
怎么让总线连续出现11位隐形电平呢?由于显性电平的高优先级特性,必须所有CAN主机都连续发送11个隐性电平,或者不发送时,总线才能出现连续11个隐性电平,即处于空闲状态。
  所以,现在可以先简单地理解为,需要在总线一开始工作的时候,所有节点都输出隐性电平;已知在一次传输时该节点输出显性电平,则在传输完成后该节点再输出隐性电平即可,这样就能将总线在无数据传输时保持空闲状态。

2.2.2、开始数据传输
每次发送数据前,节点都会监听总线的状态,如果总线状态为空闲,它就会立即向总线上发送自己的数据。这个数据里不仅有数据、还有本身的ID信息或者其它的控制指令,被称为数据包(数据帧),也可以叫报文。当报文被传输到其它节点时,只要这些节点按格式去解读,就能还原出原始数据。
报文: 在原始数据段的前面加上传输起始标签、片选(识别)标签、控制标签,在数据的尾端加上CRC校验标签、应答标签和传输结束标签。类似这样的数据包就被称为CAN的数据帧。为了更有效地控制通讯,CAN一共规定了5种类型的帧。

2.2.3、数据帧

数据帧是在CAN通讯中最主要、最复杂的报文,它是以一个显性位(逻辑0)帧起始开始,以7个连续的隐形位(逻辑1)帧结束结束。在它们之间分为仲裁段、控制段、数据段、CRC段、ACK段。

2.2.3.1、数据帧-帧起始
标准帧和扩展帧都是由1个位宽的显性电平表示帧起始SOF(Start Of Frame)。

2.2.3.2、数据帧-仲裁段
仲裁段Identify(ID),位宽:11位,ID信息的作用:
①如果同时有多个节点发送数据时,作为优先级依据(仲裁)
②目标节点通过ID信息来接受数据(验收滤波技术)
该段表示数据优先级的段,标准帧和扩展帧格式在本段有所区别,多出的SRR 位(Substitute Remote Request BIT),用于替代标准格式中的 RTR 位。
SRR 位为隐性位,由于 RTR 在数据帧为显性位,所以在两个 ID 相同的标准格式报文与扩展格式报文中,标准格式的优先级较高,区别如下图所示:

①ID: 高位在前,低位在后
②基本ID,禁止高7位都为隐性,即不能: ID=1111111 XXXX
③RTR,远程请求位。0:数据帧;1:远程帧
④SRR,替代远程请求位。设置为1(隐形电平)
⑤IDE,标识符选择位。0:标准标识符;1:扩展标识符

2.2.3.3、数据帧-控制段
表示数据段的字节数,由6个位构成,如下图所示。

①IDE:标识符选择位。0:标准标识符;1:扩展标识符
②r0,r1:保留位,必须以显性电平发送,但是接收时可以是隐性电平
③DLC:数据长度码。由 4 位组成,MSB 先行(高位先行),它的二进制编码用于表示本报文中的数据段含有多少个字节,DLC 段表示的数字为0到8,若接收方接收到 9~15 的时候并不认为是错误。

2.2.3.4、数据帧-数据段
该段可包含0~8个字节的数据,从最高位(MSB)开始输出。标准帧和扩展帧格式一致。

2.2.3.5、数据帧-CRC段
该段用于检查帧的传输错误。由15位的CRC顺序和1个位的CRC界定符(用于分隔的位)组成。标准帧和扩展帧格式一致。

发送方以一定的方法计算包括:帧起始、仲裁段、控制段、数据段;接收方以同样的算法计算 CRC 值并进行比较,如果不同则会向发送端反馈出错信息,重新发送;计算和出错处理一般由 CAN 控制器硬件完成或由软件控制最大重发数。

2.2.3.6、数据帧-ACK段
该段用于确认是否正常接收,由ACK槽(ACK Slot)和ACK界定符2个位组成。标准帧和扩展帧格式一致。

在 ACK 槽位中,发送端发送的为隐性位,而接收端则在这一位中发送显性位以示应答; 发送 ACK/返回 ACK这个过程使用到回读机制,即发送方先在 ACK 槽发送隐性位后,回读到的总线上的电平为显性0,发送方才知道它发送成功了,不需要重发。

2.2.3.7、数据帧-帧结束
①由7个位的隐性位组成
②标准帧和扩展帧在这个段格式完全一样

2.2.3.8、数据帧-举例
以IDE为标准帧为例,比如总线上有3个节点,节点1设置ID为0000101 00010,节点2验收滤波ID表中有节点1的ID号,而节点3中的验收滤波ID表中没有节点1的ID号,节点1向节点2发送1个字节的信息数据。


通过总线发送时,在ID信息发送阶段,只有节点2才能收到总线上的数据,因为节点3的验收滤波ID表中没有节点1的ID号。
在报文发送到ACK槽时,会等待并回读节点2的反馈,从节点2的角度看,此时总线为空闲状态,当验证CRC正确,则向总线发送显性电平,接着当节点1回读到显性电平,才会继续发送剩下的EOF帧结束。

2.2.4、仲裁机制
该机制运用到线与机制和回读机制。在2.2.3.8章节的例子中,是节点1主动发送数据,但万一节点1和节点2同时向节点3发送数据的时候,判定先后发送顺序就采用非破坏性位仲裁机制,也就是对各个消息的标识符(即ID号)进行逐位仲裁比较,如果某个节点发送的消息仲裁获胜,那么这个节点就将获取总线的发送权,仲裁失败的节点则立即停止发送并转变为监听(接收)状态。
由上文可知,显性的优先级高于隐性,即帧ID值越小,优先级越高,就可以获得发送权,比如000000 00010就比000000 00011的优先级要高,仲裁的过程由硬件实现;同时要注意,仲裁段除了报文ID外,还有RTR、IDE、SRR位(在扩展模式中),也就是说当ID全都一样时,会继续比较接下来的几位。

至于如何比较帧ID,可以理解为一种回读和线与机制,即显性能够将隐性覆盖,将自己要比较的位与总线上的状态相与,只有线与的结果与本身一致时,仲裁才能够通过。
其实在报文发送上去的过程,采用的是广播的方式,在节点1和节点2仲裁的同时,总线上所有的节点都能够监听到它们的ID号,只不过也在同时进行验收滤波,只有监听到的ID号存在ID表中,该节点才会选择继续监听后面的报文。

2.2.5、位时序
由于CAN没有时钟信号线,而且它的报文中并没有包含用于同步的标志,为了对总线的电平进行正确的采样以及接收到的电平是正确的,CAN中提出了位同步的方式来确保通讯时序。
CAN总线通讯协议的每一个数据帧可以看作一连串的电平信号,每一个电平信号代表一位(一字节8位的位),所以一帧中包含了很多个位,由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一位又分为4段,同步段(SS)、传播时间段(PTS)、相位缓冲段1(PBS1)、相位缓冲段2(PBS2)。分解后最小的时间单位是Tq,而一个完整的位由8~25个Tq组成。

①1位分为4段,每个段又由若干个Tq构成,这称为位时序。
②1位由多少个Tq构成,每个段又由多少个Tq构成,这些都可以任意设定定时时序。 通过设定位时序,多个单元可同时采样,也可任意设定采样点。
SS段(SYNC SEG):同步段。比如当总线上出现帧起始信号(SOF)时,其它节点上的控制器根据总线上的这个下降沿,对自己的位时序进行调整,将该下降沿包含到SS段内,这样根据起始帧进行同步的方式称为硬同步。其中SS段的大小为1Tq。总线上信号的跳变沿被包含在节点的SS段的范围之内,则表示节点与总线的时序是同步的,采样点采集到的总线电平即可被确定为该位的电平。
PTS段(PROP SEG):传播时间段。这个时间段是用于补偿网络的物理延时时间,包括发送单元的输出延迟、总线上信号的传播延迟、接收单元的输入延迟,这个段的时间为以上各延迟时间的和的两倍。大小可以为1~8Tq。
PBS1段(PHASE SEG1):相位缓冲段,主要用于补偿边沿阶段的误差,它的时间长度在重新同步的时候可以加长。PBS1段的初始大小可以为1~8Tq。
PBS2段(PHASE SEG2):另一个相位缓冲段,也是用于补偿边沿阶段误差的,它的时间长度在同步时可以缩短。PBS2段的初始大小可以为2~8Tq。
(对于PBS段而言,当信号边沿不能被包含与SS段中时,可在此段进行补偿,以及可以吸收时钟误差)
SJW(reSynchronization Jump Width):重新同步补偿宽度,即在重新同步的时候,PBS1和PBS2段的允许加长或缩短的时间长度,SJW加大后允许误差加大,但通信速率下降。SJW为补偿此误差的最大值(即每一次误差补偿都不能超过这个值,1~4Tq)。

CAN的同步分为硬同步和重新同步:
硬同步:在帧起始信号时同步总线上所有器件的位时序,无法确保后续一连串的位时序都是同步的。
重新同步:在检测到总线上的时序与节点使用的时序有相位差时(即总线上的跳变沿不在节点时序的SS段范围),通过延长PBS1或缩短PBS2段来获得同步。

采样点:读取总线电平的时刻,并将读到的电平作为位值的点。位置在PBS1结束处。
延长/缩短PBS段来达到同步:PTS和PBS1段小而PBS2加大时采样点前移,PTS+PBS1段大而PBS2减小时采样点后移。

同步过程:
在硬同步阶段,当节点检测到本身SS段并不在总线电平下降沿跳变处,节点则会把自己的位时序中的SS段平移至总线出现下降沿的部分,后面三段也跟着上去,以获得同步。(可以理解为节点在检测到帧起始信号时才开始“设置段”)

在重新同步阶段,利用普通数据位的高到低电平的条边沿来同步(帧起始信号是特殊的跳变沿)。重新同步与硬同步方式相似的地方是它们都使用SS段来进行检测,同步的目的都是使节点内的SS段把跳变沿包含起来。重新同步的方式分为超前和滞后两种情况,以总线跳变沿与SS段的相对位置进行区分,下面举例设SJW为2Tq。
①相位超前,节点从总线的边沿跳变中,检测到它内部的时序比总线的时序相对超前2Tq,这时控制器在下一个时序中的PBS1段增加2Tq的时间长度,使得节点和总线时序重新同步。

②相位滞后,节点从总线的边沿跳变中,检测到它的时序比总线的时序相对滞后2Tq,这时控制器在前一个位时序中的PBS2段减少2Tq的时间长度,获得同步。

理解上面重新同步过程时,需要知道前一次SS到下一次SS之间的长度是可伸展的(暂时称之为Length),当检测到前一次SS出现得太快(还没等到下降沿到来),这就是相位超前了,如果不把Length缩短一点,那么下一次SS将也会超前。缩短Length的方法就是调整PBS的长度,这个过程由CAN控制器完成,即新的PBS长度=当前PBS长度减SJW(同步补偿宽度)。

2.2.6、一次数据传输的例子
比如总线上有3个节点,节点1设置ID为000100 00110,节点2设置ID为000100 00111,节点3验收滤波ID表中有节点1和节点2的ID号,节点1和节点2同时向节点3发送1字节的信息。步骤如下:
1、总线空闲,节点1和节点2同时发送帧起始信号,3个节点同时调整位时序(硬同步);
2、节点1和节点2开始仲裁,两者同时向总线发送第一位0,同时回读总线状态与本身状态相与,得0,两者第1位仲裁均通过。一直持续到第9位1,两者同时向总线发送1,通过回读总线状态,得1,两者第9位仲裁均通过。
3、直到第11位,当两个节点回读总线状态与本身状态相与时,总线的显性将隐性屏蔽,即总线状态为显性,则节点1得0(与本身状态相同),而节点2得0(与本身状态不同),此时节点1仲裁胜利,节点2放弃发送请求。
4、从第1位仲裁到第11位的同时,节点1向其它节点广播了本身的ID,当节点1本身也接收到了节点2的ID信息,因此节点2和节点3也都接收到了节点1的ID信息,只不过节点2对节点1不感兴趣,因而选择了忽略节点1后续的信息,节点3则开始接收节点1的数据。
5、从硬同步之后,每当节点1和节点2发出一个仲裁位,三个节点的CAN控制器都在检测本身的位时序与总线位时序是否一致,当有相位超前或者滞后时则自动进行位时序的重新同步,在后续的报文传送中也是这样。

三、CAN总线协议的详细介绍
CAN协议经ISO标准化后有ISO11898标准和ISO11519-2标准两种,它们对于数据链路层的定义相同,但物理层不同。

CAN通信中多次提到的回读机制,指的是节点在向总线上发送报文的过程中,同时也对总线上的二进制位进行“回读”。通过这种机制,节点就可以判断出本节点发出的二进制位与总线上的二进制位是否一致。

3.1、帧的种类
帧分为数据帧、遥控帧、错误帧、过载帧、帧间隔。其中数据帧具体见2.2.3。

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

遥控帧与数据帧的不同之处:
①遥控帧的RTR位(远程请求位。0:数据帧;1:远程帧),为隐性位,没有数据位
②没有数据段的数据帧和遥控帧可通过RTR位区分开来

3.1.2、错误帧
用于在接收和发送消息时检测出错误的帧。它由错误标志和错误界定符构成。
建议看这篇文章:https://blog.csdn.net/u014157109/article/details/120663493

1、错误标志
错误标志包括主动错误和被动错误标志两种。①主动错误:6位显性②被动错误标志:6位隐性
2、错误界定符
错误界定符由8个位的隐性位组成。
3、错误标志滞后还有0~6个错误标志重叠部分
处于主动错误状态的节点检测到错误时会发生主动错误标志,6个连续显性位会违反填充规则和位场的固定形式,进而造成其它节点也检测到错误并发送错误标志。所有节点所发送的显性序列叠加组成错误标志重叠部分,错误标志重叠部分的长度在6~12个显性位之间。

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

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

①对于发送节点:在发送数据帧和遥控帧时,对于SOF~CRC(除去CRC界定符)之间的位流,相同极性的电平如果持续5位,那么在下一位插入一个与之前5位发型的电平。
②对于接收节点:在接收数据帧和遥控帧时,对于SOF~CRC(除去CRC界定符)之间的位流,相同极性电平如果持续5位,那么需要删除下一位再接收。如果这个第6个位的电平与前5位相同,将被视为错误并发送错误帧。但是位填充的副作用就是,接收到的消息中的少量位错误会破坏解填充过程(接收器需要去除填充位),从而导致大量错误在解填充消息中填充,这降低了CRC针对原始错误提供的保护级别。

5、错误的种类

位错误(Bit Check Error):节点将自己发送到总线上的电平与同时从总线上回读到的电平进行比较,如果发现二者不一致,那么这个节点就会检测出一个位错误。
有三种例外情况不属于位错误:
①在仲裁区,节点向总线发送隐性位却回读到显性位,不认为是错误,这种情况表示该节点仲裁失败
②在ACK槽,节点向总线发送隐性位却回读到显性位,不认为是错误,这是该节点当前发送的这一帧报文至少被一个其它节点正确接收
③该节点发送被动错误标识,发送节点向总线发送连续6个隐性位(被动错误标志)却回读到显性位,不认为是位错误。因为被动错误标志是6个连续的隐性位,所以在总线上按照线与机制,有可能这6个连续的隐性位被其它节点发送的显性电平吃掉。
ACK错误(Acknowledment Error):按照CAN协议的规定,在一帧报文(数据帧或者遥控帧)发出之后,如果接收节点成功接收了该报文,它就要在该帧报文ACK槽对应的时间段内向总线上发送一个显性位来应答发送节点。这样发送节点就会在ACK槽时间段内从总线上回读到一个显性位。当发送节点在ACK槽时间段内没有回读到显性位,那发送节点就会检测到一个ACK应答错误,这标识没有一个节点成功接收该帧报文。
填充错误(Fill Error):帧起始到CRC之间,接收节点检测到有6个连续相同的位电平时,也就是违反5位相同位插入1位相反位的“位填充”原则。
CRC错误:发送节点在发送数据或遥控帧时,会计算出该帧报文的CRC序列。接收节点在接收报文时也会执行相同的CRC算法,如果接收节点计算出CRC序列值与发送节点发来的CRC序列值不一致,那么接收节点就检测到一个CRC错误。
格式错误:在一帧报文发送时,如果在必须发送预定值的区域内检测到了非法值,即与任何一种帧格式都不符;CAN报文中,有预定值的区域包括:
①数据帧和遥控帧的CRC界定符、ACK界定符、EOF;
②错误帧界定符
③过载帧界定符

6、错误通知
在检测到错误之后,检测到错误的节点就要发送错误帧到总线上来通知总线上的其它节点。①节点错误状态
对于错误的界定,节点存在如下3种状态:
(1)主动错误:错误标志由6个连续的显性位组成(较填充位和其它帧格式不同,容易区分)
(2)被动错误:被动错误由6个连续的隐性位组成,当发送结束后,处于被动错误状态的节点在下一次再次发送时之前需要等待一些额外时间。
(3)总线关闭:处于总线关闭状态的节点不允许发送和接收任何形式的帧报文。且只能通过用户请求进行恢复

②错误状态的转换
在CAN节点内,有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。
错误界定并非是依据错误的类型去界定CAN节点的错误状态,而是依据错误计数器(TEC/REC)的值来界定CAN节点的错误状态;当该节点检测到错误后,内部的REC/TEC计数器会相应的增加,基于REC/TEC的值判定节点状态。

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

节点错误状态的转换就是一个“量变”到“质变”的过程。
(1)主动错误状态:REC<127且TEC<127
初步可判定该节点相对稳定可靠,该错误计数很可能是由于某个节点异常导致的,那么其它节点很可能也会触发该错误,那么允许该节点破坏CAN总线的异常报文并告知其它节点。
节点检测到一个错误就会发送带有主动错误标志的错误帧,因为主动错误标志是连续6个显性位,所以这个时候主动错误标志将会“覆盖”总线其它节点的发送位,而之前在CAN总线上传输的报文就被这6个连续显性位破坏掉。
若发出主动错误帧的节点是发送节点,这种情况就相当于:刚刚发送的那一帧报文我发错了,现在我破坏掉它(发送主动错误帧),你们不管收到什么都不算数。
若发出主动错误帧的节点是接收节点,这种情况就相当于:刚我收报文时发现了错误,不管你们有没有发下你这个错误,我现在主动站出来告诉大家这个错误,并把这一帧破坏掉(发送主动错误帧),刚才你们收到的东西不管对错都不算数了。
(2)被动错误状态:REC>128或TEC>128
节点发送错误帧的次数较多,初步可判定该节点相对不可靠,该错误计数很可能是由于自身节点问题导致,即该错误很可能仅有该节点才有,对于其它节点而言是可以正常交互的,总线不信任该节点提供的错误标识,将不允许破坏总线数据,那么允许该节点发送错误帧“6个连续隐性位”到CAN总线,仅告知其它节点异常。
若发出被动错误帧的节点为报文的发送节点,那么在发送被动错误帧之后,刚正在发送的报文被破坏,并且该节点不能在错误帧之后随着连续发送刚刚发送失败的那个报文。随之而来的是帧间隔,并且连带着8位隐性位的“延迟传送”段;这样总线电平就呈现出连续11位隐性位,总线上的其它节点就能判断总线处于空闲状态,就能参与总线竞争。
此时如果该节点能够竞争成功,那么它就能接着发送,如果竞争不能成功,那么就接着等待下一次竞争。这种机制的目的正是为了其它正常节点(处于主动错误)优先使用总线。
(3)总线关闭状态:TEC>255
一个处于被动错误状态的节点,仍然多次发送被动错误帧,使该节点转为总线关闭状态;
该节点不能向总线上发送报文,也不能从总线上接收报文,整个节点脱离总线。等到检测到128次11个连续的隐性位时,TEC和REC置0,重新回到主动错误状态。由于存在实现方式的不同,CAN总线关闭状态存在只允许用户请求恢复和检测到128个11位连续的隐性位时自恢复两种不同的恢复形式。
如果总线上只有一个节点,该节点发送数据帧后得不到应答,TEC最大只能计数到128,即这种情况下节点只会进入被动错误状态而不会进入总线关闭状态。

③错误帧的发送
按照CAN协议的规定:
发生位错误、填充错误、格式错误、ACK错误时,则在错误产生的那一位的下一位开始发送错误帧。发生CRC错误时,紧随ACK界定符后的位发送错误帧。错误帧发送完成后,总线空闲时自动重发出错的数据帧。

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

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

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

①过载标志:6个显性位。过载标志的构成与主动错误标志的构成相同。
②过载界定符:8个隐性位。过载界定符的构成与错误界定符的构成相同。

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

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

四、CAN的特性总结
(1)多主控制
在总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元同时开始发送消息时,根据标识符(Identifier,ID)决定优先级。ID并不是表示发送目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息ID的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。
(2)系统的柔韧性
与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。
(3)通信速度
通信速度较快,通信距离远。最高1Mbps(距离小于40M),最高可达10KM(速率低于5Kbps)。因为没有CLK信号线,因此异步通信,同一网络速率必须保持一致。
(4)远程数据请求
可以使用远程帧去请求数据。
(5)错误检测
具有错误检测、错误通知和错误恢复功能。所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其它所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会步段反复地重新发送此消息直到成功发送为止(错误恢复功能)。
(6)故障封闭
CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。所以,当总线上发送持续数据错误时,可将引起此故障的单元从总线上隔离出去。
(7)连接节点多
CAN理论上可以连接多个单元,但是受到负载的延迟,会导致通信速率的下降。连接的单元越多,通信速率越低。

基于AUTOSAR架构的CAN接收/发送的软件实现

CAN接收流程图

注: BSW:基础软件层;
1)COM:主要就起了一个信号接口和网关的作用。从应用层传下来数据首先就进入这里,应用层无需关心收发的数据是通过什么总线传输的,只需要将它传输给COM即可
2)PDU Router: PDU——Protocol Data Unit,协议数据单元。这个模块的功能就是将COM下发的信号数据分配到相应的协议总线上去;或者将不同的协议变成同一信号上传给COM
3)IPDU Mux:用于解析一些特殊的协议,比如CAN FD或者用户自定义的一些协议。就是起了一个统一CAN ID,不同信号Layout的作用
4)CAN Tp:分包数据传输与错误检测,一般来说只有在诊断的时候才会使用
5)CAN Interface:主要配置收发队列;组帧(FlexRay);管理时间触发总线的调度表(LIN, FlexRay)
6)CAN Driver:MCAL中对主芯片上CAN模块的驱动封装
7)Trcv Driver:Transceiver driver,收发器驱动

CAN接收的具体过程描述如下:
1、BSW(基础软件层)调度器周期性调用CAN Driver模块的Can_MainFunction_Read函数;
2、CAN Driver模块的Can_MainFunction_Read函数将访问CanController(硬件)的寄存器,如前面文章所述的仲裁寄存器,数据寄存器和数据长度寄存器,并读取这些寄存器的数据;
3、数据读取结束后,这时继续调用CAN Interface模块的CanIf_RxIndication函数,这样数据从CAN Driver模块传给了上一层的CAN Interface模块;
4、CAN Interface模块再调用PduR模块的PduR_RxIndication函数,将数据传到PduR模块;
5、PduR模块路由到Com模块,调用Com_RxIndication函数,将数据传到Com模块,Com模块将会把数据存入其缓存,供应用层软件读取使用。
注:上述的4个核心模块,除了CAN Driver能够访问或配置硬件,其它模块均不能。
 CAN发送流程图
CAN发送流程图

CAN发送功能需使用请求(Request)服务和确认(Comfirmation)服务。
CAN发送的具体过程如下:
1、BSW调度器周期性调用Com模块的Com_MainFunction_Tx函数,Com模块将从缓冲器中读取需发送的数据;
2、Com模块的Com_MainFunction_Tx函数将调用PduR模块的PduR_ComTransmit函数,将数据传给下层的PduR模块;
3、PduR模块路由到CAN Interface模块,调用CanIf_Transmit函数,这样数据从PduR模块传给了下层的CAN Interface模块;
4、CAN Interface模块再调用Can Driver模块的Can_Write函数,将数据写入相应的寄存器;
5、与CAN接收功能一样,Can_Write函数将访问仲裁,数据长度和数据寄存器,将数据写入。
CAN数据发送后的确认过程如下:
1、BSW调度器周期性的调用CAN Driver模块的Can_MainFunction_Write函数
2、CAN Driver模块的Can_MainFunction_Write函数将访问CanController(硬件)有关寄存器,读取有关数据供上层确认
3、数据读取结束后,这时继续调用CAN Interface模块的CanIf_TxComfirmation函数,这样数据从CAN Driver模块传给了上层的CAN Interface模块
4、CAN Interface模块再调用PDU Router模块的PduR_TxConfirmation函数,将数据传到PduR模块
5、PDU Router模块路由到COM模块,调用Com_TxConfirmation函数,确认发送状态

物联沃分享整理
物联沃-IOTWORD物联网 » CAN协议简明总结及要点解析

发表评论