日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于lwip中pbuf_alloc()内存申请函数

發布時間:2023/12/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于lwip中pbuf_alloc()内存申请函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. PBUF_RAM一次性分配size大小的連續內存
2. RBUF_ROM只需要分配小小的管理pbuf的控制管理內存
3. PBUF_ROOL分配一個鏈表,鏈表上每個元素所管理的內存最大不超過PBUF_POOL_BUFSIZE,它更像linux
?? 中的kmem_alloc內存高速緩存機制,所以它也更適合在網卡驅動irq中斷中為剛剛到來的網絡數據包申請存儲空間
/*-----------------------------------------------------------------------------------*/
/* pbuf_alloc():
?*
?* Allocates a pbuf at protocol layer l. The actual memory allocated
?* for the pbuf is determined by the layer at which the pbuf is
?* allocated and the requested size (from the size parameter). The
?* flag parameter decides how and where the pbuf should be allocated
?* as follows:
?*?
?* * PBUF_RAM: buffer memory for pbuf is allocated as one large
?*???????????? chunk. This includes protocol headers as well.?
?* * RBUF_ROM: no buffer memory is allocated for the pbuf, even for
?*???????????? protocol headers. Additional headers must be prepended
?*???????????? by allocating another pbuf and chain in to the front of
?*???????????? the ROM pbuf.?? ?????? ?
?* * PBUF_ROOL: the pbuf is allocated as a pbuf chain, with pbufs from
?*????????????? the pbuf pool that is allocated during pbuf_init().
?*/
/*-----------------------------------------------------------------------------------*/
struct pbuf *
pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag)
{
? struct pbuf *p, *q, *r;
? u16_t offset;
? s32_t rsize;

? offset = 0;
? switch(l) {
? case PBUF_TRANSPORT:? // 如果為傳輸層申請pbuf,那么有效數據的偏移位置為PBUF_TRANSPORT_HLEN[luther.gliethttp]
??? offset += PBUF_TRANSPORT_HLEN;
??? /* FALLTHROUGH */
? case PBUF_IP:???????? // 如果為ip層申請pbuf,那么有效數據的偏移位置為PBUF_IP_HLEN+PBUF_LINK_HLEN
??? offset += PBUF_IP_HLEN;
??? offset += PBUF_LINK_HLEN;
??? /* FALLTHROUGH */
? case PBUF_LINK:?????? // 如果是鏈路層申請pbuf內存,那么數據偏移位置就是0
??? break;
? case PBUF_RAW:
??? break;
? default:
??? ASSERT("pbuf_alloc: bad pbuf layer", 0);
??? return NULL;
? }

? switch(flag) {
? case PBUF_POOL:
??? /* Allocate head of pbuf chain into p. */
??? p = pbuf_pool_alloc(); // 為PBUF_POOL類型,那么需要多申請pbuf的head控制頭部所需內存[luther.gliethttp]
??? if(p == NULL) {
#ifdef PBUF_STATS
????? ++stats.pbuf.err;
#endif /* PBUF_STATS */
????? return NULL;
??? }
??? p->next = NULL;
?? ?
??? /* Set the payload pointer so that it points offset bytes into
?????? pbuf data memory. */
??? p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset))); // 以offset為基準,登記有效數據存儲的起始偏移位置到p->payload[luther.gliethttp]

??? /* The total length of the pbuf is the requested size. */
??? p->tot_len = size; // pbuf鏈表上有效數據總大小

??? /* Set the length of the first pbuf is the chain. */
??? // pbuf鏈表上每個元素所能存儲的最大數據為PBUF_POOL_BUFSIZE,如果超過該值,那么就會
??? // 使用鏈表方式,鏈接其很多個pbuf,直到申請的size數據全部能夠正常存儲為止[luther.gliethttp]
??? p->len = size > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: size;

??? p->flags = PBUF_FLAG_POOL;
????
??? /* Allocate the tail of the pbuf chain. */
??? r = p;
??? rsize = size - p->len; // 第1個pbuf所能存儲數據大小為p->len,這里計算還需要多少存儲空間存儲剩下的數據.
??? while(rsize > 0) {???? // 構成數據緩存鏈表,每個鏈表元素所能存儲的最大數據量為PBUF_POOL_BUFSIZE個字節[luther.gliethttp]
????? q = pbuf_pool_alloc();
????? if(q == NULL) {
??? DEBUGF(PBUF_DEBUG, ("pbuf_alloc: Out of pbufs in pool,\n"));
#ifdef PBUF_STATS
??????? ++stats.pbuf.err;
#endif /* PBUF_STATS */
??????? pbuf_pool_free(p);
??????? return NULL;
????? }
????? q->next = NULL;
????? r->next = q;
????? q->len = rsize > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rsize;
????? q->flags = PBUF_FLAG_POOL;
????? q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
????? r = q;
????? q->ref = 1;
????? q = q->next;
????? rsize -= PBUF_POOL_BUFSIZE;
??? }
??? r->next = NULL;

??? ASSERT("pbuf_alloc: pbuf->payload properly aligned",
??? ?? ((u32_t)p->payload % MEM_ALIGNMENT) == 0);
??? break;
? case PBUF_RAM:
??? /* If pbuf is to be allocated in RAM, allocate memory for it. */
// PBUF_RAM類型內存,那么一次性申請size大小的連續內存
??? p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + size + offset));
??? if(p == NULL) {
????? return NULL;
??? }
??? /* Set up internal structure of the pbuf. */
??? p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));
??? p->len = p->tot_len = size;
??? p->next = NULL;
??? p->flags = PBUF_FLAG_RAM;

??? ASSERT("pbuf_alloc: pbuf->payload properly aligned",
??? ?? ((u32_t)p->payload % MEM_ALIGNMENT) == 0);
??? break;
? case PBUF_ROM:
??? /* If the pbuf should point to ROM, we only need to allocate
?????? memory for the pbuf structure. */
// PBUF_ROM類型內存,那么只需要申請pbufs頭部控制結構體所需內存即可[luther.gliethttp]
??? p = memp_mallocp(MEMP_PBUF);
??? if(p == NULL) {
????? return NULL;
??? }
??? p->payload = NULL;
??? p->len = p->tot_len = size;
??? p->next = NULL;
??? p->flags = PBUF_FLAG_ROM;
??? break;
? default:
??? ASSERT("pbuf_alloc: erroneous flag", 0);
??? return NULL;
? }
? p->ref = 1;
? return p;
}?

總結

以上是生活随笔為你收集整理的关于lwip中pbuf_alloc()内存申请函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。