目录
一、内存管理
内存管理模块管理系统的内存资源,它是操作系统的核心模块之一,主要包括内存的初始化、分配以及释放。
在系统运行过程中,内存管理模块通过对内存的申请/释放来管理用户和 OS 对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统的内存碎片问题。
LiteOS-M 的内存管理分为静态内存管理和动态内存管理,提供内存初始化、分配、释放等功能。
动态内存:在动态内存池中分配用户指定大小的内存块。
- 优点:按需分配。
- 缺点:内存池中可能出现碎片。
静态内存:在静态内存池中分配用户初始化时预设(固定)大小的内存块。
- 优点:分配和释放效率高,静态内存池中无碎片。
- 缺点:只能申请到初始化预设大小的内存块,不能按需申请。
二、静态内存
2.1、静态内存运行机制
静态内存实质上是一个静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更。
静态内存池由一个控制块 LOS_MEMBOX_INFO 和若干相同大小的内存块LOS_MEMBOX_NODE 构成。控制块位于内存池头部,用于内存块管理,包含内存块大小uwBlkSize,内存块数量 uwBlkNum,已分配使用的内存块数量 uwBlkCnt 和空闲内存块链表
stFreeList。内存块的申请和释放以块大小为粒度,每个内存块包含指向下一个内存块的指针pstNext。
2.2、静态内存开发流程
1、执行make menuconfig命令,进入Kernel ---> Memory Management菜单,完成静态内存管理模块的配置。
配置项 | 含义 | 取值范围 | 默认值 | 依赖 |
---|---|---|---|---|
LOSCFG_KERNEL_MEMBOX | 使能membox内存管理 | YES/NO | YES | 无 |
LOSCFG_KERNEL_MEMBOX_STATIC | 选择静态内存方式实现membox | YES/NO | YES | LOSCFG_KERNEL_MEMBOX |
LOSCFG_KERNEL_MEMBOX_DYNAMIC | 选择动态内存方式实现membox | YES/NO | NO | LOSCFG_KERNEL_MEMBOX |
2、规划一片内存区域作为静态内存池。
3、调用 LOS_MemboxInit 初始化静态内存池。初始化会将入参指定的内存区域分割为 N 块(N 值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。
4、调用 LOS_MemboxAlloc 接口分配静态内存。系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。
5、调用 LOS_MemboxClr 接口。将入参地址对应的内存块清零。
6、调用 LOS_MemboxFree 接口。将该内存块加入空闲链表。
2.3、静态内存接口
功能类别 | 接口函数 | 描述 |
---|---|---|
初始化静态内存池 | LOS_MemboxInit | 初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小 |
清除静态内存块内容 | LOS_MemboxClr | 清零指定静态内存块的内容 |
申请、释放静态内存 | LOS_MemboxAlloc | 从指定的静态内存池中申请一块静态内存块 |
LOS_MemboxFree | 释放指定的一块静态内存块 | |
获取、打印静态内存池信息 | LOS_MemboxStatisticsGet | 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小 |
LOS_ShowBox | 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址 |
2.4、实例
c
#define BOXSIZE 10 //内存块大小
#define BLKNUM 3 //内存块数量
static UINT32 BoxMem[BOXSIZE*BLKNUM]; //定义一个数组作为静态内存池空间
UINT32 ret = LOS_OK;
/* 初始化内存池 */
ret = LOS_MemboxInit(&BoxMem[0], /* 内存池地址 */
BOXSIZE, /* 内存块大小 */
BLKNUM); /* 内存块数量 */
if (ret != LOS_OK)
{
printf("内存池初始化失败\n");
} else
{
printf("内存池初始化成功!\n");
}
/* 获取内存块空间 */
UINT32 *p_Num = NULL; //指向读写内存池地址的指针
p_Num = (UINT32*)LOS_MemboxAlloc(BoxMem); /* 向已经初始化的内存池分配内存 */
if (NULL == p_Num)
{
printf("分配内存失败!\n");
} else
{
printf("分配内存成功!\n");
}
/* 清除内存块数据 */
LOS_MemboxClr(BoxMem, p_Num); /* 清除在p_Num地址的内容 */
/* 释放内存块使用空间 */
ret = LOS_MemboxFree(BoxMem, p_Num); //释放内存
if (LOS_OK == ret)
{
printf("内存释放成功!\n");//内存释放成功!
} else
{
printf("内存释放失败!\n");//内存释放失败!
}