Edit online

D13x 内存使用指南

Read time: 8 minute(s)
D13x 可使用的内存资源的种类比较多,包括 SRAM、PSRAM 和 TCM 等。本节列举了以下典型场景来阐述参数配置和使用方法:

关于其它组合场景,用户可以参考本节内容灵活配置。

Edit online

SRAM + PSRAM

Read time: 8 minute(s)

作为一种典型的内存配置使用场景,SRAM + PSRAM 配置有如下特点:
  • SRAM_S0 速度较快但是容量较小,提供给软件系统使用。
  • PSRAM 速度略慢但是容量较大,提供给多媒体外设模块 DE/GE/VE 作为缓存使用。
  • 外设模块的 DMA 直接存取内存。

内存布局和使用策略


d13x_mem_layout1

注:

为了减少总线冲突,DE/ GE/ VE 硬件上已被限制不能访问 SRAM_S0 区域的内存。

如图所示,软件会使用以下策略来分配 Hardware Memory 资源:

  • 将 SRAM 的 SRAM_S0 Region 区域提供给系统软件使用。

  • 将 PSRAM 分成两个区域:
    • PSRAM Software Region:在 SRAM 不够系统软件用的情况下补充划分一部分 PSRAM 给软件使用。
    • PSRAM CMA Region:专供多媒体模块 MPP 使用

    上述区域划分可将 MPP 的动态内存池 (heap_cma) 和系统动态内存池 (heap_sys) 分离,避免 MPP 的内存池碎片化。MPP 的内存分配基本是大块内存,而系统各模块的内存分配是各种尺寸大小都有,如果共享一个内存池容易造成 MPP 大块内存分配失败。

  • 将每个 Region 进一步划分成以下子区域:
    • 静态分配 Static:编译链接后可确认地址。
    • 动态分配 Heap:Heap 内存池运行时确定地址。
最终 SRAM_S0 空间被软件划分成两块区域,PSRAM 空间会被划分成四块区域:
  • SRAM_S0 SW Static:系统静态分配区域。

    默认存放 .text.rodata.data.bss 参数,即普通的函数定义和全局变量定义。

  • SRAM_S0 SW Heap:系统动态分配区域,即 heap_sys 内存池。

    通过以下函数可以从该内存池分配内存。
    malloc(size);
    aicos_malloc(MEM_DEFAULT, size);        // MEM_DEFAULT = 0
  • PSRAM SW Static:系统静态分配区域,属于可选区域,通常情况下未配置。

    通过加上 PSRAM_SW_DATA_DEFINE 宏声明可以将函数定义和全局变量定义链接到本区域:
    // 函数定义:
    void PSRAM_SW_DATA_DEFINE test_func(void);
    
    // 全局变量定义:
    PSRAM_SW_DATA_DEFINE int a = 1;
  • PSRAM SW Heap:系统动态分配区域,即 heap_psram_sw 内存池,属于可选区域,通常情况下没有配置。

    通过以下函数可以从该内存池分配内存。
    aicos_malloc(MEM_PSRAM_SW, size);
  • PSRAM CMA Static:CMA 静态分配区域。
    • 在 SRAM_S0 空间不够用时,通过 menuconfig 配置菜单将 .text.rodata.data.bss 放置到 PSRAM 中,可以链接到本区域。
    • 通过加上 CMA_DATA_DEFINE 宏声明,可以将函数定义和全局变量定义链接到本区域。
      // 函数定义:
      void CMA_DATA_DEFINE test_func(void);   // CMA_DATA_DEFINE = PSRAM_CMA_DATA_DEFINE
      
      // 全局变量定义:
      CMA_DATA_DEFINE int a = 1;
  • PSRAM CMA Heap:CMA 动态分配区域,即 heap_cma 内存池。

    通过以下函数可以从该内存池分配内存。
    aicos_malloc(MEM_CMA, size);        // MEM_CMA = MEM_PSRAM_CMA

参数配置

