admin 管理员组文章数量: 1086019
2024年3月13日发(作者:表单大师如何导出excel)
TCP/IP在51单片机上的实现特点和方法
李章林
1
,张立民
1
( 1 南开大学信息技术科学学院, 天津 300071 )
摘要:为了实现51单片机接入internet,开发基于51单片机的TCP/IP具有重要意义。为此开发了zlIP,它是针对51单片机的特点使用
KeilC51编程语言编写的TCP/IP,具有代码量小和兼容BSD套接字(socket)用户接口等特点。zlIP1.0版注重于运行速度,zlIP2.0版注重
于用户接口的易用性,以从不同的角度试验在51单片机上实现TCP/IP的特点。通过比较两个版本的优缺点和吸收国内外其它TCP/IP的优
点,分析了在单片机上实现TCP/IP的速度、程序大小、内存大小、编译器等特点,并针对这些特点总结和提出多种技巧和方法,并对这些
技巧、方法的优缺点进行了分析。最后讲述了几点关键技术:设计清晰的TCP/IP和应用层的接口、采用前后台和多线程程序结构的比较,
内存管理方法和防止多余的内存拷贝,实现数据包整序重发和窗口控制等。
关键词:TCP/IP;单片机;zlIP
中文分类号: 文献标识码:A 文章编号:1006-8740(2003)-00-0000-00
1 引言
随着网络应用的不断扩大,将各类电子设备接入Internet的需求越来越大。电子设备入网有多
种解决方案:例如使用嵌入式系统,如使用ARM+Linux;一些实现TCP/IP的芯片也已经可以获得,
(1)
例如Analog Devices推出的Internet Modem;在51系列单片机运行TCP/IP协议栈等。前两种
方案具有良好的性能,而在单片机上实现TCP/IP的方案具有很低的价格,在某些对网络速度要求不
高的领域,有广阔的应用前景。
2 TCP/IP在单片机上实现的特点
2.1 速度慢
我们先来了解51单片机网络传输的极限速率。TCP/IP发送过程中主要的运算量集中在三个部
分:应用程序将数据拷贝到RAM、计算TCP校验和、将RAM中的数据包拷贝到网络设备的发送缓冲
区。对每一个字节数据,两次拷贝大致共使用12×2=24个指令周期;计算TCP校验和使用16个指
令周期。采用12M的晶振,最高网络传输速度为25K字节/秒。实际上要比这个速度慢,zlIP第一
版速度只有11.752K字节/秒。
为了提高速度可以采用快速的单片机比如Winbond公司的77E58或者AVR单片机,当然还可以
提高晶振频率。除此之外还有:使用KeilC时,尽量避免使用Reentrant函数,Reentrant类型的
函数比一般函数速度要慢很多,但是某些时候为了程序结构的需要必须使用Reentrant,这就需要
(2)
在速度和结构之间作一个选择;指针使用“指定存储类型”的指针(memory-specific pointer)
;
精简协议栈去除运算量大但是用处不大的功能,目前zlIP中TCP定时重发时间是固定的,也没有拥
塞窗口控制,也没有IP层路由算法;防止数据包的不必要的拷贝;优化计算校验和和内存拷贝函数。
2.2 程序存储空间和外部RAM空间不大
通常TCP/IP协议栈需要大量的RAM来存储需要被应答的TCP包,如果规定时间内没有被应答则
重发这个TCP包,被应答以后释放这个TCP包。
(3)
为了减小RAM使用量,能否不存储需要被应答的TCP包?
。当数据包需要重新发送时,如果
能够重新产生数据包所需的数据,那时就可以不存储。例如存在于EEPROM中的html网页。但是这
种方法存在以下两个缺点:一,TCPIP和应用层接口变得复杂。当需要重发时,必须需要应用层重
新产生数据,实际上将TCP负责的重发机制转移到了应用层。应用层程序编写变得复杂。二,对数
据无法重新产生的应用不适用。例如语音采集。
2.3编译器
TCP/IP一般采用C语言或者混合汇编来写。以KeilC516.0编译器为例。与X8086编辑的代码
不同,使用KeilC要注意函数重入、指针、函数指针这三个问题。使用可重入函数和一般指针(generic
pointer)使得程序代码增大,运行速度变慢。使用函数指针时,要么需要手动重建调用树(Call
tree),要么将通过函数指针调用的函数都设置为可重入函数。所以尽量少用重入函数、函数指针和
1
一般指针。
3 zlIP的特点和实现技巧
3.1 特点
其它的TCP/IP有lwIP、uIP、ucIP、tinyTCP等。其中lwIP、uIP、tinyTCP已经成功地移植到
了单片机。lwIP是专门为微处理器设计的TCP/IP协议栈,lwIP的功能很全面,但是相对来说代码
(4)
较大,有人做过移植lwip+ucOSII代码量为60K。uIP侧重于减小代码量(选择AVR为目标器件时,
代码为5K左右)和减小RAM使用量(100字节左右)。uIP采用了不保存需要应答的数据包的RAM使
用方案,没有和BSD的套接字接口兼容,应用层接口较复杂。zlIP介于uIP和lwIP之间,它针对
单片机设计,有中等代码量和RAM使用量,使用套接字的应用层接口,所有的外部变量都使用了xdata
类型,全部指针都为明确存储类型的指针,需要重入的函数已经声明为reentant,使用KeilC的小
模式下编译。使用12M晶振、KeilC编译器、89C52单片下测试的技术参数如下:
表1:zlIP技术参数(Technical parameter of zlIP)
zlIP的版本
1.0
2.0
代码量(字节)
6791
14464
外部RAM使用量(字节)发送速度(字节/秒)
20K
4K
11.752K
5.892K
2.0版主要功能有:支持套接字形式的多个TCP连接。支持多个网络设备。支持通过网关发送数据
包和数据包转发功能。响应ping命令。支持TCP包的整序、重发和窗口控制流量控制。
3.2 zlIP实现TCP/IP的技巧和方法
3.2.1设计套接字接口
zlIP接口函数基本和BSD的套接字接口相同。提供的用户接口函数有:
z TCPSocket()。函数原型:socket * TCPSocket(IP_ADDR ScrIP)。功能:申请一个套接字。ScrIP
是这个套接字的本地IP地址。返回socket类型指针,如果申请失败返回NULL。
z TCPConnect()。函数原型:BOOL TCPConnect(socket * pTCB, IP_ADDR DestIP, WORD
DestPort,void (* recv)(void * buf,WORD size),void (* close)(socket * pSocket))。功
能:向IP地址为DestIP的服务器的DestPort端口发起连接。参数recv和close用于设置当
接收到数据包和对方要求关闭TCP连接时应该调用的回调函数指针。连接成功返回TRUE,否则
返回FALSE。
z TCPSend()。函数原型:BOOL TCPSend(socket * pTCB,void *buf,WORD DataSize)。功能:发
送数据。发送数据的TCP连接是套接字指针pTCB对应的连接,发送的数据的起始地址为buf,
大小为DataSize。发送成功返回TRUE,否则返回FALSE。
z TCPListen()。函数原型:BOOL TCPListen(socket *pTCB,WORD ScrPort,void (* accept)(socket
*pNewTCB)) 。功能:使用套接字pTCB在ScrPort端口监听。参数accept是当有客户端向这个
监听端口连接成功时调用的回调函数指针。
z TCPClose()。函数原型:void TCPClose(socket *pTCB)。功能:我方主动关闭连接时调用TCPClose
函数,它将要求关闭套接字pTCB对应的连接。TCPClose返回以后这个TCP连接可能保持,因
为另一方还没有发起关闭请求。
z TCPAbort()。函数原型:void TCPAbort(socket *pTCB)。功能:当使用完这个套接字以后,调
用TCPAbort,将这个套接字释放,还给系统。
TCP/IP协议运行中,接收数据包到达、另一方发起关闭连接、另一方向我方发起连接这些事件
发生以后如何通知应用层?下面以收到数据包为例提供几种思路:(1)TCP/IP模块设置一个变量
bRecv表征是否有数据包到达,应用层必须反复的查询这个变量,如果为TRUE,则调用一个接收函
数接收这个数据包。但是这种方法增加了应用层程序的复杂性。(2)固定的回调函数。当TCP层接收
到一个数据包后调用OnReceive(pTCB,buf,size)函数。用户必须在应用层定义一个函数名为
OnReceive的函数。然后在OnReceive函数中处理接收的数据。(3)回调函数指针。每个套接字保存
2
版权声明:本文标题:51单片机TCP_IP 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/b/1710277265a565740.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论