CAN协议规定了以下5种类型的帧:
数据帧和遥控帧协议格式
数据帧
遥控帧
各个数据帧各部分用途:
ACK槽位:发送方发送隐形电平1,如果接收方存在,则接收方发显性电平0,如果接收方不存在,那就没有显性电平0了,也就是发送方释放CAN总线,接收方拉起CAN总线。ACK槽位前后,操作总线权利有一个短暂交换,在ACK槽位这一位时,变为接收方操作总线,未给权利交接留出时间,ACK槽位前后,留两个界定符。CRC界定符时,发送方必须发隐形1,除了做一个分割,另一个作用是在ACK槽位前,发送方必须释放总线,发送隐形电平1就是释放总线,ACK界定符,接收方也释放总线。
一:位编码/解码
总线管理功能管理功能执行在位时间范围内,如CAN节点同步行为、网络传输延时补偿、采样点定位等,应由CAN协议集成电路的可编程位定时逻辑给出。
1.1正常位速率(BR)
在没有重同步的情况下,一个理想的发送器每秒发送的位数。
1.2正常位时序(tB)
tB = 1/BR
正常位时序可分为几个互不重叠的时间段:同步段(SYSNC_SEG)、传播段(PROP_SEG)、相位缓冲段1(PHASE_SEG1)、相位缓冲段2(PHASE_SEG2)。
1.2.1同步段(SYSNC_SEG)
用于同步总线上的各个节点,在此段内需要一个跳边沿。
1.2.2传播段(PROP_SEG)
用于补偿网络内的传输物理延时时间。这个延时时间由信号在总线上的传播时间和CAN节点内部延时时间组成。
1.2.3相位缓冲段1(PHASE_SEG1)、相位缓冲段2(PHASE_SEG2)
用于补偿沿的相位误差,通过重同步,这两个时间段可被延长或者缩短。
1.2.4采样点
是读取总线电平,并将它解析为数值的时间点。位于相位缓冲段1(PHASE_SEG1)的终点。
1.2.5信息处理时间
由采样点开始,保留用计算位电平的时间。
1.2.6重同步调转宽度
由于重同步的结果,相位缓冲段1(PHASE_SEG1)可被延长或者相位缓冲段2(PHASE_SEG2)可被缩短。这两个相位缓冲段的延长或缩短的总和上限,由重同步跳转宽度给定。
1.2.7内部延时时间
CAN内部延时时间是发送和接收路径上的异步延时时间总和(通俗的理解是CAN收发器将逻辑电平转换成总线电平的时间toutput和将总线电平转为逻辑电平的时间tinput的总和)。
tnode = toutput + tinput
为了仲裁的有效执行:
tPROP_SEG ≥ tnodeA + tnodeB + 2*tbusline
tbusline:CAN总线的传输时间
1.3位时间编程
1.3.1. 时间份额(tq)
由振荡器周期派生出的一个固定的时间单元(1-32)。
如假设8M的振荡器频率,预分频系数为1,则最小时间份额tq = 1 / 8MHz = 0.125us。总线波特率要求为500kbps,位时间为1/500kbs = 2us,则需16tq 。
1.3.2 正常时间段长度
同步段(SYSNC_SEG):1tq
信息处理时间:小于或等于2tq
传播段(PROP_SEG):用于补偿实际网络的传输延时时间,长度可编程为1-8tq
相位缓冲段1(PHASE_SEG1):可编程为1-8tq
相位缓冲段2(PHASE_SEG2):长度为相位缓冲段1(PHASE_SEG1)和信息处理时间的最大值
在CAN实现中,传播段(PROP_SEG)和相位缓冲段1(PHASE_SEG1)被统一编程,可称为Time segment 1,长度可编程为4-16tq。Time segment 2代表相位缓冲段2(PHASE_SEG2),长度可编程为2-8tq。在位时间中,时间份额的总数必须为8-25tq。
1.3.3 采样点位置
tsp = (SYNC_SEG + Time segment 1) / (SYNC_SEG + Time segment 1 + Time segment 2)
如果位定时设置将采样点设置在位时间的末端,则传播段就会越长,能实现更远的网络。反之,则可提高重同步能力,对时钟误差的容忍能力越大。
采样点的设置应使所有节点能够达到传播延迟和时钟误差的最佳折衷点。建议采样点设置应当靠近但是不超过0.875,这使传播延迟和时钟误差容忍达到最优。
二:同步
CAN总线的位同步只有在节点检测到“隐性位”(逻辑1)到“显性位”(逻辑0)的跳变时才会产生,当跳变沿不位于位周期的同步段之内时将会产生相位误差e。该相位误差就是跳变沿与同步段结束位置之间的距离。
如果跳变沿发生在同步段之后采样点之前为正的相位误差;如果跳变沿位于同步段之前采样点之后为负的相位误差。相位误差源于节点的振荡器漂移、噪声干扰等。
硬同步和重同步是同步的两种形式,他们遵从下列规则:
- 在一个位时间内仅允许一种同步,要么硬同步要么重同步
- 任何一个从“隐性”到“显性”的下降沿都可以用于同步
- 硬同步只发生在帧起始‘SOF’位
- 重同步发生在一个报文‘SOF’位之外的其它位
- 发送节点不执行重同步,只有接收节点执行重同步
(注:在理解同步机制时,由于两个节点之间的传播延时时间相对于每一个位时间都是一致的,所以在理解同步机制时,可以将传播延时时间忽略)
2.1硬同步
硬同步只在总线空闲时通过一个下降沿(只发生在帧起始)来完成,此时不管有没有相位误差,所有节点的位时间从SYNC_SEG重新开始。强迫引起硬同步的跳变沿位于重新开始的位时间的同步段之内。
硬同步调整宽度不受限制。
如下图所示:硬同步的结果使接收节点B的下降沿重新处于位时间的SYNC_SEG内。
2.2重同步
若跳变沿发生在接收节点的SYNC_SEG内,则相位误差e = 0,不需要进行重同步。
若跳边沿发生在接收节点的SYNC_SEG之前,则相位误差e < 0,需要缩短相位缓冲段2(PHASE_SEG2)
如下图所示:执行重同步操作后,缩短了相位缓冲段2(PHASE_SEG2),使得接收节点B下一个位时间的采样点实现了与发送节点A之间的同步
若跳变沿发生在接收节点的SYNC_SEG之后,则相位误差e > 0,需要延长相位缓冲段1(PHASE_SEG1)
如下图所示:执行重同步操作后,延长了相位缓冲段1(PHASE_SEG1),使得接收节点B下一次位时间的采样点实现了与发送节点A之间的同步
三、CAN错误及CAN busoff处理机制
CAN总线具有严格的错误诊断功能,该功能已经固化在芯片中,一旦错误被检测,正在传送的数据帧将会立即停止而待总线空闲时再次重发直至发送成功,该过程并不需要CPU的干涉,除非错误累计,该发送器进入总线关闭(Bus Off)。
3.1:CAN错误帧
错误帧由两个不同的场组成。第一个场是不同节点提供的错误标志重叠部分;第二个场是错误界定符。
主动错误标志:6个连续的显性位
被动错误标志:6个连续的隐性位
错误界定符:8个连续的隐性位
错误标志之后还有0~6个错误标志重叠部分,这一段的形成在“3.1.1 错误标志”和3.4:“错误通知”段中详细讲解。
3.1.1 错误标志
错误标志分为主动错误标志和被动错误标志两种:
- 主动错误标志:
主动错误标志由6个连续的显性位0组成。处于主动错误状态的节点检测到错误时会发送主动错误标志。主动错误标志会违反位填充规则和位场的固定形式,这会造成其它节点也检测到错误并发送错误标志(错误标志重叠部分形成的原因)。所有节点所发送的显性序列叠加组成错误标志重叠部分。错误标志重叠部分的长度在6-12个显性位之间。
Q:会不会存在一个节点处于主动错误状态,其他节点处于被动错误状态?(“4.1 位错误通知_3)”)
- 被动错误标志:
被动错误标志由6个连续的隐性位1组成,被动错误标志可能会被其他节点的显性位改写。(必须为6个连续的隐性位才能代表被动错误标志发送完成),(应当理解为节点发送了6个连续隐性位就行,而不需要关注总线上的状态有没有被其他节点改写。)
如果是一个发送节点发送被动错误标志,将会导致接收节点的位填充错误。以下两种情况除外:1:如果处在仲裁期间,且其他节点取得总线控制权;
2:被动错误标志发送开始于小于CRC序列结束前的第六位的位置。(位填充只作用域数据帧和遥控帧,且只作用于CRC界定符之前)
如果一个接收节点需要发送被动错误标志,它不会诱发总线上的任何活动,当检测到6个连续的隐性位才认为被动错误标志被送出。
3.1.2 错误界定符
错误界定符由八个连续的隐性位1组成。当发送完错误标志后,所有节点开始向总线发送一个隐性位,并检测到总线电平为隐性时,发送余下的七个隐性位。
3.2:CAN错误类型
3.2.1 位错误
向总线发送一个位的节点同时会监控总线,当监控到总线的位数值和发送的位数值不一致时,则鉴定为一个位错误。(SOF到EOF的位使用位错误检测)
例外:
1)在仲裁或者ACK期间发送隐形位,但是检测到显性位时,不鉴定为位错误。
2)发送被动错误标志的节点在检测到显性位时,不鉴定为位错误。
3.2.2 填充错误
当出现6个连续的相同电平时,鉴定为填充错误。
(注:SOF到CRC序列的结束的位使用位填充错误检测)
3.2.3 CRC错误
当接收节点计算的CRC结果与接收到的CRC结果不一致时,鉴定为CRC错误。
3.2.4 格式错误
当固定格式的位段中,出现一个或者多个非法位时,鉴定为格式错误。(比如数据帧和遥控帧中的CRC界定符、ACK界定符、帧结束位,检测到一个或更多显性位)
特殊情况:
1)接收节点在EOF的最后一位检测到显性位,不鉴定为格式错误。
2)任何节点在错误界定符或过载界定符的最后一位检测到显性位,不鉴定为格式错误。
3.2.5 应答错误
在应答间隙期间,发送节点未检测到显性位,即发送方发出的帧没有接收方应答,发送方认为产生了ACK错误,则鉴定为应答错误。
3.3:CAN错误界定
CAN节点可以区分常规错误和永久故障。有故障的发送节点将切换到总线关闭状态。总线关闭状态在逻辑上与总线断开,既不能发送也不能接收。
3.3.1 CAN错误状态
对于错误界定,节点存在如下三种状态:
- 主动错误
- 被动错误
- 总线关闭
主动错误:
处于主动错误状态的节点能正常参与总线通信的收发,当检测到错误时将发送主动错误标志,错误标志由6个连续的显性位0组成(这种连续的6个显性位与常规的填充位和其它帧固定格式不相同,正因为如此,硬件才容易区别)。
如果是发送节点发送主动错误帧,这种情况相当于刚刚发送的那帧报文我发错了,我现在主动破坏它,其他节点不管接收到什么都不算数;
如果是接收节点发送主动错误帧,这种情况相当于刚刚接收的那帧报文出错了,我现在主动站出来告诉大家这个错误,并把这帧报文破坏掉,刚才你们不管接收到什么都不算数
Tips:处于主动错误状态,说明这个节点目前是比较可靠的,出现错误的原因可能不是它本身的问题,即刚刚检测到的错误可能不仅仅只有它检测到,正因为如此,整个总线才允许它破坏正在发送中的报文。
被动错误:
处于被动错误状态的节点不能发送主动错误标志。它能参与正常通信,但当检测到错误时发送的是被动错误标志。被动错误标志由6个连续的隐性位1组成。当发送结束后,处于被动错误状态的节点在下一次再次发送时之前需要等待一些额外时间。
如果是发送节点发出被动错误帧,刚刚被发送的报文被破坏。错误帧发送完成后,接着的是帧间隔(3个隐性位)和“传输延时段”(8个隐性位),这时总线上的其他节点就可以判断总线处于空闲状态并参与总线竞争。这种机制可以让其他处于主动错误状态的节点优先使用总线。
如果是接收节点发出被动错误帧,则不会对总线产生任何影响
Tips:处于被动错误状态,说明这个节点目前是不可靠的,出现错误的原因可能是它本身的问题,即刚刚检测到的错误可能只有它自己检测到,正因为如此,整个总线不会信任它的报告,从而只允许它发送6个连续的隐性位,这样才不会拖累其他节点。
总线关闭:
处于总线关闭状态的节点不允许发送和接收任何形式的帧报文。且只能通过用户请求进行恢复。
注:由于存在实现方式的不同,CAN总线关闭状态存在只允许用户请求恢复和自恢复(检测到128个11位连续的隐性位1时)两种不同的恢复形式。
Tips:如果总线上只有一个节点,该节点发送数据帧后得不到应答,TEC最大只能计数到128,即这种情况下节点只会进入被动错误状态而不会进入总线关闭状态。
3.3.2 CAN错误计数
3.4:CAN错误通知
总线通信错误以向总线发送错误帧作为标志。
位错误、填充错误、格式错误或者ACK错误产生后,将在当前发送位的下一位发送错误帧;
CRC错误产生后,紧随ACK界定符后的位发送错误帧。
错误帧发送完成后,总线空闲时自动重发出错的数据帧。
3.4.1 位错误通知
1)如下图所示:
假设总线上所有节点处于主动错误状态;
当一个发送节点监控到总线上的位数值与发送的位数值不一致时,检测为位错误,并发送主动错误标志(6个连续的显性位);
接收节点接收到发送节点发送的6个连续的显性位时,会检测为位填充错误,也会发送主动错误标志;
发送节点发送完主动错误标志后,开始监控总线是否为隐性位,当总线为隐性位时,开始发送错误界定符(8个连续的隐性位);
当接收节点发送完主动错误标志后,开始向总线发送错误界定符;
等待错误帧发送完成,总线空闲后,发送节点重新发送出错的报文;
注:由于发送节点发送6个连续的显性位会破坏位填充规则,触发接收节点发送主动错误标志,发送节点和接收节点的结合是形成错误标志叠加部分的原因。
如下图所示错误标志重叠部分为6+6个显性位
2)如下图所示:
错误重叠部分为6+4个显性位
3)如下图所示:
假设发送节点处于被动错误状态,接收节点处于主动错误状态;
当发送节点监控到总线上的位数值与发送的位数值不一致时,检测为位错误,并发送被动错误标志(6个连续的隐性位);
接收节点接收到发送节点发送的6个连续的隐性位时,会检测为位填充错误,并会发送主动错误标志;
发送节点发送完被动错误标志后,开始监控总线是否为隐性位,当总线为隐性位时,开始发送错误界定符(8个连续的隐性位);
接收节点发送完主动错误标志后,开始监控总线是否为隐性位,当总线为隐性位时,开始发送错误界定符(8个连续的隐性位);
3.4.2 格式错误通知
1)如下图所示:
假设总线上所有节点处于主动错误状态;
当接收节点和发送节点检测到总线上的格式错误时,向总线上发送主动错误标志;
3.4.3 CRC错误通知
1)如下图所示:
假设所有节点都处于主动错误状态;
当接收节点检测到CRC错误后,在ACK界定符之后,向总线发送主动错误标志;
发送节点检测到格式错误(EOF的固定格式为7个连续的隐性位),同时向总线发送主动错误标志;
注:错误标志重叠部分为6+1个显性位
3.5:CAN错误恢复
CAN bus off如下存在两种不同的形态:
- 自恢复模式:处于总线关闭状态的节点对总线没有任何影响,不允许发送任何数据帧、遥控帧,ACK位,错误帧,过载帧。是否允许接收取决于实现方式 (能进不能出)。在检测到128个11位连续的隐性位1后,节点可由总线关闭状态可以恢复到主动错误状态。
- 用户请求恢复模式:处于总线关闭状态的节点不允许任何发送和接收,只有用户请求才可以恢复。
(注:在接触过的MC9S08DZ…、MC9S12XEP…、STM32…系列单片机,在实现方式上都可通过配置寄存器的方式,关闭或者使能CAN总线BUSOFF自恢复功能。)
在通信过程中,错误主动和错误被动两种状态下节点的恢复过程一般不需要MCU进行额外的编程处理,直接使用CAN控制器固有功能即可。但对于总线关闭状态,往往不直接使用CAN控制器固有的恢复过程,而是对其进行编程控制,以实现“快恢复”和“慢恢复”机制。因为当进入总线关闭状态时,节点已经发生了严重的错误,处于不可信状态,如果迅速恢复参与总线通信,具有较高的风险,因此,在实际的应用中,往往会通过MCU对CAN控制器总线关闭状态的恢复过程进行编程处理,以控制节点从总线关闭状态恢复到错误主动状态的等待时间,达到既提高灵活性又保证节点在功能上的快速响应性的目的。具体包括“快恢复”和“慢恢复”策略,两种策略一般同时应用。
3.5.1 自恢复模式下CAN bus-off恢复过程
节点进入总线关闭状态后,bus off恢复过程
1.立即重新初始化 CAN 芯片;
2. t(tBusOffQuick 或 tBusOffSlow)时间内应暂停发送报文,分为快速恢复和慢速恢复;
3. 恢复到正常 CAN 通信。
节点进入总线关闭状态后,MCU编程实现总线关闭“快恢复”和“慢恢复”的过程
1. 首先,ECU 执行快速恢复模式;
2. 连续 5 次快速恢复后,ECU 执行慢速恢复模式;
注:所谓的快慢恢复,即进入CAN BUS OFF状态后,ECU重新初始化CAN模块,并等待t(tBusOffQuick 或 tBusOffSlow)后,重新使能总线报文的发送。如果报文发送成功,则CAN BUSOFF恢复成功;如果报文发送失败,当TEC > 255时总线会再次BUS OFF状态,再次执行恢复操作。
节点以正常发送模式发送报文的过程中,如果出现了发送错误,发送错误计数会增加,只要发送错误计数没有超过255, CAN控制器便会自动重发报文,如果出现多次发送错误,使发送错误计数累加超过255,则节点跳转为总线关闭状态。MCU能够第一时间知道节点进入了总线关闭状态(例如在错误中断处理逻辑中查询状态寄存器的相应位),这时MCU控制CAN控制器进入“快恢复”过程,即控制CAN控制器停止报文收发,并进行等待,计时达到需要的时间T1(如100ms)后,MCU重新启动恢复CAN控制器参与总线通信,这样便完成了一次“快恢复”过程。
节点每进入一次“快恢复”过程时,MCU会对此进行计数,当节点“快恢复”计数达到设定的值N(如5次),则后续再次进入总线关闭状态时MCU把恢复总线通信的等待时间T2进行延长(如1000ms),这样便实现了“慢恢复”过程。“快恢复”和“慢恢复”过程的主要区别就在于恢复节点参与总线通信的等待时间的不同。
参考:
https://blog.youkuaiyun.com/u014156403/article/details/103725924
https://blog.youkuaiyun.com/u014156403/article/details/103521725