通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置下列 Meomry 相关参数:
Board options  --->
    Mem Options  --->
  • SRAM_S0 总大小

    SRAM parameter  --->
        (0x100000) SRAM Total Size  // 配置 SRAM 总大小为 1M
        SRAM_S1 Size (0K)           // 配置 SRAM_S1 大小为 0,即所有空间分配给 SRAM_S0
  • PSRAM 总大小

    PSRAM parameter  --->
        (0x800000) PSRAM size       // 配置 PSRAM 总大小为 8M
  • CMA 区域大小

    PSRAM parameter  --->
        (0x0) Software size in PSRAM // 配置 PSRAM 开头 Software 区域大小为 0,剩余结尾 CMA 区域大小即为 8M
  • 可将 .text.rodata.data.bss 区域配置到 SRAM_S0/PSRAM 中:

    ELF Sections memory locatio  --->
        Section .text (SRAM_S0)  --->
        Section .rodata (SRAM_S0)  --->
        Section .data (SRAM_S0)  --->
        Section .bss (PSRAM)  --->
            ( ) SRAM_S0
            (X) PSRAM      // 在 SRAM 空间不足的情况下,选择把几部分数据存放到 PSRAM 当中

调试命令

查看内存布局
在工程编译时,可以通过下列命令来查看当前工程的内存布局:
scons --list-mem
输出结果示例如下所示:
scons: Reading SConscript files ...
output/d13x_demo88-nor_rt-thread_helloworld/images/d13x.elf Memory layout:

        Region                               Start       End        Length
sram_s0                                 0x30040000 - 0x30140000  0x00100000
  └─ sram_s0_static                     0x30040000 - 0x300ec1f8  0x000ac1f8
            └─ .text                    0x30040000 - 0x300ca3c0  0x0008a3c0
            └─ .rodata                  0x300ca430 - 0x300ea7b0  0x00020380
            └─ .data                    0x300ea7c0 - 0x300ec1f8  0x00001a38
  └─ sram_s0_heap                       0x300ec1f8 - 0x30140000  0x00053e08
            └─ .heap_sys                0x300ec1f8 - 0x30140000  0x00053e08
psram                                   0x40000000 - 0x40800000  0x00800000
  └─ psram_cma                          0x40000000 - 0x40800000  0x00800000
       └─ psram_cma_static              0x40000000 - 0x40010348  0x00010348
            └─ .bss                     0x40000000 - 0x40010348  0x00010348
       └─ psram_cma_heap                0x40010348 - 0x40800000  0x007efcb8
            └─ .heap_cma                0x40010348 - 0x40800000  0x007efcb8
查看内存池的运行情况
在系统运行时,可以通过 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
Edit online

TCM + SRAM + PSRAM

Read time: 8 minute(s)

D13x 支持把部分 SRAM 挂载成 Tightly Coupled Memory (TCM)。TCM 的主要优势在于其内存区域由 CPU 独占访问,不会与其它外设发生总线竞争,这对某些需要高实时性的代码来说至关重要。TCM + SRAM + PSRAM 配置和SRAM + PSRAM 配置的区别在于是否开启 TCM 上,本节仅描述两种配置的差异。

D13x 提供了 128K 的指令 TCM (ITCM) 和 128K 的数据 TCM (DTCM),分别用于存储实时代码和实时数据。开启 TCM 功能后,SRAM_S0 空间就会对应的减少 256K,因为这部分内存会被重新分配给 ITCM 和 DTCM 使用。

内存布局和使用策略


d13x_mem_layout2

如图所示,针对 TCM Memory 资源,软件会使用以下策略来进行分配:

  • 将 TCM 划分为 ITCM RegionDTCM Region 两个区域,分别用于实时代码和数据。

  • 将每个 Region 进一步划分成以下子区域:
    • 静态分配 Static:编译链接后可确认地址。
    • 动态分配 Heap:Heap 内存池运行时确定地址。
综合上述策略,TCM 空间被软件划分成四块区域:
  • ITCM Static:ITCM 静态分配区域。
    通过在函数定义中加入 TCM_CODE_DEFINE 宏声明,可链接到此区域:
    // 函数定义:
    void TCM_CODE_DEFINE test_func(void);
  • ITCM Heap:ITCM 动态分配区域,即 heap_itcm 内存池。

    可以通过以下函数从该内存池分配内存:

    aicos_malloc(MEM_ITCM, size);
  • DTCM Static:DTCM 静态分配区域。

    通过在全局变量定义中加入 TCM_DATA_DEFINE 宏声明,可链接到此区域:

    // 全局变量定义:
    TCM_DATA_DEFINE int a = 1;
  • DTCM Heap:DTCM 动态分配区域,即 heap_dtcm 内存池。

    通过以下函数,可从该内存池分配内存:

    aicos_malloc(MEM_DTCM, size);

参数配置

