一 LWIP内存管理LWIP的内存管理使用了2种方式:内存池memp和内存堆mem,如图1所示。
内存池的特点是预先开辟多组固定大小的内存块组织成链表,实现简单,分配和回收速度快,不会产生内存碎片,但是大小固定,并且需要预估算准确。
内存堆的本质是对一个事先定义好的内存块进行合理有效的组织和管理,主要用于任意大小的内存分配,实现较复杂,分配需要查找,回收需要合并,容易产生内存碎片,需要合理估算内存堆的总大小。
图1内存池与内存堆 1. 数据包管理数据包管理结构pbuf共有四种类型,它们的特点和使用场合如表1所示。
类别
| 分配方式
| 特点
| 使用场合
| PBUF_RAM
| 内存堆,包括pbuf和数据区
| 长度不定,分配耗时
| 应用程序和协议栈
| PBUF_POOL
| 内存池,包括pbuf和数据区
| 长度固定,分配快
| 中断服务程序
| PBUF_ROM
| 内存池,仅包括pbuf
| 所指数据位于ROM中
| 应用程序引用内存区
| PBUF_REF
| 内存池,仅包括pbuf
| 所指数据位于RAM中
| 应用程序引用内存区
|
表1 pbuf类型与特点 每一种pbuf分配内存的方式都不一样,如图2所示。
图2四种数据包管理结构 只有选择合适的pbuf类型才能发挥LWIP的最大性能,一个数据包可能是多种pbuf的组合,用链表连接起来,如图3所示。
图3 pbuf链表 2. 设置内存大小为LWIP开辟一个专用的内存堆是应该的,这样一来LWIP的mem_alloc()和mem_free()都将基于该堆内存进行分配和回收,不影响其他系统内存的使用。如图1左所示,lwipopt.h文件中宏MEM_SIZE定义了堆区的大小,对于一个负荷较重的系统堆区需要分配较大。
图4堆和PBUF_ROM内存区 LWIP使用PBUF_ROM类型的内存池来发送“只读”数据(处于ROM中或者其他进程中不可修改),宏MEMP_NUM_PBUF定义了该缓冲池的个数,如图2右所示。 在ISR(中断服务程序中)经常需要快速分配一部分内存进行数据存储,这是通过PBUF_POOL类型的缓冲区实现的。为此需要定义两个宏:PBUF_POOL_SIZE定义缓冲池的个数,PBUF_POOL_BUFSIZE定义单个缓冲区的大小,如图5所示。 图5 PBUF_POOL内存区 |