跳到主要内容

堆分配与 PSRAM

概述

TuyaOpen 应用通过 TALtal_memory.h / tal_api.h)进行动态内存分配。在带 外部 PSRAM 的芯片上,Kconfig 可打开 ENABLE_EXT_RAM,部分子系统与便捷宏会切换到 tal_psram_*,避免大块缓冲挤占稀缺的 片上 SRAM

读者对象:带 SPIRAM 的 ESP32 等支持 ENABLE_EXT_RAM 的目标上开发应用与中间件;Linux 开发者可将本文视为可移植 API 说明(底层映射为端口的 malloc)。

先决条件

要求

  • 头文件:#include "tal_memory.h" 或按工程惯例 #include "tal_api.h"
  • 使用 PSRAM 系列 API:在解析后的 Kconfig / app_default.config 路径中 ENABLE_EXT_RAM 须为 1,且硬件须具备 PSRAM(常见于带 SPIRAM 的 ESP32-S3 模组)。

片上堆(tal_malloc 族)

void *tal_malloc(size_t size);
void tal_free(void *ptr);
void *tal_calloc(size_t nitems, size_t size);
void *tal_realloc(void *ptr, size_t size);
int tal_system_get_free_heap_size(void);

一般对象、小型队列以及应留在 快速片上 RAM 的数据(DMA 约束、Wi-Fi/蓝牙底层等仍由端口定义)使用 tal_malloc / tal_free

tal_system_get_free_heap_size() 在典型 RTOS 端口上报告 片上 剩余堆(见 TAL 系统 API)。

PSRAM 堆(tal_psram_*ENABLE_EXT_RAM

ENABLE_EXT_RAM1 时,以下 API 可用(见 TuyaOpen/src/tal_system/include/tal_memory.h):

void *tal_psram_malloc(size_t size);
void tal_psram_free(void *ptr);
void *tal_psram_calloc(size_t nitems, size_t size);
void *tal_psram_realloc(void *ptr, size_t size);

ESP32 上,tal_psram_malloc 在适配层中映射为 heap_caps_malloc(..., MALLOC_CAP_SPIRAM) — 大块 TLS 会话结构、音频环形区、AI 流水线等在启用时常走该路径。

同一头文件中,便捷宏 Malloc / Calloc / FreeENABLE_EXT_RAM 为 1 时展开为 tal_psram_*,否则为 tal_malloc / tal_calloc / tal_free。SDK 内部分模块(如 TLS、部分 AI 服务)会显式判断 ENABLE_EXT_RAM;新增大块分配时请沿用相同模式。

备注

若端口提供 tal_psram_get_free_heap_size(),可与片上堆查询配合使用 — 见 TAL 系统 API

SRAM 与 PSRAM 的选择

优先使用片上 tal_malloc在启用时优先 tal_psram_*
小而频繁的分配大且长期存在的缓冲(音频、图像、模型临时区)
对延迟敏感的路径可接受 SPIRAM 延迟的批量数据
仅支持从片上 RAM DMA 的外设驱动SDK 示例中已迁移到 PSRAM 的 TLS / AI 缓冲

务必核对芯片 DMA 能力:并非所有外设都能从 PSRAM 做 DMA。

显示与多媒体

显示栈可能按配置在 SRAM 或 PSRAM 中申请帧缓冲。参见 显示tal_display_framebuffer_create 与内存类型参数。

预期结果

你能根据 ENABLE_EXT_RAM 与板级能力在 tal_malloctal_psram_malloc 之间一致地选型,并知道在有无 PSRAM 的板子间切换时应检查哪些 Kconfig。

参考