您好,登錄后才能下訂單哦!
netdev_pbuf_alloc是網(wǎng)卡驅(qū)動(dòng)中的內(nèi)存申請(qǐng)函數(shù),申請(qǐng)一塊緩沖區(qū)用于存放網(wǎng)絡(luò)報(bào)文數(shù)據(jù)。
netdev_pbuf_alloc函數(shù)以pbuf結(jié)構(gòu)申請(qǐng)內(nèi)存空間,如程序清單 2.1所示。
程序清單 2.1 pbuf結(jié)構(gòu)
struct pbuf { struct pbuf *next; void *payload; u16_t tot_len; u16_t len; u8_t type; u8_t flags; u16_t ref; };
netdev_pbuf_alloc函數(shù)是pbuf_alloc函數(shù)的函數(shù)封裝,對(duì)外提供的函數(shù)接口只帶有一個(gè)參數(shù)用于指定申請(qǐng)的緩沖區(qū)大小。而pbuf_alloc函數(shù)有三個(gè)參數(shù),分別是申請(qǐng)的pbuf數(shù)據(jù)緩沖區(qū)是否帶有偏移,數(shù)據(jù)緩沖區(qū)大小及緩沖區(qū)類型。在netdev_pbuf_alloc函數(shù)中,申請(qǐng)的pbuf結(jié)構(gòu)緩沖區(qū)數(shù)據(jù)偏移固定為0,緩沖區(qū)類型為PBUF_POOL。netdev_pbuf_alloc函數(shù)傳入的第二個(gè)參數(shù)緩沖區(qū)大小在調(diào)用pbuf_alloc函數(shù)申請(qǐng)pbuf結(jié)構(gòu)時(shí)會(huì)被增加一個(gè)reserve長(zhǎng)度,用于協(xié)議棧中的部分特殊操作。
在網(wǎng)絡(luò)中通信的數(shù)據(jù)報(bào)文,除了真正的數(shù)據(jù)段外,還包括了TCP/IP各層協(xié)議的報(bào)文頭。如用戶有特殊需求,要在應(yīng)用層構(gòu)建報(bào)文并直接通過網(wǎng)卡驅(qū)動(dòng)發(fā)送,則需要申請(qǐng)pbuf結(jié)構(gòu)的數(shù)據(jù)緩沖區(qū)帶有各層偏移,如程序清單 3.1所示。
程序清單 3.1 pbuf_alloc第一個(gè)參數(shù)分析
typedef enum { PBUF_TRANSPORT, /* 傳輸層報(bào)文頭偏移 */ PBUF_IP, /* IP層報(bào)文頭偏移 */ PBUF_LINK, /* 鏈路層報(bào)文頭偏移 */ PBUF_RAW_TX, /* 封裝鏈路層偏移 */ PBUF_RAW /* 無偏移 */ } pbuf_layer;
申請(qǐng)pbuf結(jié)構(gòu)需要指定pbuf類型,原因是不同類型的pbuf申請(qǐng)內(nèi)存的方式不同,如程序清單 3.2所示。
程序清單 3.2 pbuf_alloc第三個(gè)參數(shù)分析
typedef enum { PBUF_RAM, /* 內(nèi)存堆分配 */ PBUF_ROM, /* 指向ROM空間內(nèi)數(shù)據(jù) */ PBUF_REF, /* 指向RAM空間內(nèi)數(shù)據(jù) */ PBUF_POOL /* 內(nèi)存池分配 */ } pbuf_type;
PBUF_RAM類型的pbuf主要通過內(nèi)存堆分配得到,協(xié)議棧劃分了一塊空間用于申請(qǐng)PBUF_RAM類型的pbuf,劃分的空間大小通過“l(fā)ibsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_MEM_SIZE”宏配置。
PBUF_REF和PBUF_ROM類型的pbuf基本相同,前者指向ROM空間內(nèi)的某段數(shù)據(jù),而后者指向RAM空間內(nèi)的某段數(shù)據(jù)。PBUF_REF和PBUF_ROM類型的pbuf通過“l(fā)ibsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_NUM_PBUFS”宏配置在內(nèi)存池中預(yù)分配pbuf的最大數(shù)量。
PBUF_POOL類型的pbuf通過內(nèi)存池分配,這種類型的pbuf可以在極短時(shí)間內(nèi)得到分配,在網(wǎng)卡驅(qū)動(dòng)接收數(shù)據(jù)時(shí),一般采用這種方式。協(xié)議棧會(huì)在內(nèi)存池中預(yù)先分配適當(dāng)數(shù)量和大小的內(nèi)存空間,通過“l(fā)ibsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_POOL_SIZE和LW_CFG_LWIP_NUM_POOLS”宏配置。
netdev_pbuf_alloc函數(shù)申請(qǐng)PBUF_POOL類型pbuf,若申請(qǐng)的緩沖區(qū)大于PBUF_POOL池中單個(gè)pbuf緩沖區(qū)長(zhǎng)度,系統(tǒng)會(huì)分配多個(gè)固定大小的PBUF_POOL類型pbuf,并把這些pbuf鏈成一個(gè)鏈表,以滿足用戶的分配空間請(qǐng)求,如圖 3.1所示。
圖 3.1 PBUF_POOL類型pbuf申請(qǐng)流程
網(wǎng)卡驅(qū)動(dòng)收到數(shù)據(jù)后,會(huì)調(diào)用netdev_pbuf_alloc函數(shù)申請(qǐng)pbuf結(jié)構(gòu),并將數(shù)據(jù)拷貝至pbuf。當(dāng)有大量數(shù)據(jù)被網(wǎng)卡驅(qū)動(dòng)接收時(shí),可能會(huì)造成申請(qǐng)pbuf結(jié)構(gòu)失敗,原因是系統(tǒng)預(yù)分配的內(nèi)存池中的pbuf結(jié)構(gòu)已經(jīng)全部被申請(qǐng),還未被釋放??梢試L試通過“l(fā)ibsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_POOL_SIZE和LW_CFG_LWIP_NUM_POOLS”宏配置增大pbuf緩沖區(qū)大小和數(shù)量解決pbuf結(jié)構(gòu)申請(qǐng)失敗問題。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。