引言
随着嵌入式系统技术的不断发展,越来越多的应用需要嵌入式系统连接成网络使用,这就需要一个可应用于嵌入式系统的TCP/IP协议。由32位处理器搭建的嵌入式系统在使用网络的时候,通常都会运行一个集成有TCP/IP协议栈的操作系统。这样的TCP/IP协议栈是庞大的,不适用于处理能力和资源都十分有限的8位或16位的处理器搭建的嵌入式平台,而且由于处理能力和资源有限,8位或16位的处理器搭建的嵌入式系统一般都不运行操作系统。TCP/IP协议栈的透明性掩盖了其实现的复杂性,系统开发者从无到有搭建一个适用于自己平台的TCP/IP协议栈是一件艰巨的任务,很多时候从一个项目开发周期来说是不可能实现的。ZLIP TCP/IP协议栈是一种可实现的极小的TCP/IP协议栈,适用于8位或16位的处理器构建的嵌入式平台。ZLIP协议栈是针对51单片机和Keil C51编译器其自身的特点(存储类型、函数指针、重入函数等)设计的,而且ZLIP协议栈是用C语言实现的,方便协议栈的移植。ZLIP协议栈代码量适中,而且对处理器和RAM等资源要求都较小,这使得ZLIP协议栈可以很好地用于低端处理器搭建的系统上。本文将简单描述ZLIP协议栈的特点,分析ZLIP的应用接口,并讨论嵌入式平台结合ZLIP作为客户端系统的应用。
1 ZLIP协议栈特点
目前常用的TCP/IP协议有lwIP、uIP、tinyTCP、ZLIP等几种,其中lwIP、uIP、ZLIP已经成功在单片机上得到了应用。应用在微处理器上的TCP/IP协议栈中,lwIP算是功能较全面的,但是它的代码量相对来说比较大,对资源的要求也较高;uIP采用了不保存需要应答的数据包的RAM使用方案,uIP的设计侧重于减少代码量和减少RAM的使用量,相对lwIP来说对系统的资源要求较低,但其没有和BSD的套接字接口兼容应用层接口较复杂;ZLIP协议栈是以李章林博士为主的开发团队在南开大学电子应用实验室开发完成,专门为51单片机设计的,针对Keil C51编译器设计,它的代码量和RAM使用量都比较适中,所有的外部变量都使用了xdata类型,全部指针都为明确存储类型的指针,需要重入的函数已经声明为reentant,使用KeilC的小模式下编译,使用类似MFC的CScoket的套接字应用层接口,使用方便。ZLIP支持多TCP连接、多网络设备。ZLIP是用C语言实现的源码开放的协议栈,能方便地移植到多任务操作系统和其他CPU下,能方便地替换网络接口协议和网卡驱动设备,具有很好的通用性。
2 ZLIP协议栈分析
ZLIP协议通过提供一系列的接口函数,实现其与底层网卡驱动的连接以及与上层应用程序的通信。它内部的协议集合对用户都是可见的,增强了该协议栈的通用性和灵活性,用户可以根据自己的需要将此协议栈移植到不同的平台。ZLIP协议栈与系统底层驱动和应用程序之间的接口关系如图1所示。
图1
2.1 ZLIP协议栈与系统底层的接口
ZLIP与系统底层的接口包括与设备驱动的接口和与系统定时器的接口两类。ZLIP与设备驱动的接口是通过函数EtherDevInit(),将网络设备的MAC地址和接收、发送函数通过“注册”的形式“注册”进ZLIP协议栈,从而初始化一个以太网接口设备,并设置这个设备的发送和接收驱动函数。为了与ZLIP协议栈结合,其中网络设备的发送函数为unsigned char型的可重入函数,形参为一个指向待发送数据的指针和一个记录待发送数据长度的变量,例如unsigned char cp2200_Send(unsigned char xdata * outbuf, unsigned short len) reentrant。网络设备的接收函数为struct SMemHead xdata *型的可重入函数,例如struct SMemHead xdata * cp2200_rcve( ) reentrant,其中SMemHead结构体为:
struct SMemHead{
struct SMemHead xdata *pNext;
struct SMemHead xdata *pPre;
unsigned char used;
unsigned char xdata *pStart;
unsigned char xdata *pEnd;
}
在接收函数中,只要用到pStart成员,将接收到的数据存入pStart指向的存储区。
2.2 ZLIP协议栈与系统计时接口
TCP/IP协议要处理许多定时事件,例如包重发、ARP表项更新等。系统计时用于为所有ZLIP内部时钟事件计时。ZLIP与系统定时器的接口是通过NetIfTimer( )、ARPTimer( )、TCPTimer( )三个函数实现的,NetIfTimer( )函数调用“注册”了的每一个接口的接收函数,接收到达的数据包;ARPTimer( )函数处理ARP表项更新;TCPTimer( )函数处理TCP/IP包的重发等功能。这三个函数必须在短时间(一般不大于25 ms)内被调用一次,否则接收数据包等功能将停止。
3 ZLIP协议栈应用接口
ZLIP协议栈提供一系列接口函数供用户程序调用,应用程序作为单独的模块由用户实现。在应用程序中每个连接都需要定义一个套接字,ZLIP提供了TCPSocket( )函数可给每个连接申请一个套接字。当系统作为客户端使用时,ZLIP提供了TCPConnect( )函数向IP地址为DestIP的服务器的DestPort端口发起连接,通过TCPConnect( )函数还可以设置当接收到数据包和对方要求关闭TCP连接时应该调用的回调函数。
接收数据包的回调函数原型可定义为类似void OnReceive(void xdata * buf,unsigned short size) reentrant的形式,其中buf指向接收的数据,size是接收的数据量的大小。可以在OnReceive中处理接收的数据。
当程序中有多个TCP连接同时存在时,需要给每个连接准备一个接收回调函数。对方要求关闭TCP连接时应该调用的回调函数原型可定义为类似void OnClose(socket xdata* pSocket) reentrant的形式,pSocket指向将要关闭的socket,在OnClose中可调用ZLIP提供的TCPClose( )函数,它将要求关闭套接字pSocket对应的连接。当程序中有多个TCP连接同时存在时,需要给每个连接准备一个OnClose函数。回调函数的函数名在不重复的情况下可以任意命名。
当系统作为服务器使用时,可使用ZLIP提供的TCPListen( )函数对目标端口进行监听,通过TCPListen( )函数还可以设置当有客户端向这个监听端口连接成功时调用的回调函数,当程序中有多个处于监听状态的socket时,需要给每个socket准备一个这样的回调函数。
不论系统出于客户端状态还是服务器状态,只要系统被连接进网络后都可以调用ZLIP提供的TCPSend( )函数来发送数据,当使用完这个套接字以后,调用ZLIP提供的TCPAbort()函数,将这个套接字释放还给系统。
4 ZLIP的配置
用户根据具体的实际条件可对ZLIP进行设置。修改TCPIPmem.h中的宏定义TCPIP_BUF_SIZE可以设置TCP缓冲区大小,默认为8KB,建议大于4KB。缓冲区过小,将会影响发送和接收速度。如果系统中有多个网络设备,可以修改NetIf.h中的宏定义NET_IF_MAX_NUM设置系统中允许的网络设备数,在主程序中使用NetIfAdd( )函数可添加网络设备。修改TCP.h中的宏定义TCP_CONNECTION_MAX_NUM可以设置TCP的连接上限。当程序使用以太网以外的网络接口协议时,修改NetIf.h中的宏定义NETIF_HEAD_MAX_LEN可以设置网络接口层协议的最大帧头长度。修改ARP.h中的宏定义ARP_ENTRY_MAX_NUM可以设置ARP表的大小。如果不希望系统能够响应ping命令,则修改icmp.h中的宏定义ICMP_EN为0即可,响应ping命令就设置为1。
5 ZLIP协议栈应用
下面讨论将ZLIP结合CP2200以太网芯片,在C8051F120增强型单片机组成的嵌入式平台上作为客户端系统使用。该系统的实现可分为4部分:C8051F120的初始化、CP2200网卡芯片的驱动、系统定时器、应用程序。
C8051F120的初始化主要就是根据需求对系统时钟、端口设置等初始化。
CP2200网卡芯片的驱动主要包括三个部分:PHY_Init( )和MAC_Init( )函数实现网卡芯片的上电初始化,主要包括物理层的初始化和MAC初始化;cp2200_Send( )函数实现数据的发送;cp2200_rcve( )函数实现以太网数据的接收。
C8051F120上有5个可用于定时计数的定时器,可选择其中任意一个来为TCP/IP协议中与时间有关的事件定时。在定时时间到达时,需要处理的函数包括NetIfTimer( )、ARPTimer( )、TCPTimer( ),为了保证对这三个函数能被及时执行,可以将定时器的定时周期设置为20 ms。
在应用程序中可以通过调用TCPSend( )函数来发送数据。为了简单测试该客户端系统和服务器连通是否能正确通信,可以在数据包接收回调函数中将接收到的数据返发给服务器,这样可通过在PC上的网络调试助手软件查看数据的回显正确与否,从而判断客户端和服务器的通信正常与否。软件的实现框图如图2所示。
图2
将服务器IP设为192.168.1.149,端口号设为2016。当客户端和模拟服务器的网络调试助手连通后,可通过调试助手向客户端系统发送数据,然后客户端将数据返发回去。此时数据会在调试助手的网络数据接收区显示出来,实验结果如图3所示。
图3
结语
本文对ZLIP的特点、接口等进行了分析,讨论了将ZLIP结合CP2200以太网芯片在C8051F120单片机上实现客户端系统,并实验成功。采用ZLIP实现8/16位嵌入式处理器搭建的系统进行以太网通信有着良好的前景,可用于实现远程信息采集、智能仪表等嵌入式系统应用。