关于lwip中pbuf_alloc()内存申请函数
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()内存申请函数相关推荐
- Linux 基础知识(2)---Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别
Linux内核空间内存申请函数kmalloc.kzalloc.vmalloc的区别 kzalloc与kmalloc区别 这个函数就是原来的两个函数的整合 , 即原来我们每次申请内存的时候都会这么 ...
- Linux内核空间内存申请函数kmalloc、kzalloc、vmalloc的区别
Table of Contents kmalloc() kzalloc() vmalloc() 总结 内核中的内存申请:kmalloc.vmalloc.kzalloc.kcalloc.get_free ...
- linux 内核申请内存大小,linux内核常用的内存申请函数
在读驱动程序时,常遇到内存申请函数.驱动程序属于内核空间,和用户空间用到的内存申请函数不同. 内核空间最常用到的内存申请函数为kmalloc()和kzalloc(). kmalloc()是申请一段内存 ...
- 替换libc中的内存分配函数
2019独角兽企业重金招聘Python工程师标准>>> 摘要: 本文介绍如何替换glibc中的内存分配函数为自定义的内存分配函数的方法,可以方便调试内存分配,和查找内存管理错误而产生 ...
- C 中的内存操作函数-memcpy 等(to be continued)
文章目录 C中的内存操作函数 1.memcpy() 1.1 函数介绍 1.2 示例代码 1.3 Reference C中的内存操作函数 1.memcpy() 1.1 函数介绍 void *memcpy ...
- 内核中的内存申请:kmalloc、vmalloc、kzalloc、kcalloc、get_free_pages【转】
转自:http://www.cnblogs.com/yfz0/p/5829443.html 在内核模块中申请分配内存需要使用内核中的专用API:kmalloc.vmalloc.kzalloc.kcal ...
- linux 内核 内存申请函数 kmalloc、kzalloc、vmalloc 区别
我们都知道在用户空间动态申请内存用的函数是 malloc(),这个函数在各种操作系统上的使用是一致的,对应的用户空间内存释放函数是 free().注意:动态申请的内存使用完后必须要释放,否则会造成内存 ...
- 内核中的内存申请:kmalloc、vmalloc、kzalloc、get_free_pages 之间的区别
kmalloc vmalloc kzalloc get_free_page()是内核空间申请内存空间函数 malloc是用户空间申请内存函数 一 ,kmalloc() 与 kfree() ...
- Linux内核中常见内存分配函数
1. 原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...
最新文章
- img 服务器上的图片不显示图片,img显示服务器图片不显示
- Linux学习总结(3)——Linux实用工具
- MyEclipse10 Tomcat7 JDK1.7 配置
- 使用will和would来提出请求_42
- 华为云HCIE认证有多难?考试内容是什么?
- 简书的css排版,浅谈前端(WEB)排版
- NCURSES程序设计之魔数方阵
- 时域OCT(TD-OCT) 我的理解
- oracle使用decode实现竖表转横表 (列转行)
- excel输入公式不计算结果
- 多元函数的向量表示_多元高斯分布完全解析
- 匿名突破网络限制 (Tor工作原理分析)
- PHP中magic_quotes_gpc和magic_quotes_runtime的区别、作用和用法
- ‘SHIT’上最全有限状态机设计研究(一)-状态机介绍
- 国家名称映射和省市名称映射
- (C语言)栈应用简易计算器实现
- Simulink库大全
- 华为mpls实验 rip ospf sham-link
- python 什么值得买 签到_第一个实用python程序——自动填写工作日志、签到
- labview can通讯上位机,调用周立功库文件
热门文章
- Mozilla工程师观点:开源不赚钱,因为它不是为赚钱而设计的
- 【287】◀▶ arcpy 常用类说明
- DLT(Diagnostic Log and Trace)嵌入式系统程序运行记录
- 【转】Win8/8.1/Win7小技巧:揪出C盘空间占用的真凶
- 深入Java核心 Java内存分配原理精讲(3)
- URAL 1036 Lucky Tickets
- labview当前vi路径_对于LabVIEW程序为什么生成EXE后,涉及到路径的输出不正确了?...
- spring-security学习笔记--配置文件
- XML Schema全接触 (这里主要介绍W3C的Schema标准语法)
- java执行命令无返回_java运行cmd命令并获取返回信息的问题!!怎么不行了?