4.1.1. 参数配置

4.1.1.1. 术语定义


术语

定义

注释说明

DRAM

Dynamic Random Access Memory

动态随机存取存储器

SRAM

Static Random Access Memory

静态随机存取存储器

PSRAM

Pseudo Static Random Access Memory

伪静态随机存取存储器

CMA

Contiguous Memory Allocator

连续内存分配器,MPP 多媒体模块专用内存

ITCM

Instruction Tightly Coupled Memory

紧耦合指令内存,实时程序专用

DTCM

Data Tightly Coupled Memory

紧耦合数据内存,实时程序专用

4.1.1.2. M4 内存

4.1.1.2.1. 内存布局

../../../_images/m4_mem_layout.png

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

针对 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 内存池运行时地址才会确定。

4.1.1.2.2. 内存使用

综合上述策略,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
    

4.1.1.2.3. 参数配置

可以通过 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 区域
    

4.1.1.2.4. 调试命令

在工程编译时,可以通过 scons --list-mem 命令来查看当前工程的 Memory layout:

$ scons --list-mem
scons: Reading SConscript files ...
output/ZXM47D0N_rtt/images/m4.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 内存池的运行情况:

aic /> free
memheap           pool size  max used size available size
---------------- ---------- ------------- --------------
heap_cma         8362744    48            8362696
heap_sys         758948     50384         710780

4.1.1.3. M3 内存配置(1)SRAM + PSRAM

M3 可使用的内存资源的种类比较多,有 SRAM、PSRAM、TCM。本文列举了其中典型的三种场景来阐述参数配置和使用方法,其他组合场景的配置用户可以参考本文档灵活配置。

4.1.1.3.1. 内存布局

../../../_images/m3_mem_layout1.png

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

备注

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

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

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

  • 接着把 PSRAM 分成两个区域: PSRAM Software RegionPSRAM CMA Region 。CMA Region 提供给多媒体模块 MPP 专用,Software Region 是在 SRAM 不够系统软件用的情况下补充划分一部分 PSRAM 给软件使用,目的也是把 MPP 的动态内存池 (heap_cma) 和 系统动态内存池 (heap_sys) 进行分离,避免 MPP 的内存池碎片化。因为 MPP 的内存分配基本都是大块内存,而系统各模块的内存分配是各种尺寸大小都有,如果共享一个内存池容易造成 MPP 大块内存分配失败。

  • 最后会把每一个 Region 进一步划分成静态分配 Static 和 动态分配 Heap 子区域。静态分配的区域在编译链接后地址已经确定,动态分配区域就是 Heap 内存池运行时地址才会确定。

4.1.1.3.2. 内存使用

综合上述策略,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
    

4.1.1.3.3. 参数配置

可以通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置 Meomry 相关参数:

  • SRAM_S0 总大小

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

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

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

    Board options  --->
        Mem Options  --->
            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 当中
    

4.1.1.3.4. 调试命令

在工程编译时,可以通过 scons --list-mem 命令来查看当前工程的 Memory layout:

$ scons --list-mem
scons: Reading SConscript files ...
output/ZXM37D0_rtt/images/m3.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 内存池的运行情况:

aic /> free
memheap           pool size  max used size available size
---------------- ---------- ------------- --------------
heap_cma         8322232    6005224       3887936
heap_sys         343560     97084         261852

4.1.1.4. M3 内存配置(2)TCM + SRAM + PSRAM

4.1.1.4.1. 内存布局

../../../_images/m3_mem_layout2.png

M3 还支持把部分 SRAM 挂载成 TCM,TCM 的好处是 CPU 独占访问的不会和其他外设发生总线竞争,这对某些实时代码来说是必须的。其中 128K 的 ITCM 给实时代码使用,128K 的 DTCM 给实时数据使用。开启 TCM 功能以后 SRAM_S0 空间就会对应的减少 256K。

备注

可以看到配置(2)和配置(1)的区别是在开启 TCM 上,本章节仅仅只会描述其中的差异部分。

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

  • 首先 TCM 有两个区域: ITCM RegionDTCM Region ,分别用于实时代码和数据。

  • 接着会把每一个 Region 进一步划分成静态分配 Static 和 动态分配 Heap 子区域。静态分配的区域在编译链接后地址已经确定,动态分配区域就是 Heap 内存池运行时地址才会确定。

4.1.1.4.2. 内存使用

综合上述策略,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);
    

4.1.1.4.3. 参数配置

可以通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置 Meomry 相关参数:

  • 使能 TCM 空间

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

4.1.1.5. M3 内存配置(3)SRAM

4.1.1.5.1. 内存布局

../../../_images/m3_mem_layout3.png

M3 的部分型号是没有 SiP PSRAM 颗粒,没有 PSRAM Memory 空间的。这种情况下如果要使用多媒体模块 DE/GE/VE ,必须要使能 SRAM_S1 区域。SRAM_S1 区域可以被 DE/GE/VE 硬件访问,但是它的空间需要从 SRAM_S0 中划分。

备注

可以看到配置(3)和配置(1)的区别是用 SRAM_S1 取代 PSRAM 来充当 CMA 区域,本章节仅仅只会描述其中的差异部分。

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

  • 把 SRAM_S1 分成两个区域: SRAM_S1 Software RegionSRAM_S1 CMA Region 。CMA Region 提供给多媒体模块 MPP 专用,Software Region 是在 SRAM_S0 不够系统软件用的情况下补充划分一部分 SRAM_S1 给软件使用。

  • 接着会把每一个 Region 进一步划分成静态分配 Static 和 动态分配 Heap 子区域。静态分配的区域在编译链接后地址已经确定,动态分配区域就是 Heap 内存池运行时地址才会确定。

