Edit online

D21x 内存使用指南

5 Dec 2024
Read time: 3 minute(s)

D21x 硬件上使用 DRAM 作为 Memory 主要存储单元,其典型大小为 64M/128M。

内存布局


d21x_mem_layout

针对 DRAM Memory 资源,软件会使用以下策略来进行分配:

  • 首先把 DRAM 分成两个区域: DRAM Software RegionDRAM 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 相关参数:
Board options  --->
    Mem Options  --->
  • DRAM 总大小

    DRAM parameter  --->
        (0x4000000) DRAM Total Size  // 配置 DRAM 总大小为 64M
    
  • CMA 区域大小

    DRAM parameter  --->
        (0x2000000) CMA mem size     // 配置 DRAM 结尾 CMA 区域大小为 32M,剩余开头 32M 即为 Software 区域

调试命令

查看内存布局
在工程编译时,可以通过下列命令来查看当前工程的内存布局:
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
查看内存池的运行情况
在系统运行时,可以通过 RT-Thread 下的 free 命令来查看 heap_sysheap_cma 内存池的运行情况:
free
结果输出示例如下:
memheap           pool size  max used size available size
---------------- ---------- ------------- --------------
heap_cma         8362744    48            8362696
heap_sys         758948     50384         710780