FreeRTOS --(3)内存管理 heap2

本文深入解析FreeRTOS的heap2内存管理模块,详细介绍了内存大小、对齐策略、内存块管理、分配与释放机制。heap2不仅提供内存分配接口,还引入释放接口,通过链表管理和拆分内存块,有效利用内存资源。

目录

1、内存大小

2、对齐

3、内存块

3.1、数据结构

3.2、数据结构对齐

3.3、内存块 Marker

3.4、可用内存

4、分配内存

5、释放内存


 

在《FreeRTOS --(2)内存管理 heap1》知道 heap 1 的内存管理其实只是简单的实现了内存对齐的分配策略,heap 2 的实现策略相比 heap 1 稍微复杂一点,不仅仅是提供了分配内存的接口,同时也提供了释放内存的接口;

但是 heap 2 的内存分配策略中,并没有提供空闲内存的合并策略,对内存碎片没有处理;换句话来说,如果有多次的,大小各异的内存申请和释放的场景下,很可能导致很多内存碎片;

1、内存大小

和 heap 1 一样,用于内存管理的内存大小来自于一个大数组,数组的下标就是整个需要被管理的内存的大小,这个是和具体芯片所支持的 RAM 大小相关:

configTOTAL_HEAP_SIZE

被管理的内存定义为:

static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

ucHeap 就是管理的对象;

 

2、对齐

有的处理器是对内存对齐有要求的,比如 ARM-CM3 等,AAPCS规则要求堆栈保持8字节对齐。给任务分配栈时需要保证栈是8字节对齐的。所以这里 FreeRTOS 就需要涉及到对齐操作;针对 ARM-CM3 这类处理器来说,在portmacro.h 文件中,定义了对齐的字节数:

/* Hardware specifics. */
#define portBYTE_ALIGNMENT			8

而在 portable.h 中,定义了对应的 Mask(8字节对齐,那么都要是 8 的倍数,也就是二进制的 4'b1000,所以 MASK 是 4'b0111 也就是 0x07):

#if portBYTE_ALIGNMENT == 8
	#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
#endif

和 heap 1 一样,在处理对齐的时候,由于可能 ucHeap 初始的地址就没对齐,所以这里真正可以对齐分配的内存的 SIZE 就要做一些调整和妥协,由于是 8 字节对齐,所以最多妥协的大小就是 8 字节,也就是真正被管理的内存大小只有  configADJUSTED_HEAP_SIZE,这里可能造成几个字节的浪费(浪费多少,取决于ucHeap 初始地址 ),不过为了对齐,也就忽略了;

/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE	( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )

 

3、内存块

与 heap 1 不同,heap 2 可以支持分配和释放,那么管理内存的手段势必比 heap 1 复杂一些,heap 2 对内存进行分块管理,将每块内存通过一个表征该内存块的的数据结构表示,以单向链表串在一起;

3.1、数据结构

表达一个内存块的数据结构是 BlockLink_t,它的定义是:

/* Define the linked list structure.  This is used to link free blocks in order
of their size. */
typedef struct A_BLOCK_LINK
{
	struct A_BLOCK_LINK *pxNextFreeBlock;	/*<< The next free block in the list. */
	size_t xBlockSize;						/*<< The size of the free block. */
} BlockLink_t;

pxNextFreeBlock 指向下一个内存块的 BlockLink_t 结构;

xBlockSize 代表本内存块的大小;

 

3.2、数据结构对齐

当然内存块也需要对齐:

static const uint16_t heapSTRUCT_SIZE	= ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK );

heapSTRUCT_SIZE 代表了一个内存块对齐后大小(为了对齐,先加上了最大可能消耗的字节数,这里可能有一点点直接损失)

 

3.3、内存块 Marker

FreeRTOS 为内存管理,定义了两个 BlockLink_t 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值