UIP 0.9 移 植 心 得

自從網上發帖慶賀成功移植以來,隔三差五的就有人來問我,關於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,其他的協議都有範例,大家研習代碼便可。

 

急急忙忙趕出來的移植心得,很粗糙。但希望對大家有用。如果有什麼錯誤,望大家批評指正.

發佈了4 篇原創文章 · 獲贊 5 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章