Files
TAIXIN/project/app/fpv_mem.c

147 lines
7.9 KiB
C
Raw Normal View History

/**
* @file fpv_mem.c
* @brief FPV
* @details
* - av_psram_heap: PSRAM
* - av_heap: SRAM
* MPOOL_ALLOC
*
*/
#include "sys_config.h" // 包含系统配置宏定义,如 MPOOL_ALLOC、AV_PSRAM_HEAP 等
#include "basic_include.h" // 包含基础类型定义uint32 等)和基础宏
#include "osal/string.h" // 包含操作系统抽象层字符串/打印接口os_printf 等)
#include "lib/heap/av_psram_heap.h" // 包含音视频 PSRAM 堆的初始化接口声明
#include "lib/heap/av_heap.h" // 包含音视频 SRAM 堆的初始化接口声明
// 通用用户空间内存初始化
// 通用用户空间内存初始化入口函数
/**
* @brief
* @details
* 1. PSRAM AV_PSRAM_HEAP PSRAM
* psram
* 2. SRAM AV_HEAP SRAM
* sram SRAM 访
* 使 av_heap SRAM
*
* @param
* @return
*/
void user_heap_init()
{
_os_printf("\r\n"); // 打印空行,作为内存初始化信息输出的起始分隔
os_printf("--------------------------------------------------------------------\r\n"); // 打印分隔线,便于在串口日志中识别内存初始化区域
/*
* ==================== PSRAM ====================
*
* MPOOL_ALLOC -
* AV_PSRAM_HEAP - PSRAM
* PSRAM_HEAP - PSRAM
* PSRAMPseudo-SRAM SRAM
*
*/
#if defined(MPOOL_ALLOC) && defined(AV_PSRAM_HEAP) && defined(PSRAM_HEAP)
{
// 设置堆的属性标志:
// SYSHEAP_FLAGS_MEM_ALIGN_32 - 所有分配的内存按 32 字节对齐,
// 适配 DMA 传输和 SIMD 指令的对其要求
// SYSHEAP_FLAGS_MEM_LEAK_TRACE - 启用内存泄漏追踪,
// 在调试阶段记录每次分配/释放,便于排查泄漏
uint32 flags = SYSHEAP_FLAGS_MEM_ALIGN_32 | SYSHEAP_FLAGS_MEM_LEAK_TRACE;
// 从 PSRAM 系统堆中分配一块大小为 CONFIG_PSRAM_AVHEAP_SIZE 的连续内存,
// 用于后续初始化为音视频专用的 PSRAM 堆
void *av_psram_buf = os_malloc_psram(CONFIG_PSRAM_AVHEAP_SIZE);
// 保存分配到的 PSRAM 内存块大小,供后续初始化函数和日志打印使用
uint32_t av_psram_size = CONFIG_PSRAM_AVHEAP_SIZE;
// 打印 PSRAM 音视频堆的地址范围和大小信息,
// 方便开发者在串口日志中确认内存分配是否正确
os_printf("| CPU0 AV_PSRAM_HEAP : %p ~ %p, Size:%-8d |\r\n", av_psram_buf, av_psram_buf+av_psram_size, av_psram_size);
// 检查 PSRAM 内存是否分配成功,只有成功时才进行堆初始化
if (av_psram_buf)
{
// 使用分配到的 PSRAM 内存块和指定的标志位,初始化音视频 PSRAM 堆,
// 初始化后可通过 av_psram_malloc() 等接口从此堆中分配内存
av_psram_heap_init((void *) av_psram_buf, av_psram_size, flags);
}
}
#endif
/*
* ==================== SRAM ====================
*
* MPOOL_ALLOC -
* AV_HEAP - SRAM
* SRAM 访
*
*
* av_heap SRAM
* "占位-释放"
* 1. SRAM
* 2. av_heap "占位"
* 3. av_heap av_heap
* 4.
*/
#if defined(MPOOL_ALLOC) && defined(AV_HEAP)
{
// 设置 SRAM 音视频堆的属性标志:
// SYSHEAP_FLAGS_MEM_ALIGN_32 - 32 字节对齐,满足 DMA 和缓存行对齐要求
// 注意:此处未启用 SYSHEAP_FLAGS_MEM_LEAK_TRACE因为 SRAM 堆用于高频
// 临时分配,启用追踪会显著影响性能
uint32 flags = SYSHEAP_FLAGS_MEM_ALIGN_32;
// 占位空间的指针,初始为 NULL稍后根据剩余空间情况决定是否分配
void *rev_mem_head = NULL;
// 获取配置中定义的音视频 SRAM 堆大小(字节数)
uint32_t sram_size = CONFIG_AVHEAP_SIZE;
//计算SRAM_HEAP剩余空间
// 查询当前 SRAM 系统堆sram_heap中剩余可用的总字节数
// 用于判断是否有足够空间分配 av_heap 以及是否需要占位
uint32_t total_mem_remain_size = sysheap_freesize(&sram_heap);
// 如果剩余空间大于 av_heap 所需大小 + 1024 字节(预留安全余量),
// 则先分配占位空间,将 av_heap 推向高地址区域
if(total_mem_remain_size > sram_size + 1024)
{
//申请空间,尽量将av_sram空间放到最后
// 计算占位空间大小 = 剩余总量 - av_heap所需 - 1024安全余量
// 申请这块空间后,后续 av_heap 的分配就会被挤到 SRAM 的高地址端
rev_mem_head = (void*)os_malloc(total_mem_remain_size - sram_size - 1024);
}
// 正式分配音视频 SRAM 堆所需的内存块,
// 由于前面可能已有占位分配,此块内存将位于 SRAM 较高地址区域
uint8_t *sram_buf = (uint8_t*)os_malloc(sram_size);
// 打印 SRAM 音视频堆的地址范围和大小信息
os_printf("| CPU0 AV_HEAP : %p ~ %p, Size:%-8d |\r\n", sram_buf, sram_buf+sram_size, sram_size);
// 检查 SRAM 内存是否分配成功,只有成功时才进行堆初始化
if(sram_buf)
{
// 使用分配到的 SRAM 内存块和指定的标志位,初始化音视频 SRAM 堆,
// 初始化后可通过 av_malloc() 等接口从此堆中分配高速内存
av_heap_init((void *) sram_buf, sram_size, flags);
}
// 如果之前分配了占位空间,现在释放它,归还给 SRAM 系统堆,
// 这样系统堆仍可使用这块低地址空间,而 av_heap 已固定在高地址
if(rev_mem_head)
{
os_free(rev_mem_head);
}
}
#endif
os_printf("--------------------------------------------------------------------\r\n"); // 打印分隔线,标记内存初始化信息输出结束
}