![]() 前言 LwIP 在 lwipopts.h 和 opt.h 頭文件中提供了多個配置選項。用戶可以根據(jù)不同的性能需求和不同應(yīng)用的內(nèi)存限制對協(xié)議棧用到的內(nèi)存配置進行調(diào)節(jié)。Opt.h 頭文件中包括協(xié)議使能和設(shè)置,內(nèi)存設(shè)置,調(diào)試選項等等。而 Lwipopts.h 頭文件中集合了opt.h 中一些常常需要改動的部分。一般情況下用戶對 lwipopts.h 頭文件進行修改就可以了。不管是對lwipopts.h 還是opt.h進行修改,都必須保證是在已經(jīng)對你所改動的內(nèi)容足夠的了解的情況下進行,所做的改動是正確的,否則有可能導(dǎo)致協(xié)議棧 不能正常工作,或者效率低下。 在進行內(nèi)存配置之前,我們有必要先了解LwIP 的內(nèi)存管理機制。 Lwip 動態(tài)內(nèi)存管理LwIP 中可以使用兩種動態(tài)內(nèi)存分配的方法:Heap 和 Pool 的方式。 Heap 的方式,每次都根據(jù)你實際需要的大小分配一塊內(nèi)存出來用,用完以后再還回去。 Pool 的方式則是,預(yù)先將內(nèi)存等分成若干份,每次分配時都拿出其中的一塊或幾塊來。假設(shè)每等份是 256bytes,而你需要300bytes 的內(nèi)存空間,Pool 的方式就會給你分配兩個256bytes 的內(nèi)存塊(一共 512bytes)。雖然有點浪費,但這種方式分配內(nèi)存速度很快,非常適合在接收數(shù)據(jù)時使用。 對于 Heap 的方式,程序默認是使用LwIP 提供的mem_malloc/mem_free 進行內(nèi)存的分配和釋放。這種方式下,程序需要預(yù)先分配一段內(nèi)存空間用來做heap 分配,這段預(yù)留的空間大小通過 MEM_SIZE 定義。 你也可以通過 C 標(biāo)準庫里的 malloc/free 函數(shù)進行內(nèi)存的分配和釋放。需要定義宏 MEM_LIBC_MALLOC。 前面說的 Heap 和 Pool 都是 LwIP 動態(tài)分配內(nèi)存的方式。而 LwIP 采用了 pbuf 的形式管理內(nèi)存中的信息,pbuf 結(jié)構(gòu)既支持動 態(tài)內(nèi)存分配保存信息包內(nèi)容,也支持讓信息包數(shù)據(jù)駐留在靜態(tài)存儲區(qū)。pbufs 可以在一個鏈表中鏈接在一起,被稱作一個pbuf 鏈,這樣一個信息包可以跨越幾個pbufs。 LwIP 有三種類型的pbuf: PBUF_RAM, PBUF_ROM,PBUF_POOL。這三種類型擁有不同的使用目的。 ·PBUF_RAM 類型的 pbuf 用于應(yīng)用程序發(fā)送的數(shù)據(jù)被動態(tài)生成的情況。在這種情況下,pbuf 系統(tǒng)不僅為應(yīng)用數(shù)據(jù)分配內(nèi) 存,還要給為這些數(shù)據(jù)預(yù)置的包頭分配內(nèi)存。包頭大小在編譯時是可配置的。MEM_SIZE 定義定義了這類 pbuf 的可用空 間大小。 ·PBUF_ROM 類型的 pbuf 用于應(yīng)用程序要發(fā)送的數(shù)據(jù)放置在應(yīng)用程序管理的存儲區(qū)的情況。 ·PBUF_POOL 主要用于網(wǎng)絡(luò)設(shè)備驅(qū)動層,因為分配一個 pbuf 的操作可以快速完成,所以非常適合用于中斷處理。 ![]() 1. 接收數(shù)據(jù)緩存的大小 網(wǎng)絡(luò)接口接收到數(shù)據(jù)包,通過以太網(wǎng)專用DMA 放到專門的緩沖區(qū)。然后在low_level_input 函數(shù)中,被拷貝到 PBUF_POOL 中,再將指向該 PBUF_POOL 的指針傳遞給LwIP 協(xié)議棧做進一步的處理。這里用于拷貝接收到的數(shù)據(jù)的 PBUF_POOL 的大 小由下面這兩個配置選項決定:PBUF_POOL_SIZE 和 PBUF_POOL_BUFSIZE。 PBUF_POOL_SIZE:定義可用的 PBUF_POOL 的個數(shù) PBUF_POOL_BUFSIZE:定義每個 PBUF_POOL 的大小 PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE 的值就是接收數(shù)據(jù)內(nèi)存總的大小用戶需要根據(jù)接收的數(shù)據(jù)包的平均大小來設(shè)置這兩個值。PBUF_POOL_BUFSIZE 設(shè)置的太小,可能每個數(shù)據(jù)包都要多個pbuf 來保存;設(shè)置太大,很少的數(shù)據(jù)也會占用一個較大的pbuf 造成浪費。 2.發(fā)送數(shù)據(jù)緩存的大小 LwIP 通過 Heap 的方式可分配的總內(nèi)存空間大小由MEM_SIZE 定義,如果應(yīng)用程序需要發(fā)送大量數(shù)據(jù),而且這些數(shù)據(jù)需要拷 貝到 LwIP 協(xié)議棧中,那么這個值盡量設(shè)置大些。 3.連接 LwIP 協(xié)議棧中通過 PCB(Protocol Control Blocks)的方式管理各個連接。創(chuàng)建新的PCB 時,也是通過memory pool 的方式進行內(nèi)存分配。MEMP_NUM_UDP_PCB:定義可以創(chuàng)建的 UDP 連接個數(shù) MEMP_NUM_TCP_PCB:定義可以創(chuàng)建的 TCP 連接個數(shù) MEMP_NUM_TCP_PCB_LISTEN:可以創(chuàng)建 listening TCP 連接的個數(shù) MEMP_NUM_NETCONN:使用 netconn 和socket 編程時,該值的大小會影響可以同時創(chuàng)建的連接的個數(shù) MEMP_NUM_NETBUF:使用 netconn 和 socket 編程時,該值設(shè)置太小,可能導(dǎo)致接收數(shù)據(jù)時分配內(nèi)存失敗,從而不能同時為幾個連接的數(shù)據(jù)收發(fā)服務(wù)。 4. TCP 選項 TCP_MSS :該值規(guī)定了TCP 數(shù)據(jù)包數(shù)據(jù)部分的最大長度 TCP_SND_BUF:一個TCP 連接的發(fā)送緩存空間大小。改變這個值只影響一個TCP 連接可用的發(fā)送緩存空間大小?偟陌l(fā)送緩存空間是不會變的(由 MEM_SIZE 決定)。如果同時活動的TCP 連接個數(shù)很多,這個值不宜設(shè)置的太大。 TCP_SND_QUEUELEN:TCP 發(fā)送隊列中最多的pbuf 個數(shù) TCP_WND:TCP 接收窗口大小 LwIP 中的很多配置并不是孤立的,在 lwipopts.h 和 opt.h 的某些配置選項前面都有說明需要滿足的條件。在修改這些參數(shù)時 需要特別注意。另外 LwIP 還提供了“sanity checks”,在編譯時(LwIPv1.4.1,之前的版本是在 lwip_sanity_check 函數(shù)中進 行檢查)對 lwipopts.h 和opt.h 中的一些關(guān)鍵的配置進行檢查,如果發(fā)現(xiàn)錯誤就會通過error 信息進行提示。該功能可以通過宏LWIP_DISABLE_MEMP_SANITY_CHECKS 關(guān)閉,建議在調(diào)試時打開。 另外一個可以在配置LwIP 眾多選項時給你提供幫助的工具就是CubeMX。CubeMX 里的LwIP 配置頁面對每個選項都做了詳細解釋,包括建議的最大/最小值。見下圖: ![]() 重要通知 - 請仔細閱讀 意法半導(dǎo)體公司及其子公司(“ST”)保留隨時對ST 產(chǎn)品和/ 或本文檔進行變更、更正、增強、修改和改進的權(quán)利,恕不另行通知。買方訂貨之前應(yīng)獲取關(guān)于ST 產(chǎn)品的最新信息。ST 產(chǎn)品的銷售依照訂單確認時的相關(guān)ST 銷售條款。 買方自行負責(zé)對ST 產(chǎn)品的選擇和使用, ST 概不承擔(dān)與應(yīng)用協(xié)助或買方產(chǎn)品設(shè)計相關(guān)的任何責(zé)任。 ST 不對任何知識產(chǎn)權(quán)進行任何明示或默示的授權(quán)或許可。 轉(zhuǎn)售的ST 產(chǎn)品如有不同于此處提供的信息的規(guī)定,將導(dǎo)致ST 針對該產(chǎn)品授予的任何保證失效。 ST 和ST 徽標(biāo)是ST 的商標(biāo)。所有其他產(chǎn)品或服務(wù)名稱均為其各自所有者的財產(chǎn)。 本文檔中的信息取代本文檔所有早期版本中提供的信息。 © 2015 STMicroelectronics - 保留所有權(quán)利 文章來源:微信公眾號號 融創(chuàng)芯城 |