LiteOS-M内存特性-非连续性内存 原创
一些芯片片内RAM大小无法满足要求,需要使用片外物理内存进行扩充。对于这样的多段非连续性内存,需要内存管理模块统一管理,应用使用内存接口时不需要关注内存分配属于哪块物理内存。OpenHarmony LiteOS-M内核支持多段非连续性内存区域,把多个非连续性内存逻辑上合一,用户不感知底层的多段非连续性内存区域。多段非连续性内存如下图所示:
OpenHarmony LiteOS-M内核内存模块在支持非连续性内存时,把不连续的内存区域作为空闲内存结点插入到空闲内存节点链表,把不同内存区域间的不连续部分标记为虚拟的已使用内存节点,从逻辑上把多个非连续性内存区域实现为一个统一的内存池。下面通过示意图说明下多段非连续性内存的运行机制:
- 把多段非连续性内存区域的第一块内存区域通过调用LOS_MemInit接口进行初始化。
- 获取下一个内存区域的开始地址和长度,计算该内存区域和上一块内存区域的间隔大小gapSize。
- 把内存区域间隔部分视为虚拟的已使用节点,使用上一个内存区域的尾节点,设置其大小为gapSize+ OS_MEM_NODE_HEAD_SIZE。
- 把当前内存区域划分为一个空闲内存节点和一个尾节点,把空闲内存节点插入到空闲链表,并设置各个节点的前后链接关系。
- 如果有更多的非连续内存区域,重复上述步骤2-4。
当没有开启宏LOSCFG_MEM_MUL_REGIONS或者宏设置为0时,不支持多段非连续性内存区域,相关代码不使能。当宏 LOSCFG_MEM_MUL_REGIONS=1时,支持多段非连续性内存区域,相关代码使能。开发步骤如下:
开发者根据使用的多段内存区域实际情况,配置多段非连续性内存区域。
调用接口UINT32 LOS_MemRegionsAdd(VOID *pool, const LosMemRegion * const memRegions, UINT32 memRegionCount)实现多段非连续性内存逻辑上合并为一个统一的内存池。
按统一的内存池,正常调用内存接口实现业务操作。
对于多段非连续性内存区域,可以在链接脚本中进行配置。下面的示例配置片段仅用于演示:
. = ALIGN(4);
.memRegion1 :
{
__memory1_start = .;
. = . + 0x10000; /* memory region length */
__memory1_end = .;
} >RAM
......
. = ALIGN(4);
.memRegion2 :
{
__memory2_start = .;
. = . + 0x1000; /* memory region length */
__memory2_end = .;
} >RAM
在开发者应该代码中,可以调用接口UINT32 LOS_MemRegionsAdd(VOID *pool, const LosMemRegion * const memRegions, UINT32 memRegionCount)实现多段非连续性内存逻辑上合并为一个统一的内存池。示例代码如下:
#include "los_memory.h"
#if (LOSCFG_MEM_MUL_REGIONS == 1)
extern CHAR __memory1_start;
extern CHAR __memory2_start;
// 使用LosMemRegion数组配置多段非连续性内存区域
LosMemRegion memRegions[] =
{
{ (UINT8 *)&__memory1_start, 0x10000 },
{ (UINT8 *)&__memory2_start, 0x1000 }
};
......
// 逻辑上合并多段内存区域为一个统一的内存池
ret = LOS_MemRegionsAdd(NULL, memRegions, sizeof(memRegions) / sizeof(memRegions[0]));
if (ret != LOS_OK) {
return ret;
}
#endif