CAN协议
前⾔
在做智能驾驶的公司实习,有些协议是必会的。好记性不如烂笔头,所以笔者开了⼀篇⽂章来记录学习的过程,⽅便⼤家交流,也⽅便我⾃⼰
CAN。CAN协议使⽤差分信号,通讯稳定,⽽且错误诊断⼗分完备,安全性很⾼,因此⼴泛复习。这篇⽂章总结⼀下我在公司学的第⼀个协议,CAN 应⽤于汽车电⼦。这是我的第⼀篇⽂章,排版和叙述可能有些问题,⼤家将就看看。⽂末列了⼀些参考资料,写得都⽐我好。
CAN的背景
CAN-Controller Area Network,是德国公司Bosch在20世纪80年代初为了解决汽车中众多控制单元和仪器之间的实时数据交换⽽开发的⼀种串⾏通信协议。
在使⽤CAN协议之前,汽车的各种器件之间连线杂乱,这种情况下也想要保持同步以及⾼效地传输数据⽐较困难和⿇烦。如图1:
CAN协议采⽤总线型拓扑⽅式的⽹络。各单元作为总线上的节点分布,有序⾼效地读取总线上的信息。我们都知道,总线型拓扑有⼀个问题需要解决——如何确保端⽤户使⽤媒体发送数据时不能出现冲突? 此外,节点是怎么筛选信息的?重要的信息如何保证优先级?以及如何保证信息不出错,正确的传达呢?我将在下⾯的内容中,慢慢解答这些问题。
CAN的通信机制
我们在这⼀节中,详细介绍CAN的各种性质,并且回答上⾯我们提出的问题。⼤家也可以想⼀想,与我的总结相互印证。
双线差分信号
⾸先,CAN的⼀个特性是采⽤双线差分信号
采⽤双线差分信号。其实,我不知道采⽤这种信号到底有什么好处,所以我去百度了。
⼀般情况下,我们把电压1和0作为传输信号的⼿段。但实际上,这也是⼀种差分信号,只不过我们把“地”(GND)作为基准信号。这种情况下,系统的精确度就依赖于“地”的⼀致性。信号源和信号接
收器的“地”的电压可能不同,所以在精度上⽆法得到保证。所以,采⽤双线差分信号的⼀⼤优点就显现出来了。因为基准电压也可以得到控制,信号源和信号接收器的基准电压就⼀定是相同的,⽽且精度也可以得到保证。
第⼆个优点就是抗⼲扰能⼒强。传统的电压传输,“地”是不受⼲扰的,但是传输中的信号就会得到⼲扰,所以会出现错误。但是采⽤双线差分信号,要⼲扰⼤家⼀起⼲扰,反正我们看的是差值,差值始终不受影响。
传统传输⽹络中只有0、1。但是,现在如果需要⽤到双极信号。我们就要把电压区间的⼀个任意值(⼀般是中点)看做是⼀个虚地(虚假
的“地GND”)。⾼于这个值的是1,低于这个值的是-1。我们对地的要求就是要很稳定。⽆形中就是要求整个电路很稳定。但是双线差分信号就完全没有这样的顾虑。这就是第三个优点。不⽤电压稳定也能很稳定地传输信号。要求降低了但是质量不会降低。
理解了双线差分信号之后,我们就可以把它抛开了。我们就把它当成是0 1就⾏了。(只是当成是,实际上我们还是需要有双线差分信号这个概念的。)我在后⾯的叙述中也⽤1,0 来代替双线差分信号的隐性信号(1)和显性信号(0)。
为什么显性位是0,隐性位是1?
因为协议的制定者规定,ID越⼩,优先级越⾼。所以⼩的要显⽰出来。所以0是显性位。
不限制节点数量,并可以动态改变节点数量
⼴播发送报⽂
候,不能有⼲扰。在CAN协议中使⽤的是载波侦听多路访问/冲突避免(CSMA/CA)的⽅法。节点在发送报⽂之前,先侦听⼀下。如果有数据
准备好的数据。
传输就不发送了,等着。否则,就⽴刻发送准备好的
多路访问:各节点⼈⼈平等,并⽆⾼下(但是报⽂有啊),所以⼤家共⽤总线(⽽且都是⼴播)。
多路访问:
冲突避免:⼀边发着数据,⼀边要检测,看看是不是别⼈也在发,防⽌发⽣冲突,⼤家都⽩⼲活。
冲突避免:
“回读”机制:节点⼀边发,⼀边还要检查发的是不是对的。
u型管“回读”机制:
如果总线控制器发现ABC在同⼀时间发送报⽂。那到底是允许谁传输成功?优先级怎么判断呢?这⾥就必须提到报⽂的结构了。如图3、4: 报⽂的第⼀个结构是帧起始。只占1位,显性电平,标志着数据帧和远程帧(远程帧的作⽤是向其他节点请求发送相同ID的数据帧)的起始。 RTR是区别数据帧和远真正决定报⽂优先级的是第⼆个结构仲裁段。标准的报⽂,在仲裁段有12位,11位ID以及⼀位RTR(远程发送请求)。(RTR
程帧的标志:显性为数据帧,隐性为远程帧)上⾯提到,ABC都在发,当他们发了第⼀位,控制器开始仲裁(所以ID放在前⾯,根据ID进⾏对⽐),如果⼀致就继续;如果不同的话,根据ID越⼩的优先级越⾼,所以就把发出隐性信号的节点设置为【只听】,禁⽌它继续发出消息,然后发出显性信号的节点继续。这就是“线与”机制
“线与”机制。不过等到总线再次空闲的时候,节点会再次尝试进⾏重发。
接收过滤器:各个节点都有,也是根据ID进⾏判断,⽐较ID与选择器中和接收过滤相关位是否相同。存在⼀个掩码,掩码设置为1的位必须相
接收过滤器:
同;为0则不⽤。
NRZ编码。NRZ编码确保报⽂紧凑,在相同带宽下,NRZ编码⽅式的信息量更⼤。但是NRZ有缺点,如果⼀长串的 除此以外,CAN协议使⽤NRZ编码
基线漂移,因为接收⽅会保持⼀个它所看到的信号的均值,通过均值区分⾼低电平。连续的0或1会导致均值改变,使检测信号中很难0或1会导致基线漂移
位填充的⽅法。即在连续5个1或出现明显的变化。还有⼀个问题是,为了确保发送⽅和接收⽅同步需要有⾜够的跳变沿。因此CAN协议还使⽤了位填充
连续5个0后插⼊⼀个反位。那不仅减少了连续的1或0⽽且还增加了跳变沿的数量。保证了同步性。
帧的结构
1.帧起始SOF
显性位⼀位,表明帧的开始
2.仲裁段
RTR是区别数据帧和远程帧的标志:显性为数据帧,隐性为远程帧。因此远 标准帧的仲裁段有12位,11位ID(序号是28-18)和1位的RTR。RTR
程帧的优先级是不如数据帧的。
扩展帧的仲裁段有32位,前11位是ID,⽤SRR代替了RTR(所以SRR叫做代替远程请求位,隐性)因此,标准帧的优先级⽐扩展帧⾼。然后是IDE标识符扩展(区分标准帧和扩展帧,标准帧的IDE=0,隐性)再次表明标准帧的优先级,然后是扩展ID有18位(序号是0-17),最后是RTR。
3.控制段
标准帧的控制段包含6位,前两位为IDE、r位,IDE位不再赘述,r位是保留位,当前置0,后⾯ 是DLC位占4位,表⽰数据段的长度,单位是字节。DLC位有4bit,所以DLC的值是0-15,数据段的最⼤长度是0-8,但是9-15也不算错误,⽽是默认为8。
扩展帧的控制段也是6位,前两位是r1、r0位,置0,后⾯是DLC位。
4.数据段
蚊子网正如DLC位所表⽰的那样,数据段的长度不定,共有0-64位。但是远程帧是没有数据段的。
共有16位,前15位是CRC位
DEL位。CRC位
CRC位顾名思义,使⽤的是CRC循环校验。发送节点根据发送的序列计算⼀个CRC,CRC位,然后 加⼀位DEL位
接收节点也根据接收的序列计算⼀个CRC,两个⽐对⼀下,判断数据帧是否有效。DEL位是界定符,固定为隐性位,在界定符之前使⽤位填充。
6.ACK段
ACK位,接收节点正确接收之后⽤显性覆盖隐性,发送节点在回读的时候 ACK段⽤于确认报⽂被⾄少⼀个节点正确接收。共有两位,第⼀位ACK位
DEL位同上。
读到显性证明报⽂被正确接收。第⼆位是DEL位
7.帧结束
最后是帧结束EOF共有7位,连续七个隐性位表⽰数据帧结束。
结束之后是ITM:三位,表⽰帧间空格,然后就可以继续发送下⼀帧了。
以上就是帧的结构,接下来就是帧的类型。
帧的类型
标准帧和扩展帧
扩展帧。区别我们上⾯说过了,⽽且标准帧的优先级是⾼于扩展帧的。
根据帧的长度不同分为标准帧
超载帧和帧间空间
卧式钻床帧间空间。烫金膜
错误帧、超载帧
远程帧、错误帧
数据帧、远程帧
根据帧的⽤处不同还分为数据帧
。格式就是上⾯说过的格式。
数据帧:
数据帧:数据帧携带从发送节点到接受节点的数据。
远程帧:向其他节点申请具有同⼀ID的数据帧。和数据帧的区别就是没有数据段。
远程帧:
错误帧:
错误帧:节点检测到错误之后发送错误帧。因为CAN协议的错误侦测⽐较完备,安全性⾼,所以这个要详细讲。
超载定界符。在先⾏的和后续的数据帧(或远程帧)之间附加⼀段延时,表⽰满了,装不下更多超载标志和8个隐性位的超载定界符
ip调度系统
超载帧:
超载帧:6个显性位的超载标志
数据了,不要再发送了。
帧间空间:⼀个3位的ITM+任意位个隐性位,表⽰总线正处于空闲状态,如果是错误帧之后还可能有别的变化,我们在错误帧的详细解释中给出帧间空间:
介绍。
错误检测
CAN协议有⼗分详细的错误检测⼿段。⼀共有5种错误,位错误、位填充错误、CRC错误、ACK错误和格式错误。
位错误:节点回读的时候发现和⾃⾝发出的数值不同的位。不过仲裁或者ACK回读时送出隐性位,⽽检测到显性位则不导致位错误。正如上⽂所位错误:
⾔,仲裁时有线与机制
线与机制,⽽ACK回读时没读到显性位才是有问题的。
位填充错误:在使⽤位填充的段(CRC界定符之前),不允许出现连续6个相同的电平位。例如:111111、000000。
位填充错误:
CRC错误:发送节点的CRC序列和接收节点计算的CRC序列不同。
CRC错误:
格式错误:固定格式位含有⼀个或更多⾮法位。例如:r0、r1固定置0,DEL固定为0,但被置为1,就产⽣错误了
格式错误:
ACK错误:位错误中提及,ACK回读时没读到显性位就是有错。
ACK错误:
位错误、填充错误、格式错误或者ACK错误,错误产⽣之后,在下⼀位发送错误标志。⽽CRC错误的
错误标志在ACK界定符后发送,也就是EOF之前了。错误标志分为主动错误标志和被动错误标志。那么,什么时候应该发什么标志?
每个节点有两个计数器,⼀个是REC接受错误计数器,⼀个是TEC发送错误计数器。发送错误是位错误、格式错误、ACK错误;接收错误是填充错误、格式错误、CRC错误。接收错误产⽣的时候,REC增加;反之,REC减少。TEC类似。REC和TEC的数值会引发节点状态改变。
节点的三种状态
1.主动错误
REC和TEC都在0-127。这种状态下,节点可以进⾏正常的总线通信,错误产⽣时发送主动错误标志(6个连续的显性位)
2.被动错误
REC或TEC≥128。这种状态下,进⾏受限制的总线通信,错误发⽣时发送被动错误标志(6个连续的隐性位)
3.总线关闭(Bus Off)
真空注型机节点禁⽌参与总线通信。可以由⽤户申请恢复通信(发送128个11位隐性位)。
主动错误状态下和被动错误状态根据成功传输和失败传输改变REC和TEC进⾏状态的转化。两种状态下发出的错误帧的格式也不⼀样,主动错误标志是6个显性位,⽽被动错误标志是6个隐性位。然后是错误标志叠加,占据0-6个位,由于错误标志违背了位填充的规则,所以别的节点会发送错误标志,从⽽产⽣过了错误标志叠加。最后⼀段是错误界定符,8位连续隐性位。节点发送错误标志之后,监听总线,总线上出现隐性位后,节点发送剩下7个隐性位。
先写这么多吧,后⾯还有时序系统过于复杂。我暂时也没有理清楚。有缘再更新~