AliOS-Things+STM32 (五) 堆内存管理(上)

本文深入探讨了AliOS系统中的内存管理机制,详细分析了堆内存的初始化过程,包括malloc和free函数的具体实现,以及如何优化小块内存的管理。

开发过程中,写代码用得最多的就是对堆的malloc和free了, 在alios这样的小系统中,我们看下是如何处理堆内存的。

跟堆内存相关的有如下几个宏:

  • RHINO_CONFIG_MM_TLF
  • RHINO_CONFIG_MM_BLK
  • RHINO_CONFIG_MM_TLF_BLK_SIZE
  • RHINO_CONFIG_MM_DEBUG

其中RHINO_CONFIG_MM_BLK和RHINO_CONFIG_MM_TLF_BLK_SIZE涉及到小块内存管理优化, 我们下一章再研究,RHINO_CONFIG_MM_DEBUG只是调试信息,为简便起见,这章先只研究打开RHINO_CONFIG_MM_TLF宏的状态。

void aos_heap_set()
{
   
   
    g_mm_region[0].start = (uint8_t*)&Image$$RW_IRAM1$$ZI$$Limit;
    g_mm_region[0].len   =
        (g_iram1_start + g_iram1_total_size - (size_t)&Image$$RW_IRAM1$$ZI$$Limit);
}

其中Image\$\$RW_IRAM1\$\ZIZIZI$Limit为链接器导出的符号,代表ZI段的结束,也就是程序执行区的RAM结束后的地址,反过来也就是我们执行区的RAM未使用的区域的起始地址。g_iram1_start为0x20000000,g_iram1_total_size为0x00005000,分别表示ram的起始地址和长度,所以,上面代码执行完后,g_mm_region[0].start就是可用空闲区域的ram起始地址, len为可用ram的大小。

接着就到krhino_init->k_mm_init()->krhino_init_mm_head.移除RHINO_CONFIG_MM_DEBUG和RHINO_CONFIG_MM_BLK相关的代码后,krhino_init_mm_head如下:

kstat_t krhino_init_mm_head(k_mm_head **ppmmhead, void *addr, size_t len )
{
   
   
    k_mm_list_t *nextblk;
    k_mm_list_t *firstblk;
    k_mm_head   *pmmhead;
    void        *orig_addr;

    NULL_PARA_CHK(ppmmhead);
    NULL_PARA_CHK(addr);

    /* check paramters, addr and len need algin
     *  1.  the length at least need RHINO_CONFIG_MM_TLF_BLK_SIZE  for fixed size memory block
     *  2.  and also ast least have 1k for user alloced
     */
    orig_addr = addr;

    addr = (void *) MM_ALIGN_UP((size_t)addr);
    len -= (size_t)addr - (size_t)orig_addr;
    len  = MM_ALIGN_DOWN(len);

    if ( len == 0
         || len < MIN_FREE_MEMORY_SIZE + RHINO_CONFIG_MM_TLF_BLK_SIZE
         || len > MM_MAX_SIZE) {
   
   
        return RHINO_MM_POOL_SIZE_ERR;
    }

    pmmhead = (k_mm_head *)addr;

    /* Zeroing the memory head */
    memset(pmmhead, 0, sizeof(k_mm_head));

#if (RHINO_CONFIG_MM_REGION_MUTEX > 0)
    krhino_mutex_create(&pmmhead->mm_mutex, "mm_mutex");
#else
    krhino_spin_lock_init(&pmmhead->mm_lock);
#endif
	/* 1 */
    firstblk = init_mm_region((void *)((size_t)addr + MM_ALIGN_UP(sizeof(k_mm_head))),
                              MM_ALIGN_DOWN(len - sizeof(k_mm_head)));


    pmmhead->regioninfo = (k_mm_region_info_t *)firstblk->mbinfo.buffer;

    nextblk = MM_GET_NEXT_BLK(firstblk);

    *ppmmhead = pmmhead;
	/* 2 */
    /* release free blk */
    k_mm_free(pmmhead, nextblk->mbinfo.buffer);

#if (K_MM_STATISTIC > 0)
    pmmhead->free_size    = MM_GET_BUF_SIZE(nextblk);
    pmmhead->used_size    = len - MM_GET_BUF_SIZE(nextblk);
    pmmhead->maxused_size = pmmhead->used_size;
#endif

    return RHINO_SUCCESS;
}

这里面先分析/*1*/init_mm_region以及/*2*/k_mm_free

RHINO_INLINE k_mm_list_t *init_mm_region(void *regionaddr, size_t len)
{
   
   
    k_mm_list_t        *midblk, *lastblk, *firstblk;
    k_mm_region_info_t *region<
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值