4. 内存类型与分配机制

在 TouchGFX 应用中,内存并不是一块“越大越好”的模糊资源,而是由多种物理介质组成的层级体系。不同介质在容量、速度、成本、可写性和访问方式上差异巨大,如果分配策略与介质特性不匹配,轻则帧率下降,重则界面卡顿、撕裂甚至无法启动。理解每种介质的“性格”,是资源与内存优化的第一步。

TouchGFX 存储介质层级与数据分配关系 MCU 内部 内部 Flash 代码 · 常量 · 字库 · 图片资源 只读,XIP 执行,容量 512KB~2MB 访问速度中等,擦写寿命有限 内部 RAM 帧缓冲 · 栈 · 堆 · 高频变量 读写最快,容量 128KB~1MB TCM/SRAM 可零等待访问 成本高,需优先保障关键数据 ⚠ 帧缓冲放此处易导致 RAM 耗尽 MCU 外部 外部 SDRAM 主帧缓冲 · 大尺寸图片 · 动画缓存 容量大 8MB~64MB,成本低 需 FMC/LTDC 控制器,有刷新开销 带宽受总线与刷新策略影响 QSPI Flash 外部字库 · 大图资源 · 音频 容量 4MB~128MB,可 XIP 四线 SPI,速度低于 SDRAM 适合只读资源,需缓存加速 资源加载 按需读取

一、核心原理:四种介质的特性对比

TouchGFX 运行时需要同时满足“代码执行”“资源读取”“帧缓冲读写”三类需求,而没有任何一种介质能同时最优地满足全部需求。因此,合理的做法是让每种数据流向最适合它的介质。

介质 典型容量 访问速度 可写性 TouchGFX 典型用途
内部 Flash 512KB~2MB 中(XIP) 只读,需擦除 应用代码、常量、小字库
内部 RAM 128KB~1MB 最快 可读写 栈、堆、高频变量、小帧缓冲
外部 SDRAM 8MB~64MB 较快,有刷新 可读写 主帧缓冲、大图、动画缓存
QSPI Flash 4MB~128MB 较慢 只读,需擦除 外部字库、大图资源、音频

二、方法流程:分配策略的决策顺序

面对一个具体项目,建议按以下顺序做内存分配决策:

  1. 先确定帧缓冲位置。帧缓冲是 TouchGFX 最大的连续内存消耗者。若内部 RAM 不足以容纳双缓冲,应优先将帧缓冲放入外部 SDRAM,并确认 LTDC/FMC 带宽满足刷新率。
  2. 再划分只读资源。图片、字库、音频等只读数据优先放入 QSPI Flash 或内部 Flash,通过 XIP 或按需加载方式访问,避免占用 RAM。
  3. 最后分配运行时内存。栈、堆、TouchGFX 内部对象、模型数据等放在内部 RAM,保证访问速度与确定性。
  4. 用链接脚本固化布局。通过分散加载文件或链接脚本,把不同段明确映射到不同介质,避免编译器随意放置。
关键原则:速度敏感的数据放内部 RAM,容量敏感的数据放外部 SDRAM,只读资源放 Flash,帧缓冲优先考虑 SDRAM。

三、案例场景:480×272 屏的分配方案

以 STM32F429 + 480×272 RGB565 屏幕为例,单帧缓冲约 480×272×2 = 261KB,双缓冲约 522KB。若内部 RAM 仅 256KB,显然无法容纳双缓冲,必须外扩 SDRAM。

/* 链接脚本片段:将帧缓冲与资源分段放置 */
MEMORY
{
  FLASH   (rx) : ORIGIN = 0x08000000, LENGTH = 2M
  RAM     (rwx): ORIGIN = 0x20000000, LENGTH = 256K
  SDRAM   (rwx): ORIGIN = 0xC0000000, LENGTH = 8M
  QSPI    (rx) : ORIGIN = 0x90000000, LENGTH = 16M
}

SECTIONS
{
  .framebuffer : { *(.framebuffer) } > SDRAM
  .text        : { *(.text*) }       > FLASH
  .data        : { *(.data*) }       > RAM
  .bss         : { *(.bss*) }        > RAM
  .qspi_assets : { *(.qspi_assets) } > QSPI
}

对应到 TouchGFX 配置中,需要把 TouchGFX_Framebuffer 指向 SDRAM 地址,把图片资源通过 Bitmap::setCache 或外部加载器指向 QSPI 区域。这样内部 RAM 只保留栈、堆和模型数据,通常可控制在 100KB 以内。

四、误区与复盘

常见误区一:把帧缓冲放在内部 RAM。小屏低分辨率时可能可行,但一旦分辨率提升或启用双缓冲,内部 RAM 会迅速耗尽,导致栈溢出或分配失败。应尽早评估帧缓冲大小。
常见误区二:所有资源都塞进内部 Flash。内部 Flash 容量有限,且 XIP 读取大图时可能拖慢 CPU。大尺寸图片和字库应迁移到 QSPI Flash 或 SDRAM。
复盘建议:在项目早期就画出“介质—数据”映射表,明确每类数据的归属;在链接脚本中固化布局;用 TouchGFX Designer 的资源统计和 map 文件核对实际占用。这样可以在开发初期就避免后期因内存不足而大规模重构。

总结来说,内部 Flash、内部 RAM、外部 SDRAM 和 QSPI Flash 各有不可替代的位置。优化的本质不是“省内存”,而是“把正确的数据放到正确的介质上”。理解这一点,后续的帧缓冲优化、资源压缩和缓存策略才有稳固的基础。