国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
LWIP使用經(jīng)驗

http://blog.csdn.net/yangzhao0001/article/details/48625927

2015


LWIP使用經(jīng)驗

 LWIP內(nèi)存管理

LWIP的內(nèi)存管理使用了2種方式:內(nèi)存池memp和內(nèi)存堆mem,如圖1所示。

內(nèi)存池的特點是預(yù)先開辟多組固定大小的內(nèi)存塊組織成鏈表,實現(xiàn)簡單,分配和回收速度快,不會產(chǎn)生內(nèi)存碎片,但是大小固定,并且需要預(yù)估算準確。

內(nèi)存堆的本質(zhì)是對一個事先定義好的內(nèi)存塊進行合理有效的組織和管理,主要用于任意大小的內(nèi)存分配,實現(xiàn)較復(fù)雜,分配需要查找,回收需要合并,容易產(chǎn)生內(nèi)存碎片,需要合理估算內(nèi)存堆的總大小。

 

1內(nèi)存池與內(nèi)存堆

1.     數(shù)據(jù)包管理

數(shù)據(jù)包管理結(jié)構(gòu)pbuf共有四種類型,它們的特點和使用場合如表1所示。

類別

分配方式

特點

使用場合

PBUF_RAM

內(nèi)存堆,包括pbuf和數(shù)據(jù)區(qū)

長度不定,分配耗時

應(yīng)用程序和協(xié)議棧

PBUF_POOL

內(nèi)存池,包括pbuf和數(shù)據(jù)區(qū)

長度固定,分配快

中斷服務(wù)程序

PBUF_ROM

內(nèi)存池,僅包括pbuf

所指數(shù)據(jù)位于ROM

應(yīng)用程序引用內(nèi)存區(qū)

PBUF_REF

內(nèi)存池,僅包括pbuf

所指數(shù)據(jù)位于RAM

應(yīng)用程序引用內(nèi)存區(qū)

1  pbuf類型與特點

每一種pbuf分配內(nèi)存的方式都不一樣,如圖2所示。

2四種數(shù)據(jù)包管理結(jié)構(gòu)

只有選擇合適的pbuf類型才能發(fā)揮LWIP的最大性能,一個數(shù)據(jù)包可能是多種pbuf的組合,用鏈表連接起來,如圖3所示。

3  pbuf鏈表

2.     設(shè)置內(nèi)存大小

LWIP開辟一個專用的內(nèi)存堆是應(yīng)該的,這樣一來LWIPmem_alloc()mem_free()都將基于該堆內(nèi)存進行分配和回收,不影響其他系統(tǒng)內(nèi)存的使用。如圖1左所示,lwipopt.h文件中宏MEM_SIZE定義了堆區(qū)的大小,對于一個負荷較重的系統(tǒng)堆區(qū)需要分配較大。

4堆和PBUF_ROM內(nèi)存區(qū)

LWIP使用PBUF_ROM類型的內(nèi)存池來發(fā)送“只讀”數(shù)據(jù)(處于ROM中或者其他進程中不可修改),宏MEMP_NUM_PBUF定義了該緩沖池的個數(shù),如圖2右所示。

ISR(中斷服務(wù)程序中)經(jīng)常需要快速分配一部分內(nèi)存進行數(shù)據(jù)存儲,這是通過PBUF_POOL類型的緩沖區(qū)實現(xiàn)的。為此需要定義兩個宏:PBUF_POOL_SIZE定義緩沖池的個數(shù),PBUF_POOL_BUFSIZE定義單個緩沖區(qū)的大小,如圖5所示。

圖5 PBUF_POOL內(nèi)存區(qū)

宏編譯開關(guān)

若定義MEM_LIBC_MALLOC=1,直接使用C庫中的malloc、free來分配動態(tài)內(nèi)存;否則使用LWIP自帶的mem_malloc、mem_free等函數(shù)。

若定義MEMP_MEM_MALLOC=1,則memp.c中的全部內(nèi)容不會被編譯,用內(nèi)存堆來實現(xiàn)內(nèi)存池分配,使用這種方式得考慮是否能忍受內(nèi)存堆分配帶來的時間延遲。

若定義MEM_USE_POOLS=1,則mem.c中的全部內(nèi)容不會被編譯,用內(nèi)存池來實現(xiàn)內(nèi)存堆的分配,使用這種方式得考慮是否能忍受因為POOL內(nèi)存固定大小而帶來的內(nèi)存浪費。此外用戶需要定義宏MEM_USE_CUSTOM_POOLS=1,還需要額外實現(xiàn)一個頭文件lwippools.h,并在其中開辟一些用于內(nèi)存堆分配函數(shù)的內(nèi)存池POOL,開辟空間的格式如下:

