论文部分内容阅读
【摘要】文章主要讲解如何通过VxWorks的MUX(多元网络接口)实现自有协议的开发。
【关键词】VxWorks;MUX;自有协议
【中图分类号】TP393【文献标识】A
【文章编号】1671-5969(2007)06-0178-02
一、概述
VxWorks嵌入式操作系统是美国WINDRIVER(风河公司)公司于1983年开发的一种嵌入式实时操作系统,它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航天等高精尖技术及实时性要求极高地领域。经过数十年的发展完善,VxWorks嵌入式操作系统已经成为实时嵌入式系统的事实上的工业标准和军用标准。
自有协议的开发一直是嵌入式系统开发的难点。在传统的嵌入式系统中底层网络驱动和协议是紧密相关的。当协议改变时,网络驱动也要进行修改。这给系统的开发和维护增加了很多的难度。在VxWorks中,WINDRIVER提供了一个MUX层。MUX层的特点是:它可以完全屏蔽嵌入式系统的底层网络驱动和上层协议的关联,使网络驱动程序和协议之间没有内部交换数据,它们只能通过MUX间接相互作用。图1展示了协议、MUX、网络驱动之间的关系。由此可以看出MUX的目的是分解协议和网络驱动,从而使它们几乎独立彼此。这种使增加新的网络驱动和协议变得简单。如想添加一个新的END(网络驱动),所以现有基于MUX的协议可使用新的网络驱动。相同的,如想增加一个新的基于MUX的协议,任何现有的END均可通过MUX来访问新的协议。
二、MUX的分析
下面我们对VxWorks的MUX进行简要的分析。图2所示为VxWorks系统中MUX、协议和网络驱动各标准API之间的关系。
从图2我们可以看到MUX层的所以标准API及各标准API和协议、网络驱动API的调用关系。箭头表示每个调用程序的入口点。例如muxSend()调用endSend()。注意到,协议通过调用muxSend()开始传送,但图2中并没有指出它的协议程序名。此程序为非标准API。
三、协议的实现
任何要接收数据包的协议首先要将其比绑定到MUX上,通過MUX和设备连接起来。协议通过调用muxBind()来完成这个工作。下面为muxBind()的原型:
Void * muxBind
(
char * pName,/*设备名*/
int unit,/*设备单元号*/
BOOL (*stackRcvRtn) /*接收函数*/
(
void * pEnd, long type, M_BLK_ID pNetBuff,LL_HDR_INFO
* pLinkHdr,
void * pCallbackId
),
STATUS stackShutdownRtn( void * pCookie, void * pSpare),/*关闭函数*/
STATUS stackRestartRtn( void *pEND, void *Pspare),/*复位函数*/
Void stackErrorRtn(void * pEnd, END_ERR pError, void * pSpare), /*错误处理函数*/
long type, /*从RFC1700或SAP中获得的协议类型*/
char *pProtoName, /*协议名*/
void *pSpare /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/
)
这里我们要特别注意的是muxBind()中的long type(协议类型)。MUX使用此协议类型来区分协议的优先权。这个优先权决定哪个协议先获得接收数据包的处理权利。当驱动程序传送给MUX一个数据包时,驱动程序包含一个指向END_OBJ结构的指针(END_OBJ结构如图3)。此结构还包含一个protocols成员、关注设备的协议清单(NET_PROTOCL结构清单)首部。此清单中的协议顺序决定拉哪个协议优先处理数据包。MUX负责保存此清单。
协议类型VxWorks中有三个典型值,分别时MUX_PROTO_
SNARF、MUX_PROTO_PROMISC、MUX_PROTO_OUTPUT。
MUX_PROTO_SNARF:协议获得完整的接收数据包。
MUX_PROTO_PROMISC:协议优先处理接收数据包,被协议处理部分将被屏蔽。
MUX_PROTO_OUTPUT:协议获得输出数据包。
当协议在它的muxBind()中规定一种MUX_PROTO_SNARF类型,则MUX在END_OBJ.protocols清单首部添加一协议。注意VxWorks在任何时候只允许MUX下有一MUX_PROTO_SNARF类型协议激活。当协议在它的muxBind()中规定一种MUX_PROTO_PROMISC类型,则MUX在END_OBJ.protocols清单的尾部添加一协议。若协议在muxBind()中还规定了其他类型,则MUX在清单中MUX_PROTO_SNARF协议后添加这些类型的协议(若无MUX_PROTO_SNARF协议则在清单首部添加)。这种协议添加方式保证了在接收数据包之前,低优先级的协议无法盗用或破坏高优先级的协议的数据包。
协议的标准API函数我们由图2可以看到有四个:stackShutdownRtn( )、stackRcvRtn( )、stackError()、stackTxRestartRtn()。它们的功能如下表2:
StackRcvRtn()是协议里最重要的API,MUX通过它来传递数据包给协议。协议对数据包的处理也是由其完成的。它的原型如下:
BOOL stackRcvRtn
( void * pCookie, /* 调用muxBind()后的返回指针,用来识别MUX将协议绑定到那个设备上* /
long type, /* 协议类型*/
M_BLK_ID pNetBuff,/*一个指向包含数据包和连接级信息的mBlk结构指针*/
LL_HDR_INFO *pLinkHdr,/* 返回包含首部信息的一个LL_HDR_INFO结构,首部信息取决于END执行的特定数据连接层 */
void * pCallbackId /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/
)
在VxWorks中在一个设备上加入一个自有协议,当底层网络驱动完备时,我们只要将协议层的四个API函数写好并通过muxBind()绑定于设备上,协议即可生效。为了加深理解,下面以一个截获IP接收数据包的程序代码为例。
LOCAL BOOL monitorRecvProcess /*接收数据监测*/
(
void * pCookie,
longtype,
M_BLK_ID pMblk,
LL_HDR_INFO *pLinkHdrInfo,
void *pSpare
)
{
int i;
printf("DataMonitorByMux>Received data(len=%d):\n",pMblk->
mBlkHdr.mLen);
for(i=0;imBlkHdr.mLen;i++)
printf("%3x", *((unsigned char *)pMblk->mBlkHdr.mData+i));
printf("\n");
return FALSE;
}
STATUS muxMonitorStart(char *ifname,int unit) /*程序启动*/
{
monitorRecvBindCookie = muxBind (ifname, unit, (FUNCPTR)
monitorRecvProcess,NULL, NULL, NULL,MUX_PROTO_SNARF, NULL, NULL);
if(monitorRecvBindCookie==NULL)
{
logMsg("monitorRecvBindCookie:Can't bind to %s%d!\n",ifname,unit);
return(ERROR);
}
logMsg("DataMonitorByMux:%s%d Bind OK!!\n",ifname,unit);
return (OK);
}
STATUS muxMonitorStop(char *ifname,int unit) /*停止監测*/
{
if(muxUnbind(monitorRecvBindCookie,MUX_PROTO_SNARF,(FUNCPTR)monitorRecvProcess)!=OK)
{
logMsg("monitorRecvProcess unBind err!\n");
return ERROR;
}
return OK;
}
代码中monitorRecvProcess()即为协议中的StackRcvRtn(),它通过muxBind绑定于网络设备上,通过muxUnbind()从设备上卸载。monitorRecvProcess()可以截获网络设备上的所以IP接收数据包。
四、结语
通过上面的分析可以得到结论:由于Vxworks嵌入式系统为我们提供了一个MUX层,屏蔽协议和网络驱动之间的联系,让协议和网络驱动各自独立,使得用户实现自有协议变得简单、高效。
【参考文献】
[1] VxWorks Network Programmer's Guide.
[2] VxWorks BSP Developer’s Guide.
[3] Bbs.edw.com.cn(电子产品世界论坛).
【作者介绍】吴斌(1974-),广西桂林人,桂林激光研究所工程师,研究方向:实时嵌入式系统。
【关键词】VxWorks;MUX;自有协议
【中图分类号】TP393【文献标识】A
【文章编号】1671-5969(2007)06-0178-02
一、概述
VxWorks嵌入式操作系统是美国WINDRIVER(风河公司)公司于1983年开发的一种嵌入式实时操作系统,它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航天等高精尖技术及实时性要求极高地领域。经过数十年的发展完善,VxWorks嵌入式操作系统已经成为实时嵌入式系统的事实上的工业标准和军用标准。
自有协议的开发一直是嵌入式系统开发的难点。在传统的嵌入式系统中底层网络驱动和协议是紧密相关的。当协议改变时,网络驱动也要进行修改。这给系统的开发和维护增加了很多的难度。在VxWorks中,WINDRIVER提供了一个MUX层。MUX层的特点是:它可以完全屏蔽嵌入式系统的底层网络驱动和上层协议的关联,使网络驱动程序和协议之间没有内部交换数据,它们只能通过MUX间接相互作用。图1展示了协议、MUX、网络驱动之间的关系。由此可以看出MUX的目的是分解协议和网络驱动,从而使它们几乎独立彼此。这种使增加新的网络驱动和协议变得简单。如想添加一个新的END(网络驱动),所以现有基于MUX的协议可使用新的网络驱动。相同的,如想增加一个新的基于MUX的协议,任何现有的END均可通过MUX来访问新的协议。
二、MUX的分析
下面我们对VxWorks的MUX进行简要的分析。图2所示为VxWorks系统中MUX、协议和网络驱动各标准API之间的关系。
从图2我们可以看到MUX层的所以标准API及各标准API和协议、网络驱动API的调用关系。箭头表示每个调用程序的入口点。例如muxSend()调用endSend()。注意到,协议通过调用muxSend()开始传送,但图2中并没有指出它的协议程序名。此程序为非标准API。
三、协议的实现
任何要接收数据包的协议首先要将其比绑定到MUX上,通過MUX和设备连接起来。协议通过调用muxBind()来完成这个工作。下面为muxBind()的原型:
Void * muxBind
(
char * pName,/*设备名*/
int unit,/*设备单元号*/
BOOL (*stackRcvRtn) /*接收函数*/
(
void * pEnd, long type, M_BLK_ID pNetBuff,LL_HDR_INFO
* pLinkHdr,
void * pCallbackId
),
STATUS stackShutdownRtn( void * pCookie, void * pSpare),/*关闭函数*/
STATUS stackRestartRtn( void *pEND, void *Pspare),/*复位函数*/
Void stackErrorRtn(void * pEnd, END_ERR pError, void * pSpare), /*错误处理函数*/
long type, /*从RFC1700或SAP中获得的协议类型*/
char *pProtoName, /*协议名*/
void *pSpare /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/
)
这里我们要特别注意的是muxBind()中的long type(协议类型)。MUX使用此协议类型来区分协议的优先权。这个优先权决定哪个协议先获得接收数据包的处理权利。当驱动程序传送给MUX一个数据包时,驱动程序包含一个指向END_OBJ结构的指针(END_OBJ结构如图3)。此结构还包含一个protocols成员、关注设备的协议清单(NET_PROTOCL结构清单)首部。此清单中的协议顺序决定拉哪个协议优先处理数据包。MUX负责保存此清单。
协议类型VxWorks中有三个典型值,分别时MUX_PROTO_
SNARF、MUX_PROTO_PROMISC、MUX_PROTO_OUTPUT。
MUX_PROTO_SNARF:协议获得完整的接收数据包。
MUX_PROTO_PROMISC:协议优先处理接收数据包,被协议处理部分将被屏蔽。
MUX_PROTO_OUTPUT:协议获得输出数据包。
当协议在它的muxBind()中规定一种MUX_PROTO_SNARF类型,则MUX在END_OBJ.protocols清单首部添加一协议。注意VxWorks在任何时候只允许MUX下有一MUX_PROTO_SNARF类型协议激活。当协议在它的muxBind()中规定一种MUX_PROTO_PROMISC类型,则MUX在END_OBJ.protocols清单的尾部添加一协议。若协议在muxBind()中还规定了其他类型,则MUX在清单中MUX_PROTO_SNARF协议后添加这些类型的协议(若无MUX_PROTO_SNARF协议则在清单首部添加)。这种协议添加方式保证了在接收数据包之前,低优先级的协议无法盗用或破坏高优先级的协议的数据包。
协议的标准API函数我们由图2可以看到有四个:stackShutdownRtn( )、stackRcvRtn( )、stackError()、stackTxRestartRtn()。它们的功能如下表2:
StackRcvRtn()是协议里最重要的API,MUX通过它来传递数据包给协议。协议对数据包的处理也是由其完成的。它的原型如下:
BOOL stackRcvRtn
( void * pCookie, /* 调用muxBind()后的返回指针,用来识别MUX将协议绑定到那个设备上* /
long type, /* 协议类型*/
M_BLK_ID pNetBuff,/*一个指向包含数据包和连接级信息的mBlk结构指针*/
LL_HDR_INFO *pLinkHdr,/* 返回包含首部信息的一个LL_HDR_INFO结构,首部信息取决于END执行的特定数据连接层 */
void * pCallbackId /*一个指向传递给MUX的多余信息的指针,这个信息的使用是可选的*/
)
在VxWorks中在一个设备上加入一个自有协议,当底层网络驱动完备时,我们只要将协议层的四个API函数写好并通过muxBind()绑定于设备上,协议即可生效。为了加深理解,下面以一个截获IP接收数据包的程序代码为例。
LOCAL BOOL monitorRecvProcess /*接收数据监测*/
(
void * pCookie,
longtype,
M_BLK_ID pMblk,
LL_HDR_INFO *pLinkHdrInfo,
void *pSpare
)
{
int i;
printf("DataMonitorByMux>Received data(len=%d):\n",pMblk->
mBlkHdr.mLen);
for(i=0;i
printf("%3x", *((unsigned char *)pMblk->mBlkHdr.mData+i));
printf("\n");
return FALSE;
}
STATUS muxMonitorStart(char *ifname,int unit) /*程序启动*/
{
monitorRecvBindCookie = muxBind (ifname, unit, (FUNCPTR)
monitorRecvProcess,NULL, NULL, NULL,MUX_PROTO_SNARF, NULL, NULL);
if(monitorRecvBindCookie==NULL)
{
logMsg("monitorRecvBindCookie:Can't bind to %s%d!\n",ifname,unit);
return(ERROR);
}
logMsg("DataMonitorByMux:%s%d Bind OK!!\n",ifname,unit);
return (OK);
}
STATUS muxMonitorStop(char *ifname,int unit) /*停止監测*/
{
if(muxUnbind(monitorRecvBindCookie,MUX_PROTO_SNARF,(FUNCPTR)monitorRecvProcess)!=OK)
{
logMsg("monitorRecvProcess unBind err!\n");
return ERROR;
}
return OK;
}
代码中monitorRecvProcess()即为协议中的StackRcvRtn(),它通过muxBind绑定于网络设备上,通过muxUnbind()从设备上卸载。monitorRecvProcess()可以截获网络设备上的所以IP接收数据包。
四、结语
通过上面的分析可以得到结论:由于Vxworks嵌入式系统为我们提供了一个MUX层,屏蔽协议和网络驱动之间的联系,让协议和网络驱动各自独立,使得用户实现自有协议变得简单、高效。
【参考文献】
[1] VxWorks Network Programmer's Guide.
[2] VxWorks BSP Developer’s Guide.
[3] Bbs.edw.com.cn(电子产品世界论坛).
【作者介绍】吴斌(1974-),广西桂林人,桂林激光研究所工程师,研究方向:实时嵌入式系统。