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...