开发过程中,写代码用得最多的就是对堆的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<

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





