1. 程式人生 > >LWIP的資料包管理

LWIP的資料包管理

歡迎檢視本文所在的系列,STM32的LWIP應用,點選跳轉

1、資料包結構-pbuf

1.1、pbuf結構

  LWIP是TCP/IP協議棧的一種具體實現,本質就是對資料包的處理,在LWIP中使用一個被稱為pbuf的結構管理資料包,LWIP原始碼中的pbuf.c和pbuf.h這兩個檔案就是關於pbuf的,pbuf結構如下:在pbuf.h檔案中

1.2、tot_len

說一下tot_len的講解

大家最好理解一下英文註釋


1.3、type

從這裡可是使用編譯器跳過去
也就是pbuf_type的型別有

分別講一下這四種類型

1.3.1、PBUF_RAM

      PBUF_RAM型別的pbuf空間是從LWIP的記憶體堆中申請得到的,協議棧和應用程式中的待發送資料就是採用的這種方法,pbuf的申請是在pbuf_alloc()中進行的mem_malloc()函式,知道是從記憶體堆裡申請的記憶體申請的大小是:pbuf的大小 + 實際申請的大小offset是一個偏移,這個offset裡面用來儲存一些首部欄位,如TCP報文首部,IP首部等等。 最終申請出來的PBUF_RAM型別的pbuf結構是下圖1部分的就是pbuf結構部分2部分是offset部分

1.3.2、PBUF_POOL  

      PBUF_POOL型別的pbuf空間是從LWIP的記憶體池中申請得到的,因為是從記憶體池中申請的,所以這種型別的pbuf分配時間極短,在網絡卡接收資料包時,我們使用這種方式:在pbuf.c檔案中pbuf_alloc函式
既然PBUF_POOL型別是在記憶體池中申請的,那麼就必須得有對應的POOL型別,在LWIP初始化的時候就會自動的兩類與pbuf相關的POOL:MEMP_PBUF和MEMP_PBUF_POOL(在memp_std.h中),其中MEMP_PBUF是用於PBUF_REF和PBUF_ROM這兩類的,MEMP_PBUF_POOL是用於PBUF_POOL型別的。    事實上應用程式傳送和接收的資料量可能很大,但是記憶體池型別的記憶體分配每次分配到的大小是固定的,因此可能會需要進行多次分配,最終的分配成功的PBUF_POOL型別的pbuf如下圖:

1.3.3、PBUF_ROM和PBUF_REF

      PBUF_ROM和PBUF_REF型別的pbuf空間也是從LWIP的記憶體池中申請得到的,分配方法都一樣的,他們使用記憶體池MEMP_PBUF,這兩種型別申請的是指pbuf結構體的記憶體空間,並不包含資料空間,分配過程如下:

PBUF_ROM和PBUF_REF並沒有給資料空間申請記憶體,那麼他們的資料空間在哪裡呢?這兩個的資料空間可以應用其他地方的記憶體,不同之處在於PBUF_ROM的資料空間在ROM中,PBUF_REF的資料空間在RAM中。這兩種型別的pbuf最終如下:

1.3.4、多種型別pbuf混合使用

實際的資料包可能會同時使用多種型別的pbuf,如下圖:

2、資料包申請和釋放

      pbuf的申請和釋放通過函式pbuf_alloc()和pbuf_free()來完成,pbuf_alloc()函式和pbuf_free()函式原型如下:pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)pbuf_free(struct pbuf *p)      pbuf_alloc()函式有兩個重要的引數:layer和type,layer決定是協議棧的哪一層申請的,type決定申請的pbuf型別,layer決定了pbuf中的offset,也就是pbuf資料區中衛協議預留的首部空間,pbuf.h檔案定義了一個列舉型別pbuf_layer來描述LWIP中的層,如下:
typedef enum {
  PBUF_TRANSPORT,
  PBUF_IP,
  PBUF_LINK,
  PBUF_RAW
} pbuf_layer;

如果看文字版太枯燥,可以點選看視訊版:點選跳轉