4.1.1.5.2. 内存使用

综合上述策略,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
    

4.1.1.5.3. 参数配置

可以通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置 Meomry 相关参数:

  • SRAM_S1 总大小

    Board options  --->
        Mem Options  --->
            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 区域大小

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

    Board options  --->
        Mem Options  --->
            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 当中
    

4.1.1.5.4. 调试命令

4.1.1.6. M3C/M3A 内存

4.1.1.6.1. 内存布局

../../../_images/m3x_mem_layout.png

M3C/M3A 硬件上使用 PSRAM 作为 Memory 主要存储单元,其典型大小为 8M/16M。

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

  • 首先把 PSRAM 分成两个区域: PSRAM Software RegionPSRAM CMA Region 。CMA Region 提供给多媒体模块 MPP 专用,Software Region 提供给系统其他模块使用,主要目的是把 MPP 的动态内存池 (heap_cma) 和 系统动态内存池 (heap_sys) 进行分离,避免 MPP 的内存池碎片化。因为 MPP 的内存分配基本都是大块内存,而系统各模块的内存分配是各种尺寸大小都有,如果共享一个内存池容易造成 MPP 大块内存分配失败。

  • 接着会把每一个 Region 进一步划分成静态分配 Static 和 动态分配 Heap 子区域。静态分配的区域在编译链接后地址已经确定,动态分配区域就是 Heap 内存池运行时地址才会确定。

4.1.1.6.2. 内存使用

综合上述策略,PSRAM 空间被软件划分成四块区域:

  • PSRAM SW Static 系统静态分配区域。 .text .rodata .data .bss 默认会存放到这个区域,即普通的函数定义和全局变量定义。

  • PSRAM SW Heap 系统动态分配区域。即 heap_sys 内存池,可以通过以下函数从该内存池分配内存。

    malloc(size);
    aicos_malloc(MEM_DEFAULT, size);        // MEM_DEFAULT = 0
    
  • PSRAM CMA Static CMA 静态分配区域。函数定义和全局变量定义可以通过加上 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
    

4.1.1.6.3. 参数配置

可以通过 scons --menuconfig 命令进入 menuconfig 配置界面,配置 Meomry 相关参数:

  • PSRAM 总大小

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

    Board options  --->
        Mem Options  --->
            PSRAM parameter  --->
                (0x200000) Software size in PSRAM // 配置 PSRAM 开头 Software 区域大小为 2M,剩余结尾 CMA 区域大小即为 6M
    

4.1.1.6.4. 调试命令

在工程编译时,可以通过 scons --list-mem 命令来查看当前工程的 Memory layout:

$ scons --list-mem
scons: Reading SConscript files ...
output/ZXM3C3D95_rtt/images/m3c.elf Memory layout:

        Region                               Start       End        Length
psram                                   0x40000000 - 0x41000000  0x01000000
  └─ psram_sw                           0x40000000 - 0x40200000  0x00200000
       └─ psram_sw_static               0x40000000 - 0x400e7ae8  0x000e7ae8
            └─ .text                    0x40000000 - 0x400a6640  0x000a6640
            └─ .rodata                  0x400a66b0 - 0x400d6fa8  0x000308f8
            └─ .bss                     0x400d8c00 - 0x400e7ae8  0x0000eee8
       └─ psram_sw_heap                 0x400e7ae8 - 0x40200000  0x00118518
            └─ .heap_sys                0x400e7ae8 - 0x40200000  0x00118518
  └─ psram_cma                          0x40200000 - 0x41000000  0x00e00000
       └─ psram_cma_heap                0x40200000 - 0x41000000  0x00e00000
            └─ .heap_cma                0x40200000 - 0x41000000  0x00e00000

在系统运行时,可以通过 RT-Thread 下的 free 命令来查看 heap_sysheap_cma 内存池的运行情况:

aic /> free
memheap           pool size  max used size available size
---------------- ---------- ------------- --------------
heap_cma         8362744    48            8362696
heap_sys         758948     50384         710780

4.1.1.7. 栈大小配置

4.1.1.7.1. 中断栈

ZX-RTT 中断服务程序运行在独立的栈中,大小可以在 menuconfig 配置界面中修改:

  • 中断栈大小

    Board options  --->
        Mem Options  --->
            (4096) Interrupt stack siz      // 大小为 4k
    

4.1.1.7.2. RT-Thread 线程栈

Kernel 为 RT-Thread 时,几个典型线程的栈空间大小的配置:

  • main 线程栈大小

    Rt-Thread options  --->
        RT-Thread Components  --->
            (2048) Set main thread stack size  // 大小为 2k
    
  • idle 线程栈大小

    Rt-Thread options  --->
        RT-Thread Kernel  --->
            (2048) The stack size of idle thread                // 大小为 2k
            (4) Alignment size for CPU architecture data access // CONFIG_RT_ALIGN_SIZE
    
  • Shell 线程栈大小

    Rt-Thread options  --->
        RT-Thread Components  --->
            MSH: command shell  --->
                (4096) The stack size for thread  // 大小为 4k
    

重要

在使用系统 printf 打印浮点时,要求线程堆栈为 8 字节对齐。这时 CONFIG_RT_ALIGN_SIZE 需要设置为 8,同时线程栈大小也是 8 的整数倍。