内存管理
在RT-Thread中分为动态内存管理和静态内存管理。静态的又称为内存池管理,动态的称为内存堆管理。
内存堆:
官方提供了三种管理方式。
- 小内存管理。申请时在一块大的、连续的内存中按需求分割出相匹配的小内存块;释放时,归还给堆管理系统。每个内存块都包含一个管理用的数据头,通过双向链表来管理使用块和空闲块。
- slab 管理算法。TODO!
- memheap 管理算法。适用于系统含有多个地址可不连续的内存堆。
内存池:
内存池在创建时先向系统申请一大块内存,然后分成同样大小的多个小内存块,小内存块直接通过链表连接起来(此链表也称为空闲链表)。每次分配的时候,从空闲链表中取出链头上第一个内存块,提供给申请者。
小内存管理算法实现
三个核心函数
- void rt_system_heap_init(void *begin_addr, void *end_addr);
- void *rt_malloc(rt_size_t size);
- void rt_free(void *rmem);
rt_system_heap_init 初始化堆
void rt_system_heap_init(void *begin_addr, void *end_addr)
{
struct heap_mem *mem;
rt_ubase_t begin_align = RT_ALIGN((rt_ubase_t)begin_addr, RT_ALIGN_SIZE);
rt_ubase_t end_align = RT_ALIGN_DOWN((rt_ubase_t)end_addr, RT_ALIGN_SIZE);
if((end_align > (2 * SIZEOF_STRUCT_MEM)) &&
((end_align - 2 * SIZEOF_STRUCT_MEM) >= begin_align)){
// 最少要存两个heap_mem
mem_size_aligned = end_align - begin_align - 2 * SIZEOF_STRUCT_MEM;
}else{
printf("mem init, error begin address 0x%x, and end address 0x%x\n",
(rt_uint32_t)begin_addr, (rt_uint32_t)end_addr);
return;
}
heap_ptr = (rt_uint8_t *)begin_align;
mem = (struct heap_mem *)heap_ptr;
mem->magic = HEAP_MAGIC;
mem->used = 0