🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
PBUF\_POOL类型的pbuf与PBUF\_RAM类型的pbuf都是差不多的,其pbuf结构体与数据缓冲区也是存在于连续的内存块中,但它的空间是通过内存池分配的,这种类型的pbuf可以在极短的时间内分配得到,因为这是内存池分配策略的优势,在网卡接收数据的时候,LwIP一般就使用这种类型的pbuf来存储接收到的数据,申请PBUF\_POOL类型时,协议栈会在内存池中分配适当的内存池个数以满足需要的数据区域大小。 除此之外,在系统进行内存池初始化的时候,还好初始化两个与pbuf相关的内存池,分别为MEMP\_PBUF、MEMP\_ PBUF\_POOL,具体见: ``` LWIP_MEMPOOL(PBUF, MEMP_NUM_PBUF, sizeof(struct pbuf),"PBUF_REF/ROM") LWIP_PBUF_MEMPOOL(PBUF_POOL,PBUF_POOL_SIZE,PBUF_POOL_BUFSIZE,"PBUF_POOL") ``` MEMP\_PBUF内存池是专门用于存放pbuf数据结构的内存池,主要用于PBUF\_ROM、PBUF\_REF类型的pbuf,其大小为sizeof(struct pbuf),内存块的数量为MEMP\_NUM\_PBUF;而MEMP\_PBUF\_POOL则包含pbuf结构与数据区域,也就是PBUF\_POOL类型的pbuf,内存块的大小为PBUF\_POOL\_BUFSIZE,其值由用户自己定义,默认为590(536+40+0+14)字节,当然也可以由我们定义TCP\_MSS的大小改变该宏定义,我们将宏定义TCP\_MSS的值定义为1460,这样子我们PBUF\_POOL类型的pbuf的内存池大小为1514(1460+40+0+14),内存块的个数为PBUF\_POOL\_SIZE。 如果按照默认的内存大小,对于有些很大的以太网数据包,可能就需要多个pbuf才能将这些数据存放下来,这就需要申请多个pbuf,因为是PBUF\_POOL类型的pbuf,所以申请内存空间只需要调用memp\_malloc()函数进行申请即可。然后再将这些pbuf通过链表的形式连接起组成pbuf链表上,以保证用户的空间需求,分配与连接成功的pbuf示意图具体见: ![](https://box.kancloud.cn/654c673d8dfd69d0989ec6a03d56cd96_965x568.png) 注意了,pbuf链表中第一个pbuf是有layer字段的,用于存放协议头部,而在它后面的pbuf则是没有该字段,由于PBUF\_POOL类型pbuf都是以固定长度分配的,在最后一个pbuf中,可能会被浪费大量的空间,并且,每个pbuf的tot\_len字段记录的就是自身及其后面的pbuf总大小。