LWIP_MALLOC_MEMPOOL_START

LWIP_MALLOC_MEMPOOL(20, 256)

LWIP_MALLOC_MEMPOOL(10, 512)

LWIP_MALLOC_MEMPOOL_END

 LWIP啟動時序

6展示了LWIP啟動時序,大部分函數(shù)都是LWIP自帶的,主要的移植代碼是eth_init()實現(xiàn)初始化以太網(wǎng)接口,啟動程序會創(chuàng)建2個線程:tcpip_thread負責LWIP的絕大部分工作(主要是協(xié)議棧的解析和系統(tǒng)運行),ethernetif_thread負責從網(wǎng)口接收數(shù)據(jù)包再交付給tcpip_thread線程進行處理。

圖6 LWIP啟動函數(shù)

 LWIP運行邏輯

接收數(shù)據(jù)包

圖7接收數(shù)據(jù)包

當以太網(wǎng)口接收到一個數(shù)據(jù)包后,EMAC_IRQ中斷服務(wù)程序通過信號量通知ethernetif線程,ethernetif線程調(diào)用low_level_input()接收該數(shù)據(jù)包并通過郵箱交付給tcpip_thread線程,tcpip_thread根據(jù)該數(shù)據(jù)包的類型進行相應(yīng)處理。它是建立在消息傳遞的基礎(chǔ)上的,如圖8所示。

圖8數(shù)據(jù)包消息的產(chǎn)生和處理

2  SequentialAPI函數(shù)調(diào)用

API設(shè)計的核心在于讓用戶進程負責盡可能多的工作,例如數(shù)據(jù)的計算、拷貝等;而協(xié)議棧進程只負責簡單的通信工作,這是很合理的,因為系統(tǒng)可能存在多個應(yīng)用程序,它們都使用協(xié)議棧進程提供的通信服務(wù),保證內(nèi)核進程的高效性和實時性是提高系統(tǒng)性能的重要保障。進程之間通信使用IPC技術(shù),包括郵箱、信號量和共享內(nèi)存,如圖9所示。

圖9協(xié)議棧API實現(xiàn)

以函數(shù)netconn_bind()為例看API是如何實現(xiàn)的,首先用戶程序中調(diào)用函數(shù)netconn_bind()綁定一個連接,則這個函數(shù)實現(xiàn)時,是通過向內(nèi)核進程發(fā)送一個TCPIP_MSG_API類型的消息,告訴內(nèi)核進程執(zhí)行do_bind函數(shù):在消息發(fā)送后,函數(shù)阻塞在信號量上,等待內(nèi)核處理該消息;內(nèi)核在處理消息時,會根據(jù)消息內(nèi)容調(diào)用do_bind,而do_bind會根據(jù)連接的類型調(diào)用內(nèi)核函數(shù)udp_bind、tcp_bind或raw_bind;當do_bind執(zhí)行完后,它會釋放信號量,這使被阻塞的netconn_bind得以繼續(xù)執(zhí)行,整個過程如圖10所示。

圖10 API函數(shù)實現(xiàn)

 TCP/IP核心知識點

1.       滑動窗口

11滑動窗口

接收窗口相關(guān)的字段中,rcv_nxt是自己期望收到的下一個字節(jié)編號,rcv_wnd表示接收窗口的大小,rcv_ann_wnd表示將向?qū)Ψ酵ǜ娴拇翱诖笮≈?,這個值在報文發(fā)送時會被填在首部中的窗口大小字段,rcv_ann_right_edge記錄了上一次窗口通告時窗口右邊界取值。上面這四個字段都會隨著數(shù)據(jù)的發(fā)送和接收動態(tài)地改變,如圖12所示。

圖12接收窗口

發(fā)送窗口中,lastack記錄了被接收方確認的最高序列號,snd_nxt表示自己將要發(fā)送的下一個數(shù)據(jù)的起始編號,snd_wnd記錄了當前的發(fā)送窗口大小,它常被設(shè)置為接收方通告的接收窗口值,snd_lbb記錄了下一個被應(yīng)用程序緩存的數(shù)據(jù)的起始編號,如圖10所示。

上面這四個字段的值也是動態(tài)變化的,每當收到接收方的一個有效ACK后,lastack的值就做相應(yīng)的增加,指向下一個待確認數(shù)據(jù)的編號,當發(fā)送一個報文后,snd_nxt的值就做相應(yīng)的增加,指向下一個待發(fā)送數(shù)據(jù),snd_nxtlastack之間的差值不能超過snd_wnd的大小。

