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. 内存布局
M4 硬件上使用 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 内存池运行时地址才会确定。
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_sys
和 heap_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. 内存布局
M3 第一种典型内存配置是:SRAM + PSRAM。SRAM_S0 速度较快但是容量较小,提供给软件系统使用。PSRAM 速度略慢但是容量较大,提供给多媒体外设模块 DE/GE/VE 作为缓存使用,外设模块的 DMA 直接存取这些内存。
备注
为了减少总线冲突,DE/GE/VE 硬件上已被限制不能访问 SRAM_S0 区域的内存。
针对以上 Hardware Memory 资源,软件会使用以下策略来进行分配:
首先把 SRAM 的
SRAM_S0 Region
区域提供给系统软件使用。接着把 PSRAM 分成两个区域:
PSRAM Software Region
和PSRAM 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_sys
和 heap_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. 内存布局
M3 还支持把部分 SRAM 挂载成 TCM,TCM 的好处是 CPU 独占访问的不会和其他外设发生总线竞争,这对某些实时代码来说是必须的。其中 128K 的 ITCM 给实时代码使用,128K 的 DTCM 给实时数据使用。开启 TCM 功能以后 SRAM_S0 空间就会对应的减少 256K。
备注
可以看到配置(2)和配置(1)的区别是在开启 TCM 上,本章节仅仅只会描述其中的差异部分。
针对 TCM Memory 资源,软件会使用以下策略来进行分配:
首先 TCM 有两个区域:
ITCM Region
和DTCM 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. 内存布局
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 Region
和SRAM_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. 内存布局
M3C/M3A 硬件上使用 PSRAM 作为 Memory 主要存储单元,其典型大小为 8M/16M。
针对 PSRAM Memory 资源,软件会使用以下策略来进行分配:
首先把 PSRAM 分成两个区域:
PSRAM Software Region
和PSRAM 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_sys
和 heap_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 的整数倍。