uIP協議棧分析

2021-06-20 18:45:31 字數 4005 閱讀 3090

uip特性

由於uip協議棧專門為嵌進式系統而設計,因此還具有如下優越功能:

(1)    **非常少,其協議棧**不到6k,很方便閱讀和移植。

(2)    占用的記憶體數非常少,ram占用僅幾百位元組。

(3)    其硬體處理層、協議棧層和應用層共用乙個全域性快取區,不存在資料的拷貝,且傳送和接收都是依靠這個快取區,極大的節省空間和時間。

(4)    支援多個主動連線和被動連線併發。

(5)    其源**中提供一套例項程式:web伺服器,web客戶端,電子郵件傳送程式(smtp客戶端),telnet伺服器, dns主機名解析程式等。通用性強,移植起來基本不用修改就可以通過。

(6)    對資料的處理採用輪循機制,不需要操縱系統的支援。

由於uip對資源的需求少和移植輕易,大部分的8位微控制器都使用過uip協議棧, 而且很多的著名的嵌進式產品和專案(如衛星,cisco路由器,無線感測器網路)中都在使用uip協議棧。

uip架構

uip相當於乙個**庫,通過一系列的函式實現與底層硬體和高層應用程式的通訊,對於整個系統來說它內部的協議組是透明的,從而增加了協議的通用性。uip協議棧與系統底層和高層應用之間的關係如圖2-1所示。

uip_init()是系統初始化時呼叫的,主要初始化協議棧的偵聽埠和預設所有連線是封閉的。

當網絡卡驅動收到乙個輸進包時,將放進全域性緩衝區uip_buf中,包的大小由全域性變數uip_len約束。同時將呼叫uip_input()函式,這個函式將會根據包首部的協議處理這個包和需要時呼叫應用程式。當uip_input()返回時,乙個輸出包同樣放在全域性緩衝區uip_buf裡,大小賦給uip_len。假如uip_len是0,則說明沒有包要傳送。否則呼叫底層系統的發包函式將包傳送到網路上。

uip週期計時是用於驅動所有的uip內部時鐘事件。當週期計時激發,每乙個tcp連線都會呼叫uip函式uip_periodic()。類似於uip_input()函式。uip_periodic()函式返回時,輸出的ip包要放到uip_buf中,供底層系統查詢uip_len的大小傳送。

uip在mcs-51微控制器上的移植

1.為此專案建立乙個keil c工程,建立src目錄存放原始檔。

2.通過閱讀uip-1.0\unix\main.c,了解uip的的主迴圈**架構,並將main.c放到src目錄下。

3.仿照uip-1.0\unix\tapdev.c寫網絡卡驅動程式,與具體硬體相關。這一步比較費點時間,不過好在大部分網絡卡晶元的驅動程式都有**鑑戒或移植。驅動需要提供三個函式,以rtl9019as驅動為例。

etherdev_init():網絡卡初始化函式,初始化網絡卡的工作模式。

u16_t etherdev_read(void):讀包函式。將網絡卡收到的資料放進全域性快取區uip_buf中,返回包的長度,賦給uip_len。

void etherdev_send(void):發包函式。將全域性快取區uip_buf裡的資料(長度放在uip_len中)傳送出往。

所以,收包和發包主要是操縱uip_buf和uip_len。具體驅動分析可參考《第三章  網路晶元的驅動》。

4.由於uip協議棧需要使用時鐘,為tcp和arp的定時器服務。因此使用微控制器的定時器0用作時鐘,每20ms讓計數tick_cnt加1,這樣,25次計數(0.5s)滿了後可以呼叫tcp的定時處理程式。10s後可以呼叫arp老化程式。對uip1.0版本,增加了timer.c/timer.h,專門用來治理時鐘,都放到src下。

5.uip協議棧的主要內容在uip-1.0\uip\下的uip.c/uip.h中,放到src下。假如需要arp協議,需要將uip_arp.c和uip_arp.h也放到src下。

