lwip-mem_init和mem_malloc详解
lwip-mem_init和mem_malloc详解
[cpp] view plain copy <pre name="code"
class="cpp">#define MEM_ALIGNMENT 4
//对齐方式为4字节对齐#ifndef LWIP_MEM_ALIGN_SIZE #define LWIP_MEM_ALIGN_SIZE(size) (((size) +
MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) //实现待分配数据空间的内存对齐#endif #ifndef LWIP_MEM_ALIGN //地址对齐,对齐方式也为4字节对齐#define LWIP_MEM_ALIGN(addr) ((void
*)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) &
~(mem_ptr_t)(MEM_ALIGNMENT-1))) #endif /* MEM_SIZE: the size of the heap memory. If the application will send a lot of data that needs to be copied, this should be set high. */ #defi
ne MEM_SIZE (8*1024) //堆的总空间大小,此后在这个基础上划分堆,将在这个空间进行内存分配,内存块结构体和数据都是在这个空间上的
//mem为内存块的结构体,next;,prev都为内存块索引struct mem { /** index (-> ram[next]) of the next struct */
//ram为堆的首地址,相当于数组的首地址,索引基地址mem_size_t next; //next为下一个内存块的索引/** index (-> ram[next]) of the next struct */
mem_size_t prev; //prev为前一个内存块的索引/** 1: this area is used; 0: this area is unused */ u8_t used;
//标志此内存块已被分配}; static struct mem *ram_end; /** All allocated blocks will be MIN_SIZE bytes big, at least!
* MIN_SIZE can be overridden to suit your needs. Smaller values save space, * larger values could prevent too small blocks to fragment the RAM too much. */ #ifndef MIN_SIZE #define MIN_SIZE 12 //内存块大小的最小限制,不能小于12 #endif /* MIN_SIZE */ /* some
alignment macros: we define them here for better source code layout */ #define MIN_SIZE_ALIGNED
LWIP_MEM_ALIGN_SIZE(MIN_SIZE) //将MIN_SIZE
按4字节对齐,即把12按4字节对齐#define
SIZEOF_STRUCT_MEM
LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) //将mem大小按4字节对齐#define MEM_SIZE_ALIGNED
LWIP_MEM_ALIGN_SIZE(MEM_SIZE) //将堆的总空间按4字节对齐,MEM_SIZE在前面,为8*1024 //内存对齐解释看我的博文:
www.doczj/doc/017213784.html,/lg2lh/article/details/34853883 /** the heap. we need one struct mem at the end and some room for
alignment */ static u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) +
MEM_ALIGNMENT]; //实际开的堆内存空间,MEM_SIZE_ALIGNED为对齐后的数据空间为8192 //堆内存的大小为
MEM_SIZE_ALIGNED+(2*SIZEOF_STRUCT_MEM)+MEM _ALIGNMENT=8192+2*MEN结构体的大小+4 void mem_init(void) { struct mem *mem; //定义一个mem 结构体指针变量LWIP_ASSERT("Sanity check alignment", (SIZEOF_STRUCT_MEM &
(MEM_ALIGNMENT-1)) == 0); /* align the heap */
ram = LWIP_MEM_ALIGN(ram_heap); //将堆空间首地址ram_heap按4字节地址对齐/* initialize the start of the heap */ mem = (struct mem *)ram; //将堆空间ram 首地址强制转换成mem结构体类型,作为首个内存块,但这个内存块还未使用mem->next =
MEM_SIZE_ALIGNED; //把首个内存块的next指针指向了堆空间的最后一个地址(MEM_SIZE_ALIGNED为8*1024),后面实际在mem_malloc时会动态调整next索引, //从而得到实际分配内存空间即为mem->next减去该内存块mem 的地址//待分配内存块的next索引总是指向堆空间最后,好像也不一定,但是按照思路是这样的。mem->prev = 0; //初始化,因为是第一个内存块,所以前一个内存块不存
在,故初始化为0 mem->used = 0; //该内存块没有被分配,待分配状态/* initialize the end of the heap */sizeof结构体大小
ram_end = (struct mem *)&ram[MEM_SIZE_ALIGNED]; //例化一个堆空间末尾内存块,该内存块指向最后一个地址,标志结尾用的已被分配,不可再分配了
ram_end->used = 1; //该内存块已被分配
ram_end->next = MEM_SIZE_ALIGNED; //因为后续
再无内存块故,next索引指向最后,即自己
ram_end->prev = MEM_SIZE_ALIGNED; //这个我也
不知道啊mem_sem = sys_sem_new(1); /* initialize the lowest-free pointer to the start of the heap */ lfree = (struct mem *)ram; //初始化空闲对指针,此时首个内存块是空闲的MEM_STATS_AV AIL(avail,
MEM_SIZE_ALIGNED); } void *
mem_malloc(mem_size_t size) { mem_size_t ptr, ptr2; struct mem *mem, *mem2; #if
LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
u8_t local_mem_free_count = 0; #endif /*
LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ LWIP_MEM_ALLOC_DECL_PROTECT(); if (size == 0) { return NULL; } //size为0的话返回null 分配不成功/* Expand the size of the allocated memory
region so that we can adjust for alignment. */ size = LWIP_MEM_ALIGN_SIZE(size); //将待分配数据按4字节进行对齐if(size < MIN_SIZE_ALIGNED) { //如果待分配空间小于MIN_SIZE_ALIGNED(12),则返回分配空间也要为12,最小分配空间为12 /* every data block must be at least MIN_SIZE_ALIGNED long */ size = MIN_SIZE_ALIGNED; } if (size >
MEM_SIZE_ALIGNED) { //如果待分配空间大于
MEM_SIZE_ALIGNED(8*1024),超出堆空间,则返回NULL,无法分配return NULL; } /* protect the heap from concurrent access */
sys_arch_sem_wait(mem_sem, 0);
LWIP_MEM_ALLOC_PROTECT(); //未定义#if
LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
/* run as long as a mem_free disturbed mem_malloc */ do { local_mem_free_count = 0; #endif /*
LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ /* Scan through the heap searching for a free block that is big enough, * beginning with the lowest free block. */ //ptr初值=空闲内存块地址与堆内存首地址之差,如果
ptr+size小于堆空间总大小8*1024,则可实现相应大小//的内存块分配,其中ptr实际为已分配了的空间大小,size
为待分配的空间大小,两个和一定要小于总空间,才可以实现分配. //判断完成后,将ptr赋值为该内存块next所指地址for (ptr = (u8_t *)lfree - ram; ptr <
MEM_SIZE_ALIGNED - size; ptr = ((struct mem *)&ram[ptr])->next) { //将待分配的这个内存空间初始化为内存块结构体
mem = (struct mem *)&ram[ptr]; #if
LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT //未定义mem_free_count = 0;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论