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