刘玉宾
关键词:VxWorks,嵌入式TCP/IP协议栈,增强型网络驱动,自动切换,冗余备份
引言
随着网络技术的成熟,具有价格低廉、连接方便等优点的以太网己成为各种控制系统接口互联的主要媒介,它作为一种通用网络数据通讯系统,在全球的计算机网络领域已经得到了广泛的应用。把这种成熟、高速、抗干扰能力强的通讯技术应用在实时信息系统,其具有组建成本低、开发手段多样、物理协议及数据协议完善、传输速率高等明显的优越性。而实时信息系统不但要求信息传输速度快,抗干扰能力强,还要求网络具有高稳定性和高可靠性。在网络局部故障或受损时,全系统不至于瘫痪失效。但是,目前各种网络通讯设备与技术的发展都已经基本趋于稳定,要仅仅通过提高任何一种设备自身的可靠性从而提高整个系统的可靠性是难以实现的。采用冗余的思想设计一种冗余网络信息系统来提高整个系统的稳定性、可靠性是切实可行的。
本控制系统使用VxWorks系统提供的功能强大的TCP/IP协议栈实现在双冗余以太网上的高速信息传递功能。本论文针对双冗余以太网在VxWorks下的驱动开发及热切换技术进行了深入的研究,并提出了一个切实可行的解决方案。经过实验验证,很好的解决了这一技术问题。
1 VxWorks下的网络协议栈、MUX接口及END驱动程序
1.1 网络协议栈
VxWorks中的网络协议栈叫作SENS(Scalable Enhanced Network Stack),即可裁减增强网络协议栈。SENS是基于4.4BSD TCP/IP协议栈发展而来的,包含了许多4.4BSD TCP/IP协议栈没有的协议;而且SENS在实现一些协议功能时增加了许多新特性,如在IP协议实现时增加了多播功能。SENS协议栈层次如图1-1所示。
图1-1 SENS网络协议栈
SENS的基本特征和传统的TCP/IP网络协议栈相似,但从图1-1中可以看出SENS最大的特点是在数据链路层和网络协议层之间多了MUX层。在SENS中,网络接口的驱动程序是叫作END(Enhanced Network Driver),即增强型网络驱动程序,它处于数据链路层。IP层和TCP/UDP层合称为网络协议层。在数据链路层和网络协议层之间有应用程序接口(API),这个接口在SENS中叫作MUX(Multiplexer)接口。
1.2 MUX接口
MUX接口如图1-2所示,在网络协议层VxWorks典型地使用TCP/IP协议(也支持其它协议);在数据链路层典型地使用Ethernet,也支持其它数据传输的物理媒体,例如远距离连接使用的串行线路接入方式,如PPP等。但是,无论使用什么物理媒体,网络接口驱动都要用到MUX去与网络协议层通信(数据链路层是一个抽象概念,网络接口驱动程序则是这种抽象概念所描述的功能实现的代码)。
图1-2 MUX接口关系
MUX的目的是分解协议和网络驱动程序,从而使它们几乎独立于彼此。这种独立使添加新的驱动程序和协议变的简单。例如若想添加一新的END驱动,只要其满足MUX接口的要求所有现有基于MUX的协议均可使用新的驱动程序。同样若添加一新的基于MUX的协议,只要其满足MUX接口的要求任何现有的END驱动均可通过MUX来访问新的协议。
1.3 网络协议、MUX接口及END驱动程序关系
MUX层作为独立的一个阿络层有其自己的功能函数.但这些功能函数只是其上下两层通信的接口。网络橼议层和网络驱动与MUX接口的调用关系如图1-3所示。
图1-3 网络协设层和网络驱动与MUX接口的调用关系
网络协议需提供下面的接口功能函数:
- stackShutdownRtn()
- stackErrorRtn()
- stackRcvRtn()
- stackTxRestartRtn()
当MUX接口层需要与协议层相互通信时,就调用以上的功能函数。想要使网络协议层能够使用MUX,必须至少实现以上四个功能函数。如果用户想添加新的协议到MUX,同样必须实现以上四个功能函数。
MUX则实现muxBind()、muxUnBind()、muxlDevload()等。对于上层协议来说,MUX必须为它提供发送数据的接口;同时MUX也要识别上层协议的请求。所以为了实现两者之间的通信,协议或服务程序可以通过调用函数muxBind()来实现。函数muxBind()将上层协议和底层END驱动绑定,绑定的过程就是MUX知道上层协议希望从哪个END发送或接收数据。
网络协议层和网络驱动接口都要根据各自的需要使用MUX接入点。由于MUX是由系统提供的,不需要在应用时再进行额外的编码工作;只要在使用时,填入正确的参数即可。
网络接口的驱动程序要完成endLoad(),endUnload(),endSen()等功能函数。MUX使用这些功能函数来与网络驱动程序通信。当编写或加载一个使用MUX的网络驱动程序时,必须实现图1-3中driver的所有功能。这些功能函数都是针对具体的网络接口,即每一个网络驱动程序中都要有这些功能函数。
2 基于END的双冗余以太网卡驱动设计
图1-3可知,设计一个基于END的以太网卡驱动必须事先如下函数:加载设备endLoad()、卸载设备endUnload()、设备控制接口endloctl()、发送数据给设备endSend(),启动设备endStart()、停止设备endStop(),轮询发送endPollSend()、轮询接收endPolIReceive()、增加1个组播地址endMcastAddrAdd()、删除1个组播地址endMCastAddrDel()、取得组播地址表endCastAddrGet()等。
为了使基于END的以太同卡驱动挂接到MUX接口,以供VxWorks的网络协议层使用,首先要实现上文描述的函数。基于SMSC公司LAN91C111芯片使用说明书及其提供的驱动程序实例,对其根据MUX接口的要求进行了修改。定义了一个名为lan91c111FuncTable的函数功能表实现MUX接口所要求的所有功能函数。lan91c111FuncTable的函数功能表定义如下:
LOCAL NET_FUNCS lan91c111FuncTable=
{
(FUNCPTR)lan91c111Start,
(FUNCPTR)lan91c111Stop,
(FUNCPTR)Ian91c111Load,
(FUNCPTR)lan91c111UnIoad,
(FUNCPTR)lan91c111loctl,
(FUNCPTR)Ian91c111Send,
(FUNCPTR)lan91c111MCastAddrAdd,
(FUNCPTR)lan91c111MCastAddrDel,
(FUNCPTR)lan91c111MCastAddrGet,
(FUNCPTR)lan91c111PollStart,
(FUNCPTR)lan91c111PollStop,
};
Lan91c111FuncTable的函数功能表中的函数具体实现源代码可参见开发的lan91c111End.c文件。
3 冗余双网卡热切换的实现
本文的双冗余网络采用的是一块电路板上集成两块网卡的方式。虽然网络中有两块网卡,两条通道,但对于高层应用系统来说,仍呈现单网卡的特征。具体来讲,每个节点的两块网卡只能有一个IP地址。在某一特定时刻,只有一块网卡处于工作状态,另一块网卡作为备份。备份用的网卡不发送或接收数据,但已经处于激活状态。在正常通信的网卡出现故障时,备份用的网卡能实时地、自动地切换过来继续工作。从应用程序的角度看,整个切换过程是透明的。
VxWorks操作系统支持多个网络适配器,允许系统在初始化时把所有的网络适配器驱动起来。这就为在VxWorks下实现网络热切换奠定了基础。多数网卡都具有自我诊断能力,并根据相应的状态对其内部状态寄存器的值进行相应的修改。可以通过网卡驱动中的底层函数读取网卡芯片内部的该状态寄存器的值,以获得网卡及其所在的链路是否正常,以确定是否需要进行切换。在切换至备份网卡时,首先需要删除为原先网卡所绑定IP协议栈,并在ARP列表中删除网卡的IP所对应的条目;然后使用同一个地址来初始化备用网卡,主要包括为备用网卡绑定IP协议栈,指定IP地址等。为了能够更好的说明整个切换过程,需要深入地分析IP协议栈绑定与ARP协议。
3.1 IP协议栈绑定
在将网络驱动添加到MUX后,完成了网络层次中的数据链路层的设置。为了使用户的应用程序能够使用网络,必须将TCP/IP协议与数据链路层相联系,即将IP协议栈绑定到MUX中特定的网络接口。
建立TCP/IP协议与数据链路层的联系包括如下步骤:
1) 绑定IP协议栈到MUX中特定的网络接口,需调用ipAttach()函数;ipAttach()函数自动调用MUX的muxBind()函数将上层协议和底层END驱动绑定,绑定的过程就是让MUX知道上层协议希望从哪个END发送或接收数据。删除绑定到MUX中特定网络接口的IP协议栈,需调用ipDetach()函数,ipDetach()函数自动调用MUX的muxUnBind(),muxUnBind()函数将上层协议和底层END驱动绑定删除,使得上层协议不再从该END接收或向其发送数据。
2) 为网络接口指定IP地址和子网掩码。网络接口代表通过一块网卡到网络的物理连接,我们的lan91c111网卡就包含两个不同的网络接口。为了能通过IP协议栈使用一特定的网络接口,必须为其指定32bit的IP地址和子网掩码。子网掩码的作用是用于从IP地址中区分主机部分和网络部分。IP协议使用此信息决定某一个特定的IP地址是否为直接可达。并且这些信息也用于在路由表中创建一个代表本地地址信息的条目。为网络接口指定IP地址和子网掩码,首先调用ifMaskSet()为网络接口指定子网掩码;然后调用ifAddrSet()为网络接口指定IP地址。之所以要求这样的顺序,是因为ifAddrSet()函数中需使用ifMaskSet()的结果指定其广播地址。
3.2 ARP协议分析
我们的双冗余网卡具有两块网卡芯片,其具有不同的以太网地址(又称MAC地址)。对于处于数据链路层的网卡驱动程序从不检查IP数据报中的目的IP地址,而是根据48bit的MAC地址来确定目的接口的。当其中一块网卡出现故障时,另一块网卡不能立刻地代替它继续工作,这是因为它们的物理地址不同,所以它不能接受到发向前一块网卡的数据。下面我们首先对ARP协议进行分析,然后提出解决这个问题的方案。
IP地址是运行TCP/IP协议机器的通用标识,它的分配是独立于机器的物理硬件地址的。但是IP地址自身并不能使报文到达其目的地。为了把网络报文通过物理网络从一台计算机发送到另一台计算机,网络软件必须把IP地址映射到一个物理硬件地址,并用这个硬件地址传输该帧。当一台主机把以太网数据帧发送到位于同一局域网上的另一台主机时,是根据48bit的以太网地址(又称MAC地址)来确定目的接口的。设备驱动程序从不检查IP数据报中的目的IP地址。地址解析协议ARP(Address Resolution Protocol)使用底层网络通信系统完成IP地址到对应的以太网地址之间的动态映射。
通过广播ARP请求,一台机器可使用ARP找到另一台机器的硬件地址。这个请求中包含一台主机的IP地址,需要找到的是该主机的硬件地址。这个网络上的所有机器都会收到ARP请求。如果该请求与一台机器的IP地址匹配,则该机器发出一个包含所需硬件地址的应答。应答是直接发给一台机器的,不使用广播形式。为了提高ARP的效率,每台机器都把IP到物理地址的绑定保存在高速缓存中,免除了大多数ARP广播请求。
从功能上讲,ARP被划分成两部分。第一部分在发送分组时把IP地址映射到物理地址上,第二部分回答其他机器的请求。给定一个目的站的IP地址,软件查询它的ARP缓存,看是否有从该IP地址到物理地址的映射。若有,则软件提取该物理地址,把数据放在使用该地址的帧中,并发送该帧。若没有,则软件必须广播一个ARP请求并等待应答。ARP代码的第二部分处理来自网络的ARP分组。当ARP分组抵达时,软件首先提取发送方的IP地址和物理地址对,并检查本地的高速缓存,看是否己经保存有该发送方的表项。如果有这个IP地址的表项,处理程序就用从分组中获得的物理地址覆盖缓存中原先的物理地址,从而更新表项。此后接收方才处理ARP分组的其他部分。
通过对地址解析协议ARP的分析,可以采用如下的方案解决上文提出的由于两块网卡MAC地址不同,备份网卡不能立刻地代替故障网卡继续工作的问题。当调用ipDetach()函数删除绑定到故障网络接口的IP协议栈,此时断开了TCP/IP协议与数据链路层相联系。但此时由于本杌的IP地址到故障网卡MAC地址的映射关系依然存在于本机和网上其他主机的ARP地址解析表中。所以必须要清除本机和网上其他主机的ARP地址解析表中的这个条目。实现的方法是:清除本机ARP地址解析表中的条目通过调用arpDelete(本机IP);清除网上其他主机的ARP地址解析表中的这个条目,通过调用ifAddrSet()为网络接口指定IP地址的同时,在网络上广播含有绑定的ARP广播,使得网上所有主机更新ARP地址解析表中的这个条目。
3.3 实现方法
首先修改VxWorks操作系统的配置,使其支持多网络适配器,系统在初始化时能够把所有的网络适配器驱动起来。
为了可以实时监视网卡及其所在链路的工作状态,设备初始化完成后,启动一个监控任务。该任务的功能是对当前使用的网络适配器进行不问断定时查询,当发现该网络适配器失效时,就切换到另一个网络适配器上,如果切换成功,这个网络适配器就成为当前的网络适配器,然后复位故障设备,该任务继续对当前的网络适配器进行监控。判定一个网络适配器是否失效的方法是,读取网络适配器控制芯片的相关寄存器,根据其状态判定。系统查询网络适配器的时间间隔,可以根据实际系统需要进行调整,在不影响性能的前提下尽量减少故障恢复时间。
读取网络适配器的状态寄存器的方法为:
int flag=intLock(); /*关中断*/
State=LNCPHYAccess(); /*读取网卡芯片内部的状态寄存器*/
intUnlock(int flag); /*开中断*/
作为双冗余备份,两个接口需要的是同一个IP地址,这样就存在了地址冲突的问题。那么在使用新的接口之前必须去掉原先的接口的IP并在主机ARP列表中删除它。否则,不可能以同一地址来驱动第二个接口。切换网络适配器的方法如下:
1) 删除为故障网卡所绑定IP协议栈,即把IP网络层和出现故障的接口链路层断开;
2) 在ARP列表中删除网卡的IP所对应的条目,即删除和该接口相连接的路由;
3) 为备份网卡绑定IP协议栈,即把IP网络层和目的接口链路层建立新的连接;
4) 为备份网卡配置IP地址,并在网络上广播含有绑定IP的ARP广播,使得网上所有主机更新ARP地址解析表中的这个条目。;
5) 复位出现故障的网卡。
轮询法的优点是纯软件完成,不需在硬件上作更多工作,易于实现;无需占用额外的CPU硬件资源,只要两个网络适配器能正常工作,就可通过软件实现冗余网卡热切换。但是轮询法实现冗余网卡热切换也存在一些闯题。例如,每次读网络适配器的线路状态寄存器时都要先关掉中断,读完成后再把中断打开。由于网络适配器是中断收发数据,在关掉中断时,可能造成网络适配器数据包丢失。为了减少丢包,就需增加查询网络适配器的时间间隔,这就与减少故障恢复时间的要求相矛盾。
3.4 典型程序示例
完成冗余热切换的核心程序如下:
ipDetach(OldId,"OldName");
arpDelete(MY_IP);
ipAttach(nNewId,"NewName");
ifMaskSet(new,Oxffffff00);
ifAddrSet(new,MY_IP);
4 双冗余热切换以太网卡的性能测试
基于lan91c111网卡芯片的双冗余以太网卡测试内容包括网卡故障恢复时间测试、切换过程中性能测试,测试环境为Tornado 2.2/VxWorks5.5。
4.1 网卡故障恢复时间测试
计算网卡发生故障时,完成切换所需的时间消耗(最大值和平均值)。理论值计算T,监控程序检测周期;t,切换时间(经计算切换时间为1~5ms);Tr,故障恢复时间;△t,其他消耗时间(任务切换平均时间、系统调用时间等等)
最小恢复时间Trmin=t+△t
最大恢复时间Trmax=T+t+△t
平均恢复时间Travg=(Trmin+Trmax)/2
实测结果:实测方案采用“丢包计数法”。测试程序以1ms为周期连续发包40s。测试人员在20s中随机插拔网线10~20次。接收端接收数据并对序号不连续数据的时间间隔进行计算,最后统计总丢包数、数据流中断的次数以及平均丢包数。根据平均丢包数计算平均故障恢复时间。实测中,网卡切换任务的检测周期T为20ms,选择其中两组结果,如下图所示。经多组测试,与理论平均值吻合。如果故障恢复时间过长,可以通过提高监控任务优先级或者设置为不可任务抢占及不可中断抢占来解决。
图4-1第一组测试结果
图4-2第二组测试结果
4.2 切换过程中性能测试
测试当工作网卡发生故障,切换到备份网卡的过程中网络的丢包情况。
测试方案:主要分为网卡接收数据与发送数据两个方面的测试。
1)网卡接收数据测试:采用模拟发送设备将所发出的包编号,然后依次发出。备测网卡所在的收方接收并记录。连续发送1000包,在此过程中随机拔掉网线产生网卡切换。接收端接收数据并对序号不连续数据进行统计,计算切换导致的丢包数。
2) 网卡发送数据测试:采用备测网卡模拟发送,井将所发出的包编号,然后依次发出。模拟收方接收并记录。连续发送1000包,在此过程中随机拔掉网线产生网卡切换。接收端接收数据并对序号不连续数据进行统计,计算切换导致的丢包数。
测试结果:在Tornado 2.2,VxWorks 5.5环境下结果如下。
1) 同卡接收数据测试结果:模拟发送设备发包频率为50次/秒,网卡状态监控任务查询网卡状态频率50次/秒的情况下,统计10次。切换过程中测试结果如表4-1所示;
表4-1网卡接收数据测试结果
2) 网卡发送数据测试结果:网卡所在设备发包频率为50次/秒,网卡状态监控任务查询网卡状态频率50次/秒的情况下,统计10次。切换过程中测试结果如表4-2所示;
表4-2网卡发送数据测试结果
3) 当网卡接收与发送的数据频率小于50次/秒时基本上不会发生切换过程中的丢包。当网卡接收与发送的数据频率大于50次/秒时,发生切换过程中的丢包概率会随着频率的增加而增加。
测试结果分析:通过对表4-1与表4-2的分析可以看出,在上文中测试的网卡切换时间为1~5ms,与这个时间窗口冲突的接收与发送缓冲区的包将被丢弃。原因是网卡切换过程中发生了TCP/IP协议栈的删除与重新绑定。
5 结束语
本论文针对双冗余以太网在VxWorks下的驱动开发及热切换技术进行了深入的研究,并提出了一个切实可行的解决方案。
对于嵌入式实时操作系统VxWorks的TCP/IP协议栈的原理和思想进行了深入的研究,针对XXX型控制系统网络功能要求,自主开发了双冗余网卡驱动,并且实现了基于VxWorks操作系统的热切换技术。通过实际试验验证,本设计很好的解决了在XXX控制系统上实现双冗余网络实时、可靠、高速的进行信息传递这一技术难题。