内存管理
芯片内存配置基础
内存配置需先明确芯片硬件特性,核心关注 核结构、内存类型 及 存储支持,具体如下:
1. 核结构与内存分配
核类型:
芯片分为 单核(如 52x 系列)和 双核(含低功耗小核 LCPU + 高性能大核 HCPU )。双核场景:需根据功能对性能/功耗的需求分配核资源(如低功耗任务放 LCPU,高性能任务放 HCPU )。
单核场景(52x 系列):硬件为单核,但软件架构虚拟“LCPU”(实际运行在 HCPU 上),确保跨平台代码兼容性。
内存类型:
包括 SRAM(高速、小容量)和 PSRAM(低速、大容量)。LCPU 通常仅挂载 SRAM;部分 SF32LB5x 系列 LCPU 可能挂载 NOR Flash(需根据功能需求选择芯片型号 )。
2. 存储方案差异
SF32LB5x 系列支持两种存储方案,内存配置需适配:
(1)NOR Flash 方案
特性:支持 XIP(直接执行),内存需求较低。
说明:代码和资源可直接从 NOR Flash 运行,无需额外搬运。
(2)NAND/eMMC 方案
特性:不支持 XIP,需注意以下两点:
PSRAM 容量需 ≥8MB(用于加载代码和资源 );
代码(
code.bin
)和图片资源需从 NAND/eMMC 搬运到 PSRAM 后才能执行/访问。
内存分配与配置
内存主要用于 9 类场景,其存储位置(SRAM/PSRAM)通过链接脚本(solution\framework\__template__\config\link_scipt\.sct
)配置,具体如下:
No |
内存用途 |
说明与配置方式 |
---|---|---|
1 |
Code/RO |
必须常驻内存的代码及只读数据,由链接脚本指定存储位置 |
2 |
RW/ZI |
可读写数据(RW)和初始化为 0 的数据(ZI),默认随代码分配 |
3 |
帧缓冲区(framebuffer) |
用于 GUI 显示,配置路径 |
4 |
堆内存(Heap) |
包括系统堆(system heap)和专用堆(memheap),配置路径 |
5 |
场景动画切换 buffer |
支持应用切换动画时所需缓冲区,配置路径 |
6 |
线程栈(Thread stack) |
建议静态分配,频繁使用栈放 SRAM(减少Cache换入换出提升性能) |
7 |
图形加速资源 |
图片旋转缓存从 SRAM 堆分配,绘图 canvas 从 PSRAM 堆分配 |
8 |
NAND/eMMC 的 code.bin |
因不支持 XIP,开机时从 NAND/eMMC 搬运到 PSRAM 执行 |
9 |
NAND/eMMC 的图片资源 |
需先搬运到 PSRAM 才能被 ePIC 硬件访问,需使用 PSRAM 堆 |
堆内存(Heap)详解
Solution 在 app_mem.c
中提供多种堆内存管理接口,包括块内存、系统堆及专用堆,特性如下:
1. 块内存(可选)
配置:通过
menuconfig → App memory configuration → Using block memory
开启。特性:
优点:分配速度快,无内存碎片;
缺点:需预先定义块大小和数量,复用性低,易浪费内存。
适用场景:映射
lv_mem
(LVGL 的琐碎内存分配 ),通过app_malloc
申请(申请失败时自动转用系统堆 ),建议应用小内存优先使用。
2. 系统堆(system heap)
分配接口:
rt_malloc
。存储位置:可配置在 SRAM 或 PSRAM(通过
menuconfig
指定 )。管理方式:
小内存管理:内存利用率高,但分配速度慢(适合 SRAM,因容量有限 );
大内存管理:分配速度快,但易产生碎片(适合 PSRAM,因容量较大 )。
3. 专用堆(memheap)
SRAM memheap / PSRAM memheap
分配接口:
app_cache_alloc
(需指定CACHE_SRAM
或CACHE_PSRAM
);特性:采用大内存管理(分配快,易碎片 );
适用场景:
SRAM 堆用于高速度需求的内存(受容量限制 );
PSRAM 堆用于消息存储、图片缓存、canvas 等。
注:PSRAM 堆大小自动计算,无需手动配置。
Freetype memheap
用途:专用于字体渲染(支持 Freetype 时需配置 )。
容量建议:
NAND/eMMC 方案:建议 ≥500KB;
NOR 方案:建议 ≥200KB。
配置:通过
menuconfig
指定专用堆大小。
内存异常导致的死机及原因
常见内存异常场景如下(需重点规避 ):
内存越界:分配后使用范围超出申请大小。
野指针操作:未初始化/未申请的指针直接使用,覆盖其他内存或访问非法地址。
非保持区内存误用:睡眠唤醒后未重新初始化 non-retention 区域内存,继续使用。
退栈异常:野指针导致函数返回时栈错误。
回调函数指针异常:指针未赋值或指向非法地址。
释放后使用:内存已
rt_free
或·app_cache_free
释放,仍继续访问。多线程互斥缺失:同一片内存被多线程并发访问,数据异常。
Cache 操作错误:未执行
mpu_dcache_clean
或mpu_dcache_invalidate
,导致数据不一致。