LWIP數據包和網絡接口管理

LWIP數據包管理

lwip使用pbuf結構體來描述協議棧使用的數據包,pbuf結構體在pbuf.h中的定義

struct pbuf{
    struct pbuf*next;    //指向下一個pbuf結構體,可以構成鏈表
    void *payload;       //指向該pbuf真正的數據區
    u16_t tot_len;       //當前pbuf和鏈表中後面所有pbuf的數據長度,他們屬於一個數據包
    u16_t len;           //當前pbuf的數據長度
    u8_t type;           //當前pbuf的類型
    u8_t flags;          //狀態位,保留
    u16_t ref;           //該pbuf被引用的次數
}

next:指向下一個pbuf的結構體,每個pbuf能夠存放的數據有限,如果應用有大量的數據的話我們需要多個pbuf來存放,我們將同一個數據包的pbuf連接在一起形成一個鏈表,next字段就是實現這個鏈表的關鍵

payload:指向該pbuf的數據存儲區的首地址,STM32F407內部網絡模塊接收到數據並將數據提交給LWIP的時候,就是將數據存儲到payload指定的存儲區中,同樣在發送數據的時候將payload所指向的存儲區轉給STM32F429的網絡模塊去發送

tot_len:我們再接收或者發送數據的時候數據會存放在pbuf鏈表中,tot_len字段就表示當前pbuf和鏈表中以後所有pbuf總的數據長度

len:當前pbuf總數據的長度

type:當前pbuf的類型,一共有四種:PBUF_RAM  PBUF_ROM  PBUF_REF  PBUF_POOL

flag:保留位

ref:該pbuf被引用的次數,當還有其他指針指向它的時候ref字段就加一

PBUF_RAM類型的pbuf是通過內存分配得到的,pbuf_RAM類型的pbuf如圖所示 ,從圖中可以看出payload並未指向數據區的其實地址,而是隔了一段區域,這段區域是offset,在裏面通常存放的是TCP的報文首部,IP首部,以太網幀首部

PBUF_POOL類型的pbuf是通過內存池分配的,PBUF_POOL類型的pbuf如圖所示

可以看出鏈表中的第一個pbuf的payload未指向數據區的起始位置,原因和PBUF_RAM一樣,用來存放一些首部的

LWIP網絡接口管理

在LWIP中對網絡接口的描述是通過一個netif結構體完成的,netif結構體在netif.h文件中定義,由於netif結構體比較大,這裏只保留了一些比較重要的字段,具體的entif結構體定義請查閱netif.h文件

struct  netif{
    struct netif*next;                //指向下一個netif結構體
    ip_addr_t ip_addr;                //網絡接口ip地址
    ip_addr_t netmask;                //子網掩碼
    ip_addr_t gw;                     //默認網關
    netif_input_fn input;             //ip層接收數據函數
    netif_output_fn output;           //ip層發送數據包調用
    netif_linkoutput_fn  linkoutput;  //底層數據包發送
    void *state;                      //設備的狀態信息
    u16_t mtu;                        //該網絡接口最大允許傳輸的數據長度
    u8_t hwaddr_len                   //物理地址長度
    u8_t hwaddr[NETIF_MAXHWADDR_LEN]; //該網絡接口的物理地址 
    u8_t flgs;                        //該網絡接口的狀態和屬性                        
    char name[2];                     //該網絡接口的名字
    u8_t num;                         //該網絡接口的編號
}

next:該字段指向下一個netif類型的結構體,因爲LWIP可以支持多個網絡接口,當設備有多個網絡接口的話LWIP就會把所有的netif結構體組成鏈表來管理這些網絡接口

ipaddr, netmask 和 gw分別爲網絡接口的ip地址子網掩碼和默認網關。

input:此字段爲一個函數,這個函數將網卡接收到的數據交給ip層。

output:此字段爲一個函數,當ip層向接口發送一個數據包時調用此函數,這個函數通常首先解析硬件地址,然後發送數據包,此字段我們一般使用etharp.c中的etharp_output()函數

linkoutput:此字段爲一個函數,該函數被ARP模塊調用,完成網絡數據的發送,上面說的etharp_output函數將IP數據包封裝成以太網數據幀以後就會調用linkout函數將數據發送出去。

state:用來定義一些關於接口的信息,用戶可以自行設置

mtu:網絡接口所能傳輸的最大數據長度,一般設置爲1500

hwaddr_len和hwadde表示網絡接口物理地址長度和具體的地址信息

flags:表示網絡接口的狀態和屬性信息,是很重要的字段,包括網卡功能的使能,廣播使能,ARP使能

name:網絡接口的名字

num:網絡接口的編號

以上我們只列出了netif結構體中幾個比較重要的字段,我們對於網絡接口的初始化就是給這些字段賦值

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章