显示控制器与帧缓冲:图层、像素 DMA、时序与撕裂同步
更新时间:2026-09-19。前置:SPI TFT ST7789 驱动、MIPI DSI、MIPI CSI-2 摄像头、DMA 突发。命令式小屏靠 CPU 推像素;大屏/高帧率需要专门的显示控制器硬件,在屏幕刷新的同时连续不断地从内存搬像素。
本文要回答的问题
- 帧缓冲在内存里怎么布局,控制器怎么把它变成时序信号?
- 行场同步、porch、像素时钟如何确定分辨率和刷新率?
- FIFO 欠载、撕裂是怎么发生的,双缓冲/TE 怎么解决?
- 图层混合和带宽预算有哪些坑?
一、显示控制器做什么
bash
帧缓冲(内存中的像素矩阵)
│ 像素 DMA: 在消隐区持续突发读取
▼
内部 FIFO ─► 图层/格式转换/混合 ─► 时序发生器
├─ RGB 并行接口(PCLK/HS/VS/DE/RGB) 或
└─ MIPI DSI 视频模式(打包发出,见 DSI)- 帧缓冲(framebuffer):一段连续内存,按固定像素格式(RGB565/RGB888/ARGB)逐行存放,每个扫描行长度 = 宽×每像素字节,可能带 stride(行跨度对齐)。
- 像素 DMA:控制器做主控,按扫描节奏从帧缓冲连续读像素,经内部 FIFO 平滑发往接口(DMA 机制见 DMA 微架构、突发对齐)。
- 时序发生器:产生像素时钟 PCLK、行同步 HS、场同步 VS、数据有效 DE 和 porch 时序。
- 控制器常挂在 AHB/AXB 上,输出并行 RGB(如 LTDC)或经桥到 DSI/HDMI。
二、行场时序(与 porch)
一帧由可见区和消隐区组成:
bash
垂直: [VSYNC][VBP 后肩][可见行 VACTIVE][VFP 前肩]
每一行: [HSYNC][HBP][有效像素 HACTIVE][HFP]
PCLK: 每个像素一个时钟;DE 在有效像素区间高- HSYNC/VSYNC 是 CRT 时代电子束回扫的同步信号,LCD 仍沿用;控制器按屏手册配各段长度(像素数/行数)和极性。
- 总像素时钟 = (HACTIVE+HBP+HFP+HSYNC) × (VACTIVE+VBP+VFP+VSYNC) × 刷新率。例:800×480@60Hz 含 porch 常需 ~33MHz PCLK。
- porch 期没有可见像素,控制器可利用消隐时间预取下一行;软件常在 VS/消隐中断里换缓冲。
- 配错 porch/极性/时钟会出现黑屏、画面偏移、抖动(与 DSI 视频模式 porch 同理)。
三、FIFO 欠载(underrun)
显示输出不能停:每个 PCLK 都要有像素。若总线繁忙、DMA 没能及时把像素喂进 FIFO,FIFO 见底就发生 underrun,表现为该行/帧花屏、错位。
- 控制器用内部 FIFO 吸收总线抖动,并在 porch(尤其垂直消隐)尽量多预取。
- 必须保证内存平均带宽 > 像素消耗带宽,且有足够突发效率(连续帧缓冲、AXI burst、避免零碎访问)。
- 高分辨率/高色深/多层叠加时带宽陡增,要做带宽预算(与其他主控竞争,见 多通道 DMA、NoC QoS)。
四、撕裂与双缓冲
- 撕裂(tearing):控制器正在读一帧时,CPU/DMA 同时更新同一缓冲,屏幕上半部显示旧帧、下半部显示新帧。
- 双缓冲(double buffering):准备两块帧缓冲,控制器显示 A 时 CPU 写 B;在 VSYNC/消隐时刻原子切换显示地址指针(寄存器在帧边界生效),再交换角色,保证整帧一致。三缓冲可进一步解耦渲染与显示节奏。
- TE(tearing effect)信号:命令模式屏(带 GRAM,如 DSI command mode/小屏)由屏拉 TE 告诉主控「我正消隐,可安全写」,主控在 TE 后更新(见 DSI 命令模式、ST7789)。
- 切换指针要用屏障保证缓冲内容对 DMA 可见(clean cache),否则显示旧数据(见 内存屏障)。
五、图层、格式与混合
中高级控制器支持多个图层/叠加:
- 每图层独立帧缓冲、位置、格式(RGB565/888/ARGB/YUV)。
- per-pixel alpha 混合、color key(指定颜色透明)、分层优先级,硬件做 blend;视频层常直接收 YUV(摄像头经 CSI-2 进来)。
- 图层越多、色深越高,DMA 要读的像素和内部带宽越大,常对不可见层做裁剪/关层省电。
- 输出可经伽马、抖动、色彩空间转换、旋转(部分硬件)。
六、帧缓冲、cache 与对齐
- 帧缓冲通常要求起始地址和行 stride 对齐到 burst/缓存行(如 8/16/32/64 字节边界),否则 DMA 效率低或越界(见 突发对齐)。
- 帧缓冲内存若被 CPU cache,CPU 写完要 clean(写回) 后 DMA 才看得到;很多实现把帧缓冲设 non-cacheable 或显式维护,配合 DSB 屏障。
- 大块连续物理内存:带 MMU 时需分配物理连续内存(CMA)或 IOMMU 映射,否则散页无法被简单 DMA 连续读取(见 MMU/TLB)。
- 内存来源可以是片内 SRAM(小屏)或外挂 DDR/PSRAM/HyperRAM(高分辨率,见 DDR、PSRAM、HyperRAM)。
七、常见的坑
- 带宽不够导致 underrun:没算 porch/色深/层数总带宽,高负载时花屏;要预算并给显示 DMA 高优先级/QoS。
- 帧缓冲非连续/不对齐:stride 不对齐、散页内存导致 DMA 越界或低效。
- 单缓冲撕裂:边显示边写;应双缓冲并在 VSYNC 原子切指针。
- cache 未 clean:CPU 更新在缓存里没回写,屏幕显示旧帧。
- porch/极性/PCLK 配错:黑屏、偏移、闪烁;严格按屏手册。
- 像素格式不一致:RGB565 缓冲按 888 解释,颜色错、宽高错位。
- stride 与宽混淆:带对齐填充时按 width×bpp 计算下一行偏移出错。
- TE/vsync 时序没对齐就换帧:在帧中间切指针仍撕裂,要在消隐边界。
- 多层全开:叠加不可见层浪费带宽和功耗,应裁剪/关层。
- FIFO 阈值/预取不当:阈值太高启动晚、太低抗抖动弱。
- 外部 RAM 刷新争用:DDR 刷新/其他主设备在关键行抢占造成 underrun(见 DDR 刷新)。
- DSI/并行接口选择错:命令模式(GRAM)与视频模式(持续供流)模型不同(见 DSI)。
相关与延伸
小屏命令式驱动见 ST7789;串行大屏见 MIPI DSI;摄像头输入见 CSI-2;DMA/带宽见 DMA 突发对齐、多通道 DMA;外部大缓冲见 HyperRAM。
总结
显示控制器把帧缓冲(按像素格式和对齐 stride 线性存放的像素矩阵)经像素 DMA 在行场消隐期连续突发读入内部 FIFO,再由时序发生器按 PCLK、HS/VS、H/V porch 和 DE 把像素不间断输出到并行 RGB 或 MIPI DSI,任何一拍供不上就 underrun 花屏,因此内存平均带宽必须覆盖「总时序像素×刷新率×色深×层数」并给显示 DMA 足够 QoS;硬件还支持多图层、alpha/color-key 混合与 YUV 层,软件用双缓冲在 VSYNC/TE 消隐边界原子切换显示指针防撕裂,并保证缓冲物理连续、地址对齐和写完后 clean cache——带宽预算、缓冲对齐与 cache 回写、porch 时序和单缓冲撕裂是四大常见坑。