蔡雄飛,王新華,郭淑琴
(1浙江工業(yè)大學(xué)信息工程學(xué)院,浙江杭州310023;2浙江科技學(xué)院信息與電子工程學(xué)院,浙江杭州310023)
嵌入式系統(tǒng)中廣泛采用的網(wǎng)絡(luò)協(xié)議棧一般是作為嵌入式操作系統(tǒng)內(nèi)核的一部分,應(yīng)用中只需要在系統(tǒng)內(nèi)核配置標(biāo)中標(biāo)記使用即可,但這些商用操作系統(tǒng)高昂的版權(quán)費不利于初期的開發(fā)。LwIP(Lightweight Internet Protocol)是瑞士計算機科學(xué)院的Adam Dunkels等開發(fā)出來的一套用于嵌入式系統(tǒng)的開源TCP/IP協(xié)議棧,可以方便地移植于各種開源的嵌入式操作系統(tǒng)。LwIP的主要特點是在保證了TCP/IP協(xié)議基本功能模塊的基礎(chǔ)上,減少了對RAM的占用,一般只需要幾十KB的RAM就可以運行[1]。目前,最新的LwIP已經(jīng)發(fā)展到了1.4.0版。本文主要分析和研究了LwIP協(xié)議棧的內(nèi)存管理機制,并設(shè)計出了網(wǎng)絡(luò)接口層的主收發(fā)程序。
LwIP采用pbuf(packet buffer)結(jié)構(gòu)和pbuf鏈來管理數(shù)據(jù)包。pbuf結(jié)構(gòu)既能在動態(tài)內(nèi)存分配下保存信息包的數(shù)據(jù),也能夠讓信息包數(shù)據(jù)駐留在靜態(tài)存儲區(qū),通過結(jié)構(gòu)中的*prev和*next指針將存儲數(shù)據(jù)包信息的各個pbuf結(jié)構(gòu)“連接”起來,在邏輯上構(gòu)成一個pbuf鏈。pbuf鏈實現(xiàn)了使物理上呈分散存儲的數(shù)據(jù)能夠在邏輯上連續(xù)讀寫,這樣就減少了頻繁的數(shù)據(jù)拷貝和內(nèi)存分配操作。LwIP管理內(nèi)存的pbuf結(jié)構(gòu)為[2,3]:
pbuf具有PBUF_POOL、PBUF_ROM和PBUF_RAM 3種類型,結(jié)構(gòu)中的flags成員變量即用來標(biāo)識它的類型。由于分配一個pbuf的操作可以快速完成,PBUF_POOL主要用于網(wǎng)絡(luò)設(shè)備驅(qū)動層,適合用于中斷處理。當(dāng)應(yīng)用程序要發(fā)送的數(shù)據(jù)位于應(yīng)用程序管理的存儲區(qū)時,則會分配PBUF_ROM類型的pbuf。而PBUF_RAM類型的pbuf主要用于應(yīng)用程序發(fā)送的數(shù)據(jù)由動態(tài)生成的情況下。此時,pbuf系統(tǒng)不僅可以為應(yīng)用數(shù)據(jù)分配內(nèi)存,還會為待發(fā)送數(shù)據(jù)預(yù)分配包頭內(nèi)存空間。
LwIP的內(nèi)存管理能夠適應(yīng)大小變化的接收或發(fā)送緩沖區(qū),其范圍從包含幾百字節(jié)數(shù)據(jù)的TCP段緩沖區(qū)到僅僅包含幾個字節(jié)的ICMP回報。
當(dāng)應(yīng)用層要發(fā)送的數(shù)據(jù)位于外部存儲區(qū)時,將會分配到PBUF_ROM。外部存儲區(qū)是指不由TCP/IP協(xié)議管理和操作的存儲區(qū),它可以是應(yīng)用程序管理的存儲器為用戶數(shù)據(jù)分配的緩存,也可以是ROM區(qū)域,如靜態(tài)網(wǎng)頁中的字符串常量等。由于應(yīng)用程序交付給協(xié)議棧的數(shù)據(jù)不能被改動,因此就需要動態(tài)地分配一個PBUF_RAM類型的pbuf來裝載各層協(xié)議的首部,然后將PBUF_RAM(存儲首部)添加到PBUF_ROM(存儲數(shù)據(jù))的前面,這樣就構(gòu)成了一個完整的數(shù)據(jù)分組。由此可見,承載數(shù)據(jù)包的pbuf鏈可以包含不同類型的pbuf結(jié)構(gòu)[4]。如圖1(a)所示,PBUF_ROM的數(shù)據(jù)指針payload指向外部存儲區(qū)。
圖1 發(fā)送數(shù)據(jù)時的pbuf
如圖1(b)所示,當(dāng)應(yīng)用程序待發(fā)送的數(shù)據(jù)是動態(tài)生成時,系統(tǒng)分配若干個PBUF_RAM類型的pubf,組成一條pbuf鏈。PBUF_RAM類型的pbuf在事先劃分好的內(nèi)存堆中分配。每個被分配的存儲塊附帶了一個小結(jié)構(gòu),該結(jié)構(gòu)的兩個指針(*prev和*next)分別指向相鄰的內(nèi)存塊。根據(jù)要添加的各層報頭大小,在分配PBUF_RAM時會預(yù)留相應(yīng)大小的空間用于包頭填充。used標(biāo)識位用來指示該內(nèi)存塊的分配情況,陰影部分表示已經(jīng)被分配了,此時used為1。當(dāng)需要一塊N字節(jié)的存儲塊時,就對整個存儲堆進(jìn)行搜索。如果找到一塊未用的(used=0)并且容量不小于N字節(jié)的區(qū)域就表示分配成功,并且置used為1。根據(jù)LwIP內(nèi)存分配與回收利用的原則,設(shè)計了實現(xiàn)網(wǎng)絡(luò)接口層數(shù)據(jù)發(fā)送的主函數(shù)low_level_output()。
該函數(shù)包含兩個參數(shù),分別是管理待發(fā)送數(shù)據(jù)的pbuf以及用于發(fā)送數(shù)據(jù)的邏輯網(wǎng)絡(luò)接口netif。mem_malloc()根據(jù)pbuf結(jié)構(gòu)中tot_len成員變量的值,為待發(fā)送數(shù)據(jù)分配相應(yīng)大小的發(fā)送緩沖區(qū)。
如圖2所示,當(dāng)網(wǎng)絡(luò)接口層讀取到網(wǎng)絡(luò)控制器接收緩沖區(qū)有數(shù)據(jù)到來時,遍立即獲得數(shù)據(jù)包的包頭并調(diào)用GetInputPacketLen()函數(shù)獲得幀長,然后根據(jù)幀長分配若干大小適中的PBUF_POOL類型的pbuf組成一個pbuf鏈,將接收緩沖區(qū)的數(shù)據(jù)拷貝到鏈中。
圖2 接收數(shù)據(jù)時的pbuf
PBUF_POOL是具有固定容量的pbuf,為網(wǎng)絡(luò)接口層收到的數(shù)據(jù)包分配緩存。在協(xié)議棧管理的內(nèi)存中初始化了一個pbuf池(PBUF_POOL),具有相同尺寸的pbuf都是從這個pbuf池中分配得到的。在網(wǎng)絡(luò)接口層,真正實現(xiàn)數(shù)據(jù)接收的函數(shù)是low_level_inpu()。
在檢測到硬件網(wǎng)絡(luò)接口ethernetif有數(shù)據(jù)待接收時,pbuf_alloc()分配len大小的內(nèi)存空間,以pbuf邏輯鏈的形式將數(shù)據(jù)保存到內(nèi)存中再進(jìn)行校驗、去包頭、提取源地址信息等操作。
實驗采用了Keil公司基于Cortex-M3內(nèi)核的MCBTMPM360開發(fā)板來驗證上述基于該內(nèi)存管理機制的底層網(wǎng)絡(luò)接口收發(fā)模塊的有效性。該開發(fā)板配有一顆東芝TMPM364F10FG芯片,具有64KB大小的RAM和1M的Flash存儲空間,各項硬件資源滿足實驗要求。實驗前在LwIP的相關(guān)文件中對目標(biāo)板的IP 地址進(jìn)行靜態(tài)配置(如設(shè)為192.168.1.3),使用C 類私用地址192.168.1.0網(wǎng)段,使其與PC 的IP地址192.168.1.6在同一網(wǎng)段。然后把協(xié)議棧和修改后的與硬件相關(guān)的配置文件、SimpleSvr(一種用于測試的簡單Web服務(wù)器程序)下載到目標(biāo)板的Flash上。將PC機與開發(fā)板通過RJ45接口用超五類非屏蔽雙絞線連接起來。實驗第一步首先使用Ping命令,驗證目標(biāo)板與PC之間的網(wǎng)絡(luò)鏈路能否連通。為進(jìn)一步驗證該協(xié)議棧工作的有效性,在PC機的Web瀏覽器地址欄中鍵入目標(biāo)板的IP地址,申請訪問目標(biāo)板Web服務(wù)器上一個簡單的Htm l頁面。實驗結(jié)果如圖3所示。
圖3 實驗結(jié)果
實驗結(jié)果表明,該協(xié)議棧工作穩(wěn)定,文中提出的基于該內(nèi)存管理機制的網(wǎng)絡(luò)收發(fā)模塊能夠完成基本的網(wǎng)絡(luò)應(yīng)用,實現(xiàn)了預(yù)期的結(jié)果,為后續(xù)的嵌入式網(wǎng)絡(luò)應(yīng)用開發(fā)打下了基礎(chǔ)。
本文研究了輕量級嵌入式TCP/IP協(xié)議棧LwIP的內(nèi)存管理機制,給出了適用于存儲資源有限的嵌入式系統(tǒng)網(wǎng)絡(luò)接口層的主收發(fā)程序模型,并對其有效性進(jìn)行了實驗測試,測試結(jié)果滿意。為LwIP協(xié)議棧在μC/OS-II嵌入式實時操作系統(tǒng)上的移植以及最終設(shè)計出Cortex-M3平臺上基于μC/OS-II&LwIP的嵌入式Web服務(wù)器具有重要意義[5]。
[1] 孫樂明,江來,代鑫.嵌入式TCP/IP協(xié)議棧LWIP的內(nèi)部結(jié)構(gòu)探索與研究[J].電子元器件應(yīng)用,2008,3(10):26-28.
[2] Savannah Inc.Design and Implementation of the LwIP TCP/IP Stack[EB/OL].http://savannah.nongnu.org,2007-06-12.
[3] 馬爭鳴,張成言.TCP/IP原理與應(yīng)用[M].北京:冶金工業(yè)出版社,2006:121-124.
[4] 付曉軍,夏應(yīng)清,何軒.嵌入式LwIP協(xié)議棧的內(nèi)存管理[J].電子技術(shù)應(yīng)用,2006,8(3):56-57.
[5] Jeremy Bentham.陳向群譯.嵌入式Web服務(wù)器TCP/IP Lean[M].北京:機械工業(yè)出版,2003:78-82.