PSRAM 使用指南
概述
PSRAM(Pseudo Static RAM,伪静态随机存取存储器)是一种兼具 SRAM 接口简单性与 DRAM 容量优势的存储器类型。 通过内部 DRAM 技术 + 自动刷新控制,PSRAM 向主控提供与 SRAM 接口兼容的易用体验,且具备更高容量性价比,适用于图像/音频/缓存等大容量应用场景。
PSRAM 适用场景
PSRAM 特别适合以下应用场景:
图像缓存(摄像头帧缓存、图像预处理)
音频数据处理(语音识别、语音缓存)
联网应用缓存(TCP/IP 缓冲区、OTA 数据)
堆内存扩展(task 创建、运行时内存分配)
我们的 PSRAM 支持情况(BK7258)
BK7258 芯片内置 合封 PSRAM(封装在芯片内部)
自动识别型号与容量:支持 4MB / 8MB / 16MB 三种型号,驱动在启动时会根据 PSRAM ID 自动检测并配置初始化参数,编译时使用的大小需要在ram_regions.csv中配置。
初始化完成后,系统自动映射有效地址空间,供开发者使用
注意:尽管驱动能自动识别容量,但用户访问地址仍需确保不超出有效大小
PSRAM 使用方法
作为 Heap 使用
在配置
AP_PSRAM_HEAP和CP_PSRAM_HEAP即可配置各自APP的PSRAM_HEAP空间,并需要开启宏配置CONFIG_PSRAM_AS_SYS_MEMORY。动态内存接口:
void *psram_malloc(size_t size);
void psram_free(void *p);
低功耗场景:未释放 Heap 内存会影响进入低功耗,可用 bk_psram_heap_get_used_state() 查询当前状态。
PSRAM 上的 Task 创建接口:
bk_err_t rtos_create_psram_thread(beken_thread_t *thread, uint8_t priority, const char *name, beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg);
bk_err_t rtos_delete_thread(beken_thread_t *thread);
作为 多媒体静态内存 使用
多媒体模块(AP)独占部分 PSRAM 空间
使用专用接口申请/释放:
void *bk_psram_frame_buffer_malloc(psram_heap_type_t type, uint32_t size);
void bk_psram_frame_buffer_free(void* mem_ptr);
PSRAM 使用说明
PSRAM 可被 AP 与 CP共同访问,但访问时需要避免资源冲突,确保互斥管理
支持使用 psram_malloc() / psram_free() 接口动态分配内存,用于多媒体缓存、任务创建等
一部分 PSRAM 空间可用于扩展堆内存,提升系统动态内存灵活性
PSRAM的类型
BK7258支持三种类型的PSRAM,具体配置如下:
name
size(Mbyte)
W955D8MKY_5J
4
APS6408L_O
8
APS128XXO_OB9
16
PSRAM的划分
PSRAM主要分为两部分,一部分是多媒体当作数据内存进行使用,另一部分当作不同CPU的heap空间进行使用,需要参考下面的宏定义去使能配置:
marco
value
implication
CONFIG_PSRAM
Y
使能PSRAM模块
CONFIG_PSRAM_AS_SYS_MEMORY
Y
使能PSRAM作为Heap
CONFIG_USE_PSRAM_HEAP_AT_SRAM_OOM
Y
使能sram申请不到内存,从psram申请
功能开关CONFIG_PSRAM_AS_SYS_MEMORY依赖CONFIG_PSRAM和CONFIG_FREERTOS_V10
备注
注意:
系统默认从PSRAM的起始地址(0x60000000)开始的头部区域给多媒体使用。
某个核上是否需要将psram作为heap,是由 CONFIG_PSRAM_AS_SYS_MEMORY 控制。
ram_regions.csv仅作为划分资源分区,是否使用特定的分区由相应的宏进行控制,
但AP侧未开启 CONFIG_PSRAM_AS_SYS_MEMORY 则此分区未被使用。
PSRAM在多媒体上的划分
PSRAM在多媒体上使用,根据功能被划分为四个模块,参考结构体:
psram_heap_type_t,位置:ap/include/driver/media_types.h.各个模块使用的内存是由结构体:
psram_mem_slab_mapping,定义的,参考路径:ap/components/media_utils/src/frame_buffer_mapping.h。 各个模块分配的内存大小在ram_regions.csv中配置,默认配置如下所示:
marco
value(byte)
implication
CONFIG_PSRAM_MEM_SLAB_USER_SIZE
102400
user defined mem block
CONFIG_PSRAM_MEM_SLAB_AUDIO_SIZE
102400
audio module mem block
CONFIG_PSRAM_MEM_SLAB_ENCODE_SIZE
1433600
encode image mem block
CONFIG_PSRAM_MEM_SLAB_DISPLAY_SIZE
5701632
undecode image mem block
备注
注意:上面宏定义的值是默认定义的,使用时可以根据自身需求,动态调整,直接在对应project中ram_regions.csv中进行修改即可。
各个模块内存调整
根据上节所述,psram被划分为四个模块,不同的模块存储的数据类型不同,可在ram_regions.csv中配置地址空间,具体如下:
UASER:分配给用户使用,编译时生成
CONFIG_PSRAM_MEM_SLAB_UASER_SIZE和CONFIG_PSRAM_MEM_SLAB_UASER_SIZE;AUDIO:分配给audio使用,存储的是音频数据,编译时生成
CONFIG_PSRAM_MEM_SLAB_AUDIO_SIZE和CONFIG_PSRAM_MEM_SLAB_AUDIO_SIZE;ENCODE:分配给编码使用,存储的是完整的JPEG图像或者H264图像,编译时生成
CONFIG_PSRAM_MEM_SLAB_ENCODE_SIZE和CONFIG_PSRAM_MEM_SLAB_ENCODE_SIZE;DISPLAY:分配给显示使用,存储的是显示的数据类型,如YUV、RGB565、RGB888等,编译时生成
CONFIG_PSRAM_MEM_SLAB_DISPLAY_SIZE和CONFIG_PSRAM_MEM_SLAB_DISPLAY_SIZE;根据上面不同的模块功能,以及大小,存储的数据量也不一样,比如ENCODE模块可以存储不止一帧的JPEG图像或H264图像, 系统还定义了一帧图像的大小的宏,参考文件:
./bk_idk/middleware/driver/camera/Kconfig:
marco
value(byte)
implication
range
CONFIG_JPEG_FRAME_SIZE
153600
a jpeg frame max size
[0, 204800]
CONFIG_H264_FRAME_SIZE
65536
a h264 frame max size
[0, 204800]
上面的大小需要根据自身需求需要调整,比如需要存储1280X720的JPEG图像,150K的空间可能不够,需要改成200K(204800),甚至更大,根据实际使用情况调整。 同样针对H264数据,有时候需要调整H264的压缩率,以达到更清楚的画质,默认的64K可能不够,需要继续调大,所以也需要根据实际情况做调整。
根据上面的定义的大小,不同块存储的个数可以计算出来,假设DISPLAY模块使用的RGB565,且分辨率为:800X480,那么一帧图像的大小为:800*480*2=768000, 可存储的个数为:CONFIG_PSRAM_MEM_SLAB_DISPLAY_SIZE/768000=7,表示最大存7帧800X480的RGB565图像;
假设ENCODE模块都用来存储JPEG图像,最多存储数量:CONFIG_PSRAM_MEM_SLAB_ENCODE_SIZE/CONFIG_JPEG_FRAME_SIZE=9;但实际情况会同时存储JPEG和H264数据,代码中定义了 各个图像模块最大的存储个数,参考:
ap/components/multimedia/include/frame_buffer.h。
#define FRAME_LIST_NODE_MAX 6
#define COMM_FRAME_LIST_MAX_NODE (FRAME_LIST_NODE_MAX - 2)
#if (!CONFIG_MEDIA_PSRAM_SIZE_4M)
#define H26X_FRAME_LIST_MAX_NODE FRAME_LIST_NODE_MAX
#else
#define H26X_FRAME_LIST_MAX_NODE (FRAME_LIST_NODE_MAX - 2)
#endif
#define YUV_FRAME_LIST_MAX_NODE (FRAME_LIST_NODE_MAX - 3)
上面的数量可以调整,只要保证总的数据量不超过各自模块的size即可。
多媒体上PSRAM使用
因为多媒体的功能都在AP上使用,所以针对PSRAM的使用,只能在AP上直接调用,系统AP启动后会自动给多媒体整个PSRAM进行初始化,用户不需要去自己调用实现。 当AP掉电时,多媒体不再使用PSRAM,不需要额外调用注销的接口去释放相应的内存。
内存初始化接口:
bk_psram_frame_buffer_init内存申请和释放接口:
void *bk_psram_frame_buffer_malloc(psram_heap_type_t type, uint32_t size); void bk_psram_frame_buffer_free(void* mem_ptr);
备注
客户使用时,建议使用系统的接口去申请和释放psram内存(psram_mallocpsram_free),不建议使用上面多媒体模块自定义的申请和释放psram内存接口
应用层配置psram过cache
如果上层应用想要配置psram过cache来的提升速度,可以参考下述方法。 下面是默认的psram配置:
- { ARM_MPU_RBAR(0x60000000UL, ARM_MPU_SH_NON, 0, 1, 0),
ARM_MPU_RLAR(0x63FFFFE0UL, 1) },
假如现在上层需要将部分psram配置为cacheable,需要将代码修改为以下,这部分代码位于mpu_cfg.c中:
- { ARM_MPU_RBAR(0x60000000UL, ARM_MPU_SH_INNER, 0, 1, 0),
ARM_MPU_RLAR(0x62FFFFE0UL, 1) }, //noncacheable
- { ARM_MPU_RBAR(0x62FFFFE0UL, ARM_MPU_SH_NON, 0, 1, 0),
ARM_MPU_RLAR(0x63FFFFE0UL, 0) }, //cacheable
备注
1.不要将所有psram都配置为cacheable,而应该分段配置。因为被系统部分使用的psram默认是不开启cache的。
2.客户上层配置的cacheable的pasrm部分,需要由上层保证数据的一致性。
PSRAM使用注意事项与动态行为
PSRAM与低功耗管理的关系
Heap 初始化 / 多媒体静态使用时 投票上电
资源释放后 投票下电,系统自动管理,无需手动干预
PSRAM空间划分规则
默认 PSRAM_DATA_ADDR(0x60000000) 到 DISPLAY分区结束为多媒体静态区
避免各个分区重叠
不同容量对工程配置影响
不同工程场景需合理配置 PSRAM 空间
若配置超出硬件容量,编译阶段 自动报错提示
Dump 行为说明
系统默认 Dump Heap 区内容
多媒体静态区需手动接口查看,不自动 Dump