自从网上发帖庆贺成功移植以来,隔三差五的就有人来问我,关于UIP0.9移植的问题。其实很早就写了这篇文章,只是一直没有贴出来。这段时间老是有人问,我才想起来,把它翻出来贴上。希望对路过的各位有所帮助。另外,想说一点,我这里没有去讲底层的函数到底是什么样的,因为每个phy都不一样,得根据实际情况编写相应的代码。也不是说全部都自己写,在网上找找相应的phy的驱动,根据自己的硬件改改就OK了。
我移植的uip目前没有加操作系统,等有时间了把LWIP加到操作系统(uC/OS-II)中去。目前,已经把uC/OS-II调通了。准备马上开始移植LWIP。
本来很想写一份移植心得,可是一直没有时间。今天有个朋友问我,决定写一个说明。我当时也是多方寻求资料,可是很多资料都没有讲的很清楚(也许是我比较笨^_^)。
相信你手上已经有了uip的源代码,以下说明已uip0.9为准。
1,uip和LWIP的区别
uip主要是针对没有操作系统的8、16位的CPU,当然在32位上也可以运行。它也可以运行在有操作系统的CPU上。只是效率可能底一些。因为它没有使用信号量或消息等等,而是采用轮询的方式,来处理数据的发送和接受。
LWIP和uip出自同一个地方,只是LWIP主要针对有操作系统的应用。(没有研究过源代码,不敢过多发表言论)。
2,文件关系
弄清楚源代码之间的联系和各个主要函数的功能,移植就不困难了。
Apps à 这是作者写的一些应用代码。包括Http、Smtp、Telnet和Webclient等等。
Uip à 这是uip的核心代码。
Unix à 这是作者在unix系统下的一个工程。
Doc à 这是说明文档。
重点说说Uip和Unix这两个文件夹中比较重要的函数。
Uip:
Uip.c :
uip_process( ) 完成对ip,udp,tcp的数据的解析。
uip_udp_new() 建立一个udp。
uip_listen() 监听一个端口。
uip_connect() 准备建立一个tcp连接,发送同步信号。
Uip_arp.c
uip_arp_update()更新arp列表。
uip_arp_init() 初始化arp缓冲块
uip_arp_out() 发送一个arp请求
uip_arp_arpin() 处理收到一个arp包
uip_arp_ipin() 处理收到是arp包的ip包。
Slipdev.c 是关于SLIP 协议的文件
Unix:
Main.c uip服务的主循环。
Tapdev.c 和 tapdev.h 是低层数据的接收与发送。
Uip_arch.c 一些计算校验和的函数。
Uipopt.h 这是一个uip的配置文件。你可以修改IP,NETMASK,GATEWAY,MAC等等以便符合你的网络。
3,移植细节
在你的工程中,你需要包含如下文件:
Uip.c
Uip_arch.c
Uip_arp.c
Tapdev.c
Main.c
A, 网卡驱动移植
Tapdev.c 包含3个函数:
a> tapdev_init(void) 网卡初始化.
b> unsigned int tapdev_read(void) 接收网卡数据
c> void tapdev_send(void) 发送网卡数据
这3个函数与低层硬件有关.大家只需按照上述函数的接口,完成低层数据的收发便可.
B, UDP的移植
a> uipopt.h 中修改
#define UIP_UDP 1
#define UIP_UDP_CONNS 10(同时可建立udp的连接数)
#define UIP_UDP_APPCALL udp_appcall (UDP的用户接口函数)
添加 #include <udp.h>
b> 新建udp.c 和udp.h 两个文件
udp.c中定义两个函数
udpinit(void)
{
uip_ipaddr(ipaddr, RIPADDR0, RIPADDR1, RIPADDR2, RIPADDR3);
uip_udp_new(ipaddr, UDP_LPORT, UDP_RPORT); //建立一个udp,指定udp端口。
//注意:我对uip_udp_new()函数做了修改,原来本地端口是随机的,我改为了可以配置的。
}
//当UDP数据被tapdev_read ()收到,uip_process()函数对UDP进行解析,如果正确,则调用udp_appcall()来交给用户处理。此时,用户可以用uip_newdata()检测是否有新数据,新数据放在uip_appdata指针中,长度为uip_len。
//当定时轮询到达,后也会调用udp_appcall(),可以用uip_poll()检查。此时,用户可以主动发送数据。只须将数据放入指针uip_appdata后的空间中,并将数据长度传给uip_slen便可。
下面给出了函数的模型(仅供参考):
void udp_appcall(void)
{
if(uip_udp_conn->rport == HTONS(UDP_RPORT))
{
if(uip_poll())
{
/*
for(u16_t i=0; i<1000; i++)
{
*(uip_appdata++) = (u8_t)i;
}
*uip_appdata = '\0';
uip_slen = 1000; //strlen((char*)uip_appdata);*/
}
if(uip_newdata())
{
uip_appdata[uip_len]='\0';
uip_slen = uip_len;
}
}
}
赶紧试试吧!体验一把移植成功的快乐!
C,TCP的移植
如果你已经弄清楚了UDP的移植,TCP的移植则易如反掌了。
你可以参看一下Doc文件夹下的uip-refman.pdf中的1.7 example 这一小节(第13页)。上面已经说的很清楚,我不想在这里多说。虽然是英文的,但是比较浅显。另外,你也可以找到 张伟林 翻译的中文版本,我这里也有.
另外,http://network.51cto.com/art/201111/301161.htm 的这篇文章大家也可以看看。
D,其他的协议都有范例,大家研习代码便可。
急急忙忙赶出来的移植心得,很粗糙。但希望对大家有用。如果有什么错误,望大家批评指正.