6.uipopt.h/uip-conf.h是配置檔案,用來設定本地的ip位址、閘道器位址、mac位址、全域性緩衝區的大小、支援的最大連線數、偵聽數、arp表大小等。需要放在src下,並且根據需要配置。在v1.00版本中對配置做了如下修改:

(1)配置ip位址,預設先關ip,在初始化中再設定。

#define uip_fixedaddr   0

#define uip_ipaddr0     192

#define uip_ipaddr1     168

#define uip_ipaddr2     1 

#define uip_ipaddr3     9

#define uip_netmask0    255

#define uip_netmask1    255

#define uip_netmask2    255

#define uip_netmask3    0  

#define uip_dripaddr0   192

#define uip_dripaddr1   168

#define uip_dripaddr2   1 

#define uip_dripaddr3   1  

(2)使能mac位址

#define uip_fixedethaddr 1  

#define uip_ethaddr0    0x00 

#define uip_ethaddr1    0x4f

#define uip_ethaddr2    0x49

#define uip_ethaddr3    0x12

#define uip_ethaddr4    0x12 

#define uip_ethaddr5    0x13

(3)使能ping功能

#define uip_pingaddrconf  1

(4)封閉主動請求連線的功能

#define uip_active_open 0

(6)由於微控制器是大端結構,因此巨集定義需要修改

#define uip_conf_byte_order      uip_big_endian

(7)暫時不移植列印資訊,先封閉

#define uip_conf_logging     0

(8)定義資料結構型別

typedef unsigned char u8_t;

typedef unsigned int u16_t;

typedef unsigned long u32_t;

7. 假如使用keil c的小模式編譯,需要在大部分的ram的變數前增加xdata。

9.解決編譯過程中的錯誤。uip協議棧為c語言編寫,編譯過程中的題目比較少,並且輕易解決。

uip的主控制迴圈

通過實際的**說明uip協議棧的主控制迴圈。 

void main(void)

} /*收到的是arp資料,呼叫uip_arp_arpin()處理*/

else if(buf->type == htons(uip_ethtype_arp)) }

}/*檢視0.5s是否到了,到了則呼叫uip_periodic處理tcp超時程式*/

else if(timer_expired(&periodic_timer))

}         

/*檢視10s是否到了,到了則呼叫arp處理程式*/

if(timer_expired(&arp_timer))

} }

return; }

uip協議棧提供的主要介面

提供的介面在uip.h中,為了減少函式呼叫造成的額外支出,大部分介面函式以巨集命令實現的。

1.初始化uip協議棧:uip_init()

2.處理輸進包:uip_input()

3.處理週期計時勢件:uip_periodic()

4.開始監聽埠:uip_listen()

5.連線到遠端主機:uip_connect()

6.接收到連線請求:uip_connected()

7.主動封閉連線:uip_close()

8.連線被封閉:uip_closed()

9.發出往的資料被應答:uip_acked()

10.在當前連線傳送資料:uip_send()

11.在當前連線上收到新的資料:uip_newdata()

12.告訴對方要停止連線:uip_stop()

13.連線被意外終止:uip_aborted()

uip協議棧分析(2)

uip的記憶體管理方法 記憶體管理的實現在memb.c memb.h裡。這兩個檔案負責uip的記憶體塊的管理,記憶體塊是由memb 巨集宣告。記憶體從宣告的記憶體塊裡用memb alloc 分配,用memb free 釋放。因為命名空間的衝突,每個c模組只能有乙個memb 巨集宣告。先看memb.h...

uip協議棧分析(1)

uip的原始碼目錄結構 研究unix下的 可以知道uip是如何使用的,關鍵是理解uip協議棧的主控制迴圈。int main void int i uip ipaddr t ipaddr struct timer periodic timer,arp timer 設定tcp超時處理時間和arp老化時間...

uip協議棧分析(2)

uip的記憶體管理方法 記憶體管理的實現在memb.c memb.h裡。這兩個檔案負責uip的記憶體塊的管理,記憶體塊是由memb 巨集宣告。記憶體從宣告的記憶體塊裡用memb alloc 分配,用memb free 釋放。因為命名空間的衝突,每個c模組只能有乙個memb 巨集宣告。先看memb.h...