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結構體中幾個比較重要的字段,我們對於網絡接口的初始化就是給這些字段賦值