自從網上發帖慶賀成功移植以來,隔三差五的就有人來問我,關於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,其他的協議都有範例,大家研習代碼便可。
急急忙忙趕出來的移植心得,很粗糙。但希望對大家有用。如果有什麼錯誤,望大家批評指正.