"); //-->
在这个“网文”兴盛的时代,单纯的技术帖越来越不招人喜欢了。
怎样才能既传递技术的干货,又不至于陷入专业概念的漩涡?或者说,能不能像东方臻选的董宇辉那样,既卖了货,还能双语授课?
洒家思索再三,唯一的方法也许是走下专业的神坛,抛开拗口的概念,靠着侵淫多年的思考把背后的原理讲得有趣、直白又简单。
今天讲的是在工业自动化、汽车等领域应用很广泛的CAN总线。
CAN总线的多主结构和内容寻址
上个世纪七八十年代超大规模集成电路的发展,开启了汽车行业轰轰烈烈延续至今的电子化进程。
各种电子控制单元(ECU)的出现,让ECU之间的信息交互变得越来越普遍。在ECU交互比较简单时,最直接也最简单的方案便是一个信号一根线。
一支穿云箭,千军万马来相见。但在没有CAN总线的年代里,一根实体线,只能单个信号来见面。
毫无疑问,这种方式会导致线束数量不断翻番,实在不是一个好方案,于是乎,汽车专家们把目光投向了串行总线。
当时,RS232-RS422-RS485总线已经将触角延伸到了工业自动化领域,其中,RS485总线采用双绞线差分传输,支持多节点数据通信,似乎到上车只差临门一脚。但是,RS485采取主从结构以及分配设备地址这两大缺陷,使得汽车专家决定另起炉灶,开发新的串行总线。
新的串行总线-CAN,没有主从的概念,以ID而非设备地址进行寻址,完美克服了这俩在汽车应用中格格不入的缺陷。
爱思考的小伙伴,端起了大蒲扇,主从结构怎么就成了缺点?为不同节点分配各自的设备地址,又存在什么缺陷?
要搞明白第一点,需要先看看主从结构的特点,至于第二点,需要对照一下汽车应用的要求来看看。
武林至尊,宝刀屠龙,号令天下,莫敢不从。在主从结构里,一主多从,主节点不发号令,从节点便永远没有参与通信的可能。
在主子“翻牌子”之前,从节点唯一能做的便是洗得白白净净,耐心坐等!
据说,这种方式主要是为了防止多个节点向总线上发送数据导致的错乱。
在没有更好的方法解决大家同时访问总线的挑战之前,这种主从结构似乎是唯一的答案,但是,它的缺点显而易见!
首先,从节点没有主动发送数据的权力,主机一旦瘫痪,整个网络就玩完。
其次,由于不能同时竞争总线,通信效率也只能维持在较低的区间,对于有高速和实时要求的应用场合,这种方式怎么玩得转?
你就说,在汽车的总线通信网络里面,行车安全、动力操控、告警显示相关的那些小主儿,哪个能坐等?
所以,必须抛弃主从结构,寻找一种新的解决方案。竞争和仲裁就是CAN总线标准给出的答案。
再来看分配设备地址的缺点。
汽车电子化是随着半导体技术的发展而不断升级的一个进程,主机厂为了保持产品的竞争力或者满足用户的期待,会引入新的ECU,加入新的功能,在这种升级、扩展需求面前,固定设备地址等于自套枷锁,给挂接新节点的网络升级带来困难。
CAN总线,通过报文ID这种内容性的寻址,解决了升级扩展的挑战。
最后总结一下CAN总线的突出特点:
不分主从,可自由竞争总线;
通过ID“寻址”,可以灵活扩展。
CAN总线的竞争和仲裁
说到对资源的竞争,洒家总会想起电影《1942》里头,那些饥饿的难民拿着耙子、铁锹、木棍攻打大地主家,以争夺粮食这个能活命的资源的画面。
资源,有时候就是生命线!
不过,计算机的世界很体面,尽管CAN总线只有两根线(CANH和CANL),没有了主节点这个“话事人”在中间调度转圜,但是,博世的天才工程师们依然想出了方法,可以避免没高没低的节点对总线资源的争抢。
将一头大象放进冰箱需要三步,博世解决CAN节点竞争总线的方案却只需要两步。
第一步,只有在总线空闲时,才开始发送报文;
第二步,如果大家同时开始发送报文,则在仲裁场一决胜负。
为了讲明白这一点,需要先给出CAN总线的报文格式,或者说帧结构,如下图所示。
关于第一步,需要着重搞清楚的是何谓“总线空闲”,以及,为什么总线空闲能有效避免大家伙一哄而上地搞乱了总线。
总线空闲
在CAN总线标准里,将总线上出现连续11个位的隐性电平定义为总线空闲。
隐性电平即CAN总线上数据为1时对应的总线电平(数据为0时便是显性电平),这里的总线电平,可以认为是CANH和CANL上各自的电压,也可以认为是两者的电压差。
至于具体什么样的电压水平,ISO11898-2和3中分别给出了高速CAN和低速CAN的电压标准。
这里,以ISO11898-2为例进行说明。
CANH对地3.5V,CANL对地1.5V时,总线电平为显性电平,对应数据0。
CANH对地2.5V,CANL对地2.5V时,总线电平为隐性电平,对应数据1。
或者说,电压差在2V左右时,对应数据1,电压差在0V左右时,对应数据0。
这里面,大家经常搞混淆的便是显性电平对应数据0,隐性电平对应数据1。因为,根据大家的“直觉”,道生一,一生万物,没有前面的1,后面隐藏了多少0也无济于事,所以,本该显性为1、隐性为0的嘛。
据说,女孩子的“直觉”很准,不过好在,这个世界,不讲直觉,讲科学!
CAN总线之所以把0定义为显性,是因为CAN总线执行“线与”机制,0&1还是0,所以,在0面前,1自动隐身,总线上显出来的是0,故显性为0,隐性为1。
在显性面前,1是默默含藏的,1是甘愿隐身的,正是因为1有了这种包容的精神,才能1生万物!
至于为何连续11个隐性位代表总线空闲,这一点可以从帧格式里找到答案。
首先,CAN总线是半双工通信,半双工的特点是节点可发送可接收,但是不能同时发送。在CAN通信中对应的情况便是,当一个节点占据了总线并发送报文时,其它节点只能处于接收状态。
那么,最有效率的半双工通信做法是什么?等待发送报文的节点接收完报文后就马上发送报文!
其次,CAN通信里有一个位填充机制,不允许在报文的SOF、仲裁场、控制场、数据场、CRC场中连续出现6个相同的逻辑位,换句话说,在CAN报文传输的主要过程(即上述那几个场,有的技术帖称之为“域”或“段”,对应的英文为Field)中,不可能出现11个位的隐性电平。
但是,为了保证总线通信的效率,允许在EOF场(End Of Frame)和IFS(Inter Frame Space)中出现。
根据CAN帧结构,报文结尾的EOF场和IFS场为连续7+3=10个隐性位,那么,为了让等待发送报文的节点可以在确认总线空闲的第一时间启动报文发送,是不是11个隐性位正好合适?
在外行的眼里,上个报文的结尾10个隐性位,总线空闲定义为11个隐性位,简直巧的不能再巧。
可在内行者的眼中,这是设计上的巧妙,是严丝合缝的独到,是天才的光芒,在灼灼闪耀!
竞争与仲裁
在人类社会中,看到他人在忙就不打扰是一种基本的素养,如前所述,CAN节点也是这样有涵养的谦谦君子。
但,君子待时而动,顺势而为,CAN节点一边监听总线是否空闲,一边在确认总线空闲的第一时间去竞争宝贵的总线资源。
CAN节点通过SOF,打响了争夺总线资源的第一枪。
显然,为了避免混乱,需要有一种合适的手段,尽快地仲裁出答案,决定自己是继续占有还是放弃对总线的主权。
博世的科学家们,引入了一种非破坏性仲裁的方案。
即,各个节点在仲裁场里拿出报文ID,通过比大小的方式公平竞争。
在这里,ID越小,优先级越高,其竞争总线的胜率也就越高。
之所以如此,还要回到前面讲解显性电平和隐性电平的“线与”机制。
图例中,节点A的报文ID最大,节点C的报文ID最小。节点A、B、C在未决出胜负之前,都一边向总线发送报文ID里的数据位,一边监听总线。
因为总线的线与机制,节点A发出的1和节点B/C发出的0进行“与运算”之后,总线上的数据位依然为0。节点A监测到自己发送了1却回读到0后,自动退出总线竞争,转入接受模式,同理,节点B也在随后退出了对总线的竞争,ID最小的节点C最终夺魁。
比大小,这个人类社会解决分歧的最原始、最有效的方式,竟然在CAN总线这么一个高大上的地方找到了用武之地。
只能感叹,这个世界真奇妙!
CAN总线的门道还很多,且等咱家慢慢跟你聊~~
文:三德子
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。