Skip to content

LVGL / SD 卡 / PSRAM / 固件资源优化

熟悉 LVGL UI 开发和嵌入式资源优化,具备 SD 卡资源管理、PSRAM 内存优化和固件体积优化经验。
使用 LVGL 实现设备 UI 界面和状态展示,并将部分图片资源外置到 SD 卡,降低固件资源占用。
结合 PSRAM 优化音频缓冲、图片资源和运行时内存占用。

UI 和资源优化能体现你是否真的在资源受限设备上做过工程。面试官会看你是否理解 LVGL 线程模型、固件体积、.rodata、PSRAM 和 SD 卡资源管理。

短答:

LVGL 是嵌入式图形界面库,提供控件、布局、样式、动画和显示刷新能力。

展开回答:

LVGL 通常需要:

display driver
input driver
tick
lv_timer_handler
draw buffer

它不是操作系统,刷新和事件处理需要应用定期调用或由专门 UI task 驱动。

结合我的项目:

我用 LVGL 做设备 UI 状态展示,包括页面、图片、文本和状态切换。

继续追问:

LVGL 的显示 buffer 大小会影响内存占用和刷新效率。

Q2:嵌入式 UI 为什么不能随便跨线程刷新?

Section titled “Q2:嵌入式 UI 为什么不能随便跨线程刷新?”

短答:

LVGL 默认不是多线程安全的,多个 task 同时操作 UI 对象可能造成状态混乱或崩溃。

展开回答:

常见做法是让一个 UI task 或 AppCore 统一调用 LVGL API,其他 task 通过 queue/event 通知 UI 更新。

结合我的项目:

Session、WebSocket、音频 task 不应该直接改 LVGL 控件,而是上报状态,由 App 层统一渲染。

继续追问:

如果必须跨线程访问,需要加锁,但更推荐单 owner 模型。

Q3:图片、字体为什么会占 .rodata

Section titled “Q3:图片、字体为什么会占 .rodata?”

短答:

如果把图片和字体转换成 C 数组编进固件,它们会成为只读数据,占用 app image 的 .rodata

展开回答:

大量图片、中文字体、动画资源会显著增大固件。如果 app 分区有限,可能导致构建产物超过分区大小。

结合我的项目:

我的项目里 UI 图片资源较大,因此把部分图片迁移到 SD 卡,减少固件 .rodata 占用。

继续追问:

字体迁移比图片复杂,因为涉及字库、缓存和渲染性能;图片外置通常风险更低。

Q4:SD 卡外置资源有什么收益和风险?

Section titled “Q4:SD 卡外置资源有什么收益和风险?”

短答:

收益是降低固件体积、方便替换资源;风险是 SD 卡可能缺失、文件损坏、读取慢或路径错误。

展开回答:

外置资源需要考虑:

挂载时机
路径规范
文件存在性检查
fallback
读取失败日志
页面切换性能

结合我的项目:

我把 UI 图片放到 SD 卡,并保留内置 fallback 或错误处理,避免缺卡时设备崩溃。

继续追问:

关键启动资源不一定适合外置;大图片、皮肤、非关键资源更适合外置。

短答:

SRAM 是片上内存,速度快、容量小;PSRAM 是外部伪静态内存,容量大但访问更慢,适合大缓冲和非强实时数据。

展开回答:

PSRAM 适合:

图片缓存
音频大缓冲
网络缓冲
临时大块数据

不适合:

极高频小对象
ISR 关键数据
强实时 DMA 不支持区域

结合我的项目:

我把音频缓冲、下行队列、图片相关数据尽量放到 PSRAM,释放内部 SRAM 给任务栈、驱动和实时路径。

继续追问:

是否能 DMA 访问取决于芯片和配置,不能默认所有 PSRAM 都能给外设 DMA 用。

短答:

先看 app image 大小和分区表,再用 size 工具分析 .text.rodata、组件占用,找大资源和大依赖。

展开回答:

排查方向:

图片/字体 C 数组
日志字符串
未裁剪组件
调试符号/优化等级
第三方库
分区表 app 分区大小

结合我的项目:

我遇到过 app 分区余量不足,优先把图片资源从 .rodata 外置到 SD 卡,而不是一上来改分区表。

继续追问:

改分区表可能影响 OTA、NVS、文件系统布局,不应作为第一反应。

短答:

看 heap 剩余、最小剩余、PSRAM 使用、任务栈 high-water mark、分配失败日志和大缓冲 owner。

展开回答:

需要区分:

固件体积超限: app image 太大
运行时内存不足: heap/stack 不够

二者不是一回事。图片编进 .rodata 影响固件体积;运行时图片缓存和音频缓冲影响 heap。

结合我的项目:

我同时处理过固件 .rodata 占用和运行时音频缓冲占用,分别用 SD 卡外置资源和 PSRAM 承接大缓冲。

继续追问:

任务栈不足不能简单归为 heap 不足,要看每个 task 的 stack watermark。

Q8:为什么把图片资源迁移到 SD 卡,并结合 PSRAM 优化音频缓冲?

Section titled “Q8:为什么把图片资源迁移到 SD 卡,并结合 PSRAM 优化音频缓冲?”

短答:

图片外置解决固件体积问题,PSRAM 解决运行时大缓冲问题,两者对应不同资源瓶颈。

展开回答:

图片 C 数组 -> app image/.rodata 变大 -> 迁移 SD 卡
音频队列/PCM buffer -> heap 占用变大 -> 使用 PSRAM

结合我的项目:

设备既有 UI 图片,又有音频上行/下行缓冲。如果都放内部资源,容易同时遇到分区不足和运行时内存紧张。

继续追问:

外置资源要保证缺卡不崩溃;PSRAM 要保证实时路径不被慢访问拖垮。

  • 认为 PSRAM 可以解决固件分区超限。
  • 多 task 直接调用 LVGL。
  • SD 卡资源缺失时没有 fallback。
  • 把所有数据都放 PSRAM,不考虑 DMA 和实时性。
  • 分不清 .rodata、heap、stack。
我理解嵌入式资源优化要区分固件体积和运行时内存。图片、字体编进固件会占 .rodata,适合通过 SD 卡外置资源降低 app image;音频缓冲、图片缓存这类运行时大块内存可以结合 PSRAM 优化。LVGL 方面,我会避免多线程直接操作 UI,统一由 App/UI 线程刷新。