通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置下列 Meomry 相关参数:
Board options  --->
    Mem Options  --->
  • 使能 TCM 空间

    SRAM parameter  --->
        [*] Enable TCM (Tightly Coupled Memory)  // 开启 TCM 功能,SRAM_S0 空间相应的会减小 256k
Edit online

SRAM

Read time: 8 minute(s)

对于没有 SiP PSRAM 颗粒和 PSRAM Memory 空间的部分 D13x型号,如需使用多媒体模块 DE/ GE/ VE ,必须使能 SRAM_S1 区域。SRAM_S1 区域可以被 DE/GE/VE 硬件访问,但其空间需要从 SRAM_S0 中划分。

SRAM 配置和SRAM + PSRAM 配置区别是用 SRAM_S1 取代 PSRAM 来充当 CMA 区域,本节仅描述两者的差异部分。

内存布局和使用策略


d13x_mem_layout3

如图所示,针对 SRAM_S1 Memory 资源,软件会使用以下策略来进行分配:

  • 将 SRAM_S1 分成两个区域:
    • SRAM_S1 Software Region:在 SRAM_S0 不够系统软件用的情况下补充划分一部分 SRAM_S1 给软件使用。
    • SRAM_S1 CMA Region:专供多媒体模块 MPP 使用
  • 将每个 Region 进一步划分成以下子区域:
    • 静态分配 Static:编译链接后可确认地址。
    • 动态分配 Heap:Heap 内存池运行时确定地址。
综合上述策略,SRAM_S1 空间被软件划分成四块区域:
  • SRAM_S1 SW Static:系统静态分配区域,属于可选区域,通常情况下未配置。

    如需链接到此区域,可在函数定义和全局变量定义中加入 SRAM1_SW_DATA_DEFINE 宏声明:

    // 函数定义:
    void SRAM1_SW_DATA_DEFINE test_func(void);
    
    // 全局变量定义:
    SRAM1_SW_DATA_DEFINE int a = 1;
  • SRAM_S1 SW Heap:系统动态分配区域,即 heap_sram1_sw 内存池,属于可选区域,通常情况下未配置。

    使用以下函数,可从该内存池分配内存:

    aicos_malloc(MEM_SRAM1_SW, size);
  • SRAM_S1 CMA Static:CMA 静态分配区域,属于可选区域,通常情况下未配置。
    • 当 SRAM_S0 空间不够用时,通过 menuconfig 配置菜单,将 .text.rodata.data.bss 放置到 PSRAM 中,可链接到本区域。

    • 如需链接到此区域,可在函数定义和全局变量定义中加入 CMA_DATA_DEFINE 宏声明:
      // 函数定义:
      void CMA_DATA_DEFINE test_func(void);   // CMA_DATA_DEFINE = SRAM1_CMA_DATA_DEFINE
      
      // 全局变量定义:
      CMA_DATA_DEFINE int a = 1;
  • SRAM_S1 CMA Heap:CMA 动态分配区域,即 heap_cma 内存池

    使用以下函数,,可从该内存池分配内存。

    aicos_malloc(MEM_CMA, size);        // MEM_CMA = MEM_SRAM1_CMA

参数配置

通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置下列 Meomry 相关参数:
Board options  --->
    Mem Options  --->
  • SRAM_S1 总大小

    SRAM parameter  --->
        (0x100000) SRAM Total Size    // 配置 SRAM 总大小为 1M
        SRAM_S1 Size (512K)           // 配置 SRAM_S1 大小为 512k,SRAM_S0 大小即为剩下的 512k
            ( ) 0K
            ( ) 128K
            ( ) 256K
            ( ) 384K
            (X) 512K
            ( ) 640K
  • SRAM_S1 CMA 区域大小

    SRAM parameter  --->
        (0x0) Software size in SRAM_S1 // 配置 SRAM_S1 开头 Software 区域大小为 0,剩余结尾 CMA 区域大小即为 512k
  • .text.rodata.data.bss 区域可选择配置到 SRAM_S0/SRAM_S1 中:

    ELF Sections memory locatio  --->
        Section .text (SRAM_S0)  --->
        Section .rodata (SRAM_S0)  --->
        Section .data (SRAM_S0)  --->
        Section .bss (SRAM_S1)  --->
            ( ) SRAM_S0
            (X) SRAM_S1      // 在 SRAM_S0 空间不足的情况下,选择把部分数据存放到 SRAM_S1 当中