随着以太网的稳定性、抗干扰性和带宽问题的逐步改善,以太网正在大规模进入工业控制领域。
用于工业过程控制、通信、航天器和导航系统中的网络对可靠性及其响应故障的快速性要求极高。当前,冗余设计作为一种提高设备可靠性的有效方法,已经得到了广泛的应用。对于网络系统中的单个节点,常常需要对网卡进行双冗余备份,即每个节点都采用2块网卡(或2个网口),中间用集线器或交换机互连,当正常通信的网卡或线路出现故障时,该节点能自动地切换到备份网卡进行通信。图1为冗余网络的一种典型联接形式。
具有双冗余网卡的节点虽然有2块网卡,2条通道,但对于高层应用系统来说,仍呈现单网卡的特征。具体来讲,2块网卡共有1个物理地址,1个IP地址。根据TCP/IP参考模型,TCP/IP协议族可以分为应用层、传输层、网络层和链路层4层,冗余网卡技术可以在其中各个层面中实现。
VxWorks、MUX与网卡驱动程序
嵌入式实时操作系统VxWorks的网络协议栈与网络设备驱动的接口有2种:一种是标准的BSD4.4Driver,它将Driver和协议紧密关联在一起,不利于多协议的支持;另一种标准是VxWorks特有的,它将Driver和协议栈隔离开,使二者通过一个称为MUX的薄层相连,使得网络服务免受特定的网络接口驱动程序的影响,达到Driver独立于具体协议的目的,从而实现多协议的支持,三者间的关系如图2所示。
目前版本的MUX支持2种网络驱动程序接口模式:增强型网络驱动程序接口( END)和网络协议工具包(NPT)驱动程序接口。现以END型网卡驱动为例介绍如何在VxWorks5.4下的NE2000兼容网卡驱动程序中实现双网卡冗余设计。正常情况下,协议驱动程序通过MUX层提供的NIC的句柄来提交请求,这个句柄是调用EndLoaD()获得的;然后MUX层调用网卡驱动程序中的接口函数,实现高层协议驱动程序的请求。
在应用层实现双冗余网卡技术的分析
在系统中对网卡进行双冗余备份,即1块网卡在正常工作时使用,另1块网卡作为备份。备份用的网卡处于激活状态。在正常通信的网卡出现故障或系统需要时,备份用的网卡能实时地、自动地切换到继续工作。显然,这就要求2块网卡只能使用同1个物理地址和同1个IP地址。从应用程序的角度看,只会看见1块网卡在工作,不关心是哪块网卡在工作及如何切换。
理论上讲,冗余网卡技术可以在OSI各层中实现,而且越在底层实现,检测和切换的速度越快,效果应该越好。其他利用应用层实现双冗余网卡的主要方法是在程序中发起任务,以查询的方式不断对当前工作网卡的工作状态进行判断,当判断出当前使用的网卡处于非正常状态的时候,将删除当前网卡的路由,在主机列表中删除当前主机名,并解除网卡与协议的绑定;然后进行备份网卡的配置:为备份网卡绑定协议,设置子网掩码和IP地址。用此种方法实际测试,测试中使装有双网卡的主机不断向外发送广播报文,同时用网络分析软件接收。测得2个网口的切换时间平均为120ms,在切换期间有很多广播报文丢失。可见在应用层实现双网卡冗余备份技术,网卡切换速度慢,不利于网络的可靠性和实时性。
在驱动程序中的实现
在VxWorks系统中,相同类型的网卡使用同一个驱动程序,网卡之间由驱动程序提供的句柄来区别。MUX调用NIC驱动程序的接口函数时,都会把网卡的句柄传入函数中。这就为在驱动程序中实现双网卡冗余备份提供了基础。因此要实现网卡的双冗余备份,最理想的办法是在NIC驱动程序中实现。
数据结构
网卡驱动程序中最关键的数据结构是有关网卡特性的数据结构。每种网卡都有它自己的特性,包括它的单元号、中断向量、I/O基址、物理地址等。
系统启动时,在网卡驱动的装载函数中ne2000EndLoad( )中,会为设备初始化1个数据结构,并分配一个指针指向这个结构。这时定义2个全局指针:
NE2000END-DEVICE * pDrvCtrl-0;
NE2000END-DEVICE * pDrvCtrl-1;
在网卡初始化时把这2个指针分别指向2块网卡的数据结构,通过这2个指针的定义,在MUX调用NIC驱动程序的接口函数时,可以根据网卡的好坏或系统的需要来选择pDrvCtrl-0或pDrvCtrl-1,以调整工作网卡。
发送和接收处理
在上层驱动程序通过MUX调用NIC驱动程序的发送函数时,会传入网卡的句柄,指定要使用的网卡。通常情况下,驱动程序会根据该句柄向相应网卡发出指令,把报文发出去。在双网卡冗余备份驱动程序中,根据需要来指定发送数据要使用的网卡,而不一定使用MUX指定的网卡。如先读2块网卡的Link信号寄存器,判断网络连线的通断,再决定使用哪一块网卡来发送数据。
在接收报文的时候,通常是在中断中进行处理。因为以太网在物理层上的特点,2块网卡都能收到报文,不同的是只有与高层协议绑定的网卡收到的数据才能向上传递。在双网卡冗余备份驱动程序中,不是由MUX指定的网卡句柄来向上传送数据,而是根据当前网卡的工作状态向上层传送数据,即使数据是从另一块网卡上接收来的或另一块网卡没有和高层协议绑定。
单物理地址的处理
通常每块网卡有1个全世界范围内唯一的物理地址,它保存在网卡的PROM中。网卡初始化时,要从PROM中读出物理地址,把它存放在适当的寄存器和数据结构中。
要使2块网卡能相互备份,它们必须有相同的物理地址和IP地址。在双网卡冗余备份驱动程序中,可以用其中1块网卡的物理地址。方法有2种:在驱动程序初始化时只读1块网卡的PROM中的物理地址;或者在网卡驱动程序中的ne2000EnetAddrGet()函数中作修改,完全可以给网卡设定任意的物理地址(只要避免了同一网络中的冲突)。
单IP地址处理
至于2块网卡采用相同的IP地址,可以这样实现:在安装2块网卡时,只让1块网卡有IP地址,另1块网卡没有IP地址。因为给网卡绑定IP地址是在IP协议所在的网络层实现的,所以在网络层以下切换网卡对上层来说是完全透明的。应用程序自始自终只看见1块网卡在工作。图3是从应用程序的角度看双网卡备份的示意图。
效果分析
通过对比实验,在应用层实现双网卡冗余备份的平均网卡切换时间是120ms,在驱动层实现双网卡冗余备份的平均网卡切换时间是5ms,相对于在应用层或其他高层中实现,效率较高,大大缩短双网卡的切换时间,从而降低切换时网络通信丢包的机率。
结束语
分析了VxWorks系统的网络结构模型,提出了在系统底层驱动中实现双网卡冗余备份功能的设想,并进行了设计实现,同时对在驱动程序中实现与在应用层中实现2种方法进行了对比,证明了在驱动程序中不但能够很好地实现双网卡冗余备份功能,而且提高了以太网的实时性和可靠性,在工业以太网蓬勃发展的今天,具有一定的实用意义。