FreeRtos内存管理

FreeRtos内存管理

标签(空格分隔): FreeRtos内存


FreeRtos的内存管理接口,都遵循POSIX接口标准.可移植操作系统接口(英语:Portable Operating System Interface,缩写为POSIX),是IEEE为要在各种UNIX操作系统上运行软件,而定义API的一系列互相关联的标准的总称,其正式称呼为IEEE Std 1003,而国际标准名称为ISO/IEC 9945。该标准要求malloc分配的内存地址必须是对齐的地址.

FreeRtos 内存管理共4种方式,分别对应源码文件中的heap_1.c,heap_2.c,heap_3.c,heap_4.c.

FreeRtos内存管理方式 优点 缺点 备注
heap_1.c 只能malloc,不能free
heap_2.c 1.malloc速度快
1.容易出现内存碎片,如果不停的malloc小内存块,大内存块会被拆分为小的内存块,但是free的时候,并不会将小内存块合并,就会出现malloc大内存,无法分配成功的问题
2.free时,无法对该节点检查.free其他内存,或者free两次,无法检查
Free-list链表的节点是按照节点内存块大小排序的
heap_3.c 采用系统默认的malloc和free,只是添加了线程保护
heap_4.c 1.内存合并功能,不会出现内存碎片
2.添加节点保护,malloc时会在内存快上设定标志位,避免多次free和free其他内存引起的crash
1.malloc的时候有大小限制,因为malloc标志位是放在size的最高bit
2.malloc的时间比heap_2.c要慢
Free-list链表的节点是按照节点地址排序的,目的是方便内存合并

1 heap_1.c源码分析

这种方式比较简单,只支持用户malloc内存,不支持用户free.heap_1的内存池是用户自定义了一块数组,为了保证地址对齐,将该数组放在了结构体的第2个元素.

#全局数组ucHeap作为heap的内存词,这里为了保证heap起始地址是4字节对齐的,将ucHeap放在结构体里面保证地址对齐.
extern struct xRTOS_HEAP
{
    unsigned long ulDummy;
    unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
} xHeap;
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL; 

    /* Ensure that blocks are always aligned to the required number of bytes. */
    #if portBYTE_ALIGNMENT != 1
        if( xWantedSize & portBYTE_ALIGNMENT_MASK )
        {
            /* Byte alignment required. */
            #保证malloc的长度是4字节对齐的,那下一次malloc的地址还是4字节对齐的
            xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
        }
    #endif

    vTaskSuspendAll();
    {
        /* Check there is enough room left for the allocation. */
        if( ( ( xNextFreeByte + xWantedSize ) < configTOTAL_HEAP_SIZE ) &&
            ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
        {
            /* Return the next free byte then increment the index past this
            block. */
            pvReturn = &( xHeap.ucHeap[ xNextFreeByte ] );
            xNextFreeByte += xWantedSize;           
        }   
    }
    xTaskResumeAll();


    return pvReturn;
}

2 heap_2.c源码分析

heap_2的内存池也是一块用户自定义的静态数组,与heap_1的区别是,这块数组的初始化地址可能是非4字节对齐的.因此初始化的时候会取4字节对齐的地址开始作为整个内存池使用.
heap_2的核心思想是将空闲的内存,放到Free-List链表里面管理.Free-List链表里面的节点是按照该节点内存块大小排序存储的.每次malloc的时候,会从Free-List链表里面取出来可以满足malloc大小的节点使用,同时在malloc的时候,会对较大的节点进行拆分,将空闲区域按照区域大小排序插入到Free-List的列表里面.用户调用Free的时候,也是将某个节点插入到Free-List链表里面.

static void prvHeapInit( void )
{
BlockLink_t *pxFirstFreeBlock;
uint8_t *pucAlignedHeap;

    /* Ensure the heap starts on a correctly aligned boundary. */
    pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGN
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值