網(wǎng)絡(luò)通信之UIP在STM32上的移植
1、什么是UIP協(xié)議棧:
UIP是一種適用于小型嵌入式通信的TCP/IP協(xié)議棧,由瑞典計算機(jī)科學(xué)院的人開發(fā)編寫的,它去掉了完整的TCP/IP中不常用的功能,簡化了通訊過程,但其保留了網(wǎng)絡(luò)通信中必須使用的協(xié)議,把設(shè)計重點放在IP、TCP和ARP協(xié)議的實現(xiàn)上。簡單易用、占用資源少是它的設(shè)計特點。
2、協(xié)議棧接口
UIP協(xié)議棧通過一系列接口函數(shù)與底層函數(shù)和上層應(yīng)用程序通信,在兩者之中,UIP接口函數(shù)處于中間。其中UIP提供兩個個接口函數(shù)給底層系統(tǒng)。分別是
(1)uip_input()
當(dāng)網(wǎng)卡驅(qū)動收到一個輸入包時,將放入全局緩沖區(qū)uip_buf中,包的大小由全局變量uip_len約束。同時將調(diào)用 uip_input() 函數(shù),這個函數(shù)將會根據(jù)包首部的協(xié)議處理這個包和需要時調(diào)用應(yīng)用程序。當(dāng) uip_input() 返回時,一個輸出包同樣放在全局緩沖區(qū)uip_buf里,大小賦給uip_len。如果uip_len 是0,則說明沒有包要發(fā)送。否則調(diào)用底層系統(tǒng)的發(fā)包函數(shù)將包發(fā)送到網(wǎng)絡(luò)上。
(2)uip_periodic()
uIP 周期計時是用于驅(qū)動所有的uIP 內(nèi)部時鐘事件。當(dāng)周期計時激發(fā),每一個TCP 連接都會調(diào)用uIP 函數(shù)uip_periodic() 。類似于 uip_input() 函數(shù)。uip_periodic()函數(shù)返回時,輸出的IP 包要放到uip_buf中,供底層系統(tǒng)查詢uip_len的大小發(fā)送。
UIP提供一個調(diào)用函數(shù)uip——appcall()與上位機(jī)應(yīng)用程序通信。當(dāng)uip在接收到底層傳來的數(shù)據(jù)包后,直接調(diào)用uip_appcall()就可以把數(shù)據(jù)傳送到上層應(yīng)用程序進(jìn)行處理。
系統(tǒng)底層其實在一開始時還需要調(diào)用初始化UIP的函數(shù)——uip_init(),主要是初始化協(xié)議棧的偵聽端口和默認(rèn)所有連接都是關(guān)閉的。
3、UIP協(xié)議棧在STM32上的移植
(1)DM9000A初始化和UIP初始化;
tapdev_init();uip_init();
(2)設(shè)置IP地址
uip_ipaddr(ipaddr, 192,168,1,10);
(3)設(shè)置默認(rèn)的路由器地址
uip_ipaddr(ipaddr, 192,168,1,1);
(4)設(shè)置網(wǎng)絡(luò)掩碼
uip_setnetmask(ipaddr);
(5)當(dāng)DM9000A接收到數(shù)據(jù)后會產(chǎn)生中斷,這時候從DM9000A讀取一個IP包,返回數(shù)據(jù)長度;
uip_len = tapdev_read();
(6)校驗處理數(shù)據(jù)包
BUF->type == htons(UIP_ETHTYPE_IP
(7)去除以太網(wǎng)幀頭結(jié)構(gòu),更新ARP表
uip_arp_ipin();
(8)IP包處理
uip_input();