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