D21x 内存使用指南
D21x 硬件上使用 DRAM 作为 Memory 主要存储单元,其典型大小为 64M/128M。
内存布局
针对 DRAM Memory 资源,软件会使用以下策略来进行分配:
-
首先把 DRAM 分成两个区域:
DRAM Software Region
和DRAM CMA Region
。CMA Region 提供给多媒体模块 MPP 专用,Software Region 提供给系统其他模块使用,主要目的是把 MPP 的动态内存池 (heap_cma) 和 系统动态内存池 (heap_sys) 进行分离,避免 MPP 的内存池碎片化。因为 MPP 的内存分配基本都是大块内存,而系统各模块的内存分配是各种尺寸大小都有,如果共享一个内存池容易造成 MPP 大块内存分配失败。 -
接着会把每一个
Region
进一步划分成静态分配Static
和 动态分配Heap
子区域。静态分配的区域在编译链接后地址已经确定,动态分配区域就是 Heap 内存池运行时地址才会确定。
内存使用
综合上述策略,DRAM 空间被软件划分成四块区域:
-
DRAM SW Static
系统静态分配区域。.text .rodata .data .bss
默认会存放到这个区域,即普通的函数定义和全局变量定义。 -
DRAM SW Heap
系统动态分配区域。即heap_sys
内存池,可以通过以下函数从该内存池分配内存。malloc(size); aicos_malloc(MEM_DEFAULT, size); // MEM_DEFAULT = 0
-
DRAM CMA Static
CMA 静态分配区域。函数定义和全局变量定义可以通过加上CMA_DATA_DEFINE
宏声明链接到这个区域: (这个区域是可选的,通常情况下没有配置。)// 函数定义: void CMA_DATA_DEFINE test_func(void); // CMA_DATA_DEFINE = DRAM_CMA_DATA_DEFINE // 全局变量定义: CMA_DATA_DEFINE int a = 1;
-
DRAM CMA Heap
CMA 动态分配区域。即heap_cma
内存池,可以通过以下函数从该内存池分配内存。aicos_malloc(MEM_CMA, size); // MEM_CMA = MEM_DRAM_CMA
参数配置
可以通过 scons --menuconfig
命令进入 menuconfig 配置界面,配置 Meomry 相关参数:
-
DRAM 总大小
Board options ---> Mem Options ---> DRAM parameter ---> (0x4000000) DRAM Total Size // 配置 DRAM 总大小为 64M
-
CMA 区域大小
Board options ---> Mem Options ---> DRAM parameter ---> (0x2000000) CMA mem size // 配置 DRAM 结尾 CMA 区域大小为 32M,剩余开头 32M 即为 Software 区域
调试命令
free
命令来查看
heap_sys
和 heap_cma
内存池的运行情况:$ scons --list-mem
scons: Reading SConscript files ...
output/d21x_demo88-nand_rt-thread_helloworld/images/d21x.elf Memory layout:
Region Start End Length
dram 0x40000000 - 0x44000000 0x04000000
└─ dram_sw 0x40000000 - 0x42000000 0x02000000
└─ dram_sw_static 0x40000000 - 0x401cb970 0x001cb970
└─ .text 0x40000000 - 0x400cda80 0x000cda80
└─ .rodata 0x400cda80 - 0x4016ea20 0x000a0fa0
└─ .bss 0x40172000 - 0x401cb970 0x00059970
└─ dram_sw_heap 0x401cb970 - 0x42000000 0x01e34690
└─ .heap_sys 0x401cb970 - 0x42000000 0x01e34690
└─ dram_cma 0x42000000 - 0x44000000 0x02000000
└─ dram_cma_heap 0x42000000 - 0x44000000 0x02000000
└─ .heap_cma 0x42000000 - 0x44000000 0x02000000