由于實際數(shù)據(jù)發(fā)送時是按照報文段的形式組織的,因此可能存在這樣的情況:即使發(fā)送窗口允許,但并不是窗口內(nèi)的所有數(shù)據(jù)都能發(fā)送以填滿窗口,如圖13中編號為1113的數(shù)據(jù),可能因為它們太小不能組織成一個有效的報文段,因此不會被發(fā)送。發(fā)送方會等到新的確認到來,從而使發(fā)送窗口向右滑動,使得更多的數(shù)據(jù)被包含在窗口中,這樣再啟動下一個報文段的發(fā)送。

13發(fā)送窗口

2.       三次握手

14連接建立過程

3.       斷開連接

15連接斷開過程

4.      TCP狀態(tài)轉(zhuǎn)換

16  TCP狀態(tài)轉(zhuǎn)換圖

5.       同時打開

17雙方同時打開

6.       同時關(guān)閉

 

18雙方同時關(guān)閉

五正確使用LWIP

一般說來LWIP協(xié)議棧是比較穩(wěn)定的,尤其像V1.3.2經(jīng)歷過業(yè)界廣泛使用和工程應(yīng)用,完全可以應(yīng)用于嵌入式產(chǎn)品。那為什么還是有很多人反映LWIP不穩(wěn)定呢?主要是以下幾個方面的原因:

1.      網(wǎng)絡(luò)硬件驅(qū)動 確保EMAC口接收與發(fā)送穩(wěn)定可靠

2.      移植LWIP 基于OS的移植代碼正確穩(wěn)定

3.      配置LWIP 根據(jù)設(shè)備RAM尺寸進行合理配置

1)        值(PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE)必須大于TCP_SND_BUFTCP_WND,否則容易引起錯誤;

2)        當內(nèi)存有限時TCP發(fā)送不能太快(具體值依賴于分配內(nèi)存的大?。?,否則引起tcp_enqueue()邏輯錯誤;

4.      調(diào)用LWIPAPI函數(shù) 正確使用API函數(shù),特別防止內(nèi)存泄露。

5.      資源不足 打開報警提醒,當資源不夠時提醒設(shè)計者

 LWIP常見問題

1.       網(wǎng)卡驅(qū)動程序

首先,必須將協(xié)議棧完全初始化才能打開網(wǎng)絡(luò)接收功能,接收中斷必須將數(shù)據(jù)封裝在PBUF中,然后交會給協(xié)議棧內(nèi)核處理。其次,LWIP的全局變量(arp_table,netif_list,udp_pcbs等)確保賦初值0,否則容易一運行就崩潰。

2.       內(nèi)存泄露

第一個原則(責任制):誰分配內(nèi)存,誰就負責回收。

第二個原則(對稱性):分配內(nèi)存者與回收內(nèi)存者一一對應(yīng)構(gòu)成閉環(huán)。

另外,需要特別注意一些系統(tǒng)函數(shù)的調(diào)用,它們也會帶來內(nèi)存泄露,如:

1

newconn = netconn_accept(conn);

do_something_for(newconn);

netconn_close(newconn);

netconn_delete(newconn);   /*一定要釋放newconn否則將導(dǎo)致內(nèi)存泄露 */

 

2

inbuf = netconn_recv(conn);

do_something_for(inbuf);

netbuf_delete(inbuf);   /*一定要釋放inbuf否則將導(dǎo)致內(nèi)存泄露 */

3.      PC機無法與LWIP建立TCP連接

問題:PC機能夠與LWIP設(shè)備PING操作成功,但是無法建立TCP連接。

原因:通過代碼跟蹤,發(fā)現(xiàn)LWIP發(fā)出了SYN+ACK數(shù)據(jù)包,但是PC機無法接收該握手數(shù)據(jù)包,該數(shù)據(jù)包為60字節(jié),小于以太網(wǎng)的最小長度(64字節(jié)),而LWIP設(shè)備的EMAC沒有設(shè)置短小數(shù)據(jù)包填充功能,導(dǎo)致PC機無法接收該短數(shù)據(jù)包。

解決:使能EMAC的短小數(shù)據(jù)包填充功能。



本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
lwIP配置文件opt.h和lwipopts.h初步分析
手把手教你手擼通訊協(xié)議(二)-網(wǎng)絡(luò)的基礎(chǔ)
lwip之內(nèi)存管理
嵌入式以太網(wǎng):Lwip內(nèi)存管理之內(nèi)存堆
LwIP在stm32上的無操作系統(tǒng)移植
LwIP源代碼文件目錄解析
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服