以前自己写了一个TCP/IP的协议栈,但是需要的48K的RAM。后来随着产品功能的增加,RAM资源就越来越不够用了。在一个偶然的机会下,发现了一个开源的协议栈--uIP。于是在网上找了一些资料。
原来现在比较流行的开源的小型协议栈有两个--lwIP和uIP。
lwIP主页:http://savannah.nongnu.org/projects/lwip/
uIP主页:http://www.sics.se/~adam/old-uip/
uIP文档:http://www.sics.se/~adam/download/?f=uip-1.0-refman.pdf
其中lwIP实现的功能比较多,所以其会较复杂;uIP主要实现了TCP和UDP以及ARP的等简单功能。并且两者都可用于裸机或有操作系统。由于我只需要简单的功能,所以选择了简单的uIP。
下面概述一下uIP及裸机的移植方法,不足之处,请大家多多指正。
uIP概述
uIP的结构不是层次式的,其整个处理过程单独为一个进程,即一个函数,下面就大概分析这个函数。
一、主循环控制
在主循环中,需要处理两个事情。
1. 检测是否有数据到来,当有数据到来时调用uip_input()函数。
2. 检测网络定时器是否超时,如果超时,则调用uip_periodic()函数。
二、体系结构相关功能定义
1. 检验计算,可以手动修改的两个函数是uip_ipchksum()和uip_tcpchksum()。
2. uip不使用32-bit的变量,所以要手动实现uip_add32()这个函数。
(这里移植的时候可以不重写这些函数,按照其默认的算法也可以)
三、内存管理
1. 整个协议栈使用一个全局的buffer(变量uip_buf)装载收到的数据包,所以有数据到来时,必须立刻处理该数据,或者将数据从buffer中考出来;只有buffer中的数据处理了,才会接受下一包数据。
2. 当程序正在处理数据包时,这时如果有数据到来,则需要网卡的驱动程序去把数据按顺序缓存
有一些网卡可以缓存好几包的数据(即网卡或驱动程序把数据包缓存起来),否则丢掉数据或
降低性能。(但这一般只会在多个TCP连接时才会发生)
3. 发送的数据的头部会使用全局buffer,同时uIP没有重传缓冲,即没有把已发送的数据排队,
所以当需要重传数据时,需要应用程序再生成重传数据。
4. 总共需要的内存可以按应用程序的发在来配置。
移植
一、下载源代码。
从http://www.sics.se/~adam/old-uip/download.html下载源代码。解压后,uip的核心代码都在uip文件夹中,所以我们只要把该目录放到自己的工程里面就行了。同时去掉
clock.h timer.c(因为我不使用这种定时方法,我只是在定时器里自加来做超时)
psock.c psock.h(因为我是裸机,所以不需用到这个功能)
uip-split.c uip-split.h(因为我的程序中不需要分包,所以也没有这个功能)
二、配置
配置文件是uipopt.h和uip-conf.h文件,其中uip-conf.h在解压后的unix文件夹下,并且include在uipopt.h文件中,具体配置参考其文档。
我修改了以下地方
//#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN // 注释这行,如果该配置,则默认配置为LITTLE_ENDIAN(小端系统)
#define UIP_CONF_BUFFER_SIZE 1500 //定义了uip_buf的大小
#include "client.h"