2. 显示子系统基础概念:CRTC、Encoder、Connector、Plane、Framebuffer 的定义与关系

在 DRM/KMS 模型中,显示子系统被抽象为若干个逻辑组件,每个组件承担特定的硬件控制职责。理解这些组件的定义及其协作关系,是进行驱动移植和调试的基础。本章将逐一解析 CRTC、Encoder、Connector、Plane 和 Framebuffer 的核心概念,并通过结构图和表格阐明它们在显示流水线中的角色。

2.1 核心组件定义

组件 英文全称 核心职责 硬件对应
CRTC Cathode Ray Tube Controller 生成显示时序、扫描控制、帧同步 显示控制器(如 i.MX8 LCDIF、Rockchip VOP)
Encoder Encoder 将像素数据编码为特定接口信号 HDMI 发送器、LVDS 发送器、DSI D-PHY
Connector Connector 物理连接检测、EDID 读取、热插拔管理 HDMI 插座、VGA 接口、eDP 连接器
Plane Plane 图层合成、缩放、颜色空间转换 硬件图层(Overlay、Primary、Cursor)
Framebuffer Framebuffer 存储像素数据的内存缓冲区 显存区域(DMA-BUF、CMA、IOMMU 映射)
术语提醒:CRTC 名称源自阴极射线管时代,但在现代 LCD/LED 显示中,它仍然代表“时序控制器”这一核心功能。不要被字面意思误导。

2.2 组件关系:显示流水线

五个组件按照固定的数据流方向组成一条完整的显示流水线。数据从 Framebuffer 出发,经过 Plane 合成,由 CRTC 控制时序,通过 Encoder 编码,最终由 Connector 输出到物理显示器。

数据流方向: Framebuffer → Plane → CRTC → Encoder → Connector → 显示器
DRM 显示流水线组件关系图 DRM 显示流水线:组件关系与数据流 Framebuffer 像素数据存储 Plane 图层合成/缩放 CRTC 时序生成/扫描 Encoder 信号编码 Connector 物理连接 说明: • 一个 CRTC 可以连接多个 Encoder(如同时输出 HDMI 和 LVDS),但同一时刻只能激活一条路径。 • 一个 Plane 必须绑定到一个 CRTC 才能参与显示;Framebuffer 是 Plane 的数据来源。 • Connector 负责检测显示器是否插入、读取 EDID 信息,并报告给 CRTC 进行模式配置。

2.3 各组件在 DRM 模型中的角色详解

2.3.1 CRTC:显示引擎的“心脏”

CRTC 是显示子系统的核心时序发生器。它负责从内存中读取像素数据,按照设定的分辨率、刷新率、行/场同步参数生成扫描时序,并将数据推送到下一级。在嵌入式平台中,CRTC 通常对应 SoC 内部的显示控制器模块(如 Rockchip VOP、Allwinner DE2)。

  • 关键参数:时钟频率(pixel clock)、水平/垂直前肩、同步宽度、后肩。
  • 多 CRTC 场景:双屏异显时,每个显示器需要独立的 CRTC 实例。
  • 驱动接口:struct drm_crtc + drm_crtc_helper_funcs。

2.3.2 Encoder:像素数据的“翻译官”

Encoder 将 CRTC 输出的并行 RGB 数据转换为特定显示接口所需的串行信号格式。常见的编码类型包括:

接口类型 编码方式 典型应用
HDMI TMDS(Transition Minimized Differential Signaling) 电视、显示器
LVDS 低压差分信号,4/5 通道 工业屏、笔记本内屏
MIPI DSI D-PHY 高速串行 手机、平板、嵌入式 LCD
eDP 嵌入式 DisplayPort 笔记本、高端嵌入式

2.3.3 Connector:物理世界的“桥梁”

Connector 代表物理显示接口,负责检测显示器是否连接、读取 EDID(扩展显示标识数据)以获取显示器支持的分辨率列表,并管理热插拔事件。Connector 本身不处理像素数据,而是作为状态感知节点。

常见陷阱:Connector 的 EDID 读取失败会导致 CRTC 无法获取有效模式,进而无法点亮屏幕。调试时优先检查 /sys/class/drm/card0-*-edid 文件是否存在且内容正确。

2.3.4 Plane:图层合成的“画家”

Plane 是 DRM 模型中实现硬件图层叠加的关键组件。每个 Plane 对应一个独立的显示图层,支持独立的 Framebuffer、位置、大小、透明度(alpha)和颜色空间。典型的 Plane 类型包括:

  • Primary Plane:主图层,每个 CRTC 至少有一个,通常用于显示桌面或主界面。
  • Overlay Plane:叠加图层,用于视频播放、UI 弹窗等,支持硬件缩放。
  • Cursor Plane:光标图层,尺寸小(通常 64x64),更新频率高,独立于主图层。

2.3.5 Framebuffer:像素数据的“仓库”

Framebuffer 是存储像素数据的内存区域,通常由 DMA-BUF 或 CMA 分配。它包含颜色格式(RGB565、XRGB8888、NV12 等)、分辨率、行宽(pitch)和偏移量等信息。Plane 从 Framebuffer 中读取数据,经过合成后输出。

// Framebuffer 创建示例(简化)
struct drm_framebuffer *fb;
struct drm_mode_fb_cmd2 r = {
    .width  = 1920,
    .height = 1080,
    .pixel_format = DRM_FORMAT_XRGB8888,
    .handles[0]   = gem_handle,
    .pitches[0]   = 1920 * 4,
};
fb = drm_internal_framebuffer_create(dev, &r, NULL);

2.4 组件绑定关系:KMS 对象拓扑

在 DRM 内核中,上述组件通过对象指针形成拓扑结构。一个典型的绑定关系如下:

KMS 对象拓扑绑定关系 KMS 对象拓扑:组件绑定关系 CRTC (crtc0) Primary Plane Overlay Plane Cursor Plane Encoder (encoder0) Connector (HDMI-A-1) • 一个 CRTC 可以绑定多个 Plane(主层 + 叠加层 + 光标层)。 • 一个 CRTC 连接一个 Encoder,Encoder 再连接一个 Connector,形成完整链路。

2.5 组件协作流程:一次完整的显示刷新

  1. 应用程序通过 DRM 的 drmModePageFlip() 或 drmModeAtomicCommit() 提交新的 Framebuffer。
  2. Plane 接收新的 Framebuffer,配置裁剪区域、缩放参数和透明度。
  3. CRTC 在下一个 VBlank 周期开始读取 Plane 合成的像素数据,生成行/场同步信号。
  4. Encoder 将 CRTC 输出的并行数据编码为 TMDS/LVDS/DSI 信号。
  5. Connector 将编码后的信号通过物理线缆发送到显示器,同时监控热插拔状态。
  6. 显示器 接收信号并显示画面,完成一次刷新。
关键点:整个流程是流水线并行的——CRTC 在读取当前帧时,Plane 已经在准备下一帧的配置。这种双缓冲/多缓冲机制保证了画面不撕裂。

2.6 总结:组件角色速查表

组件 一句话角色 驱动开发关注点
CRTC 时序生成器 时钟配置、模式验证、VBlank 中断
Encoder 信号编码器 接口初始化、电源管理、模式设置
Connector 物理接口管理器 EDID 解析、热插拔检测、状态轮询
Plane 图层合成器 Framebuffer 绑定、alpha 混合、缩放
Framebuffer 像素数据容器 内存分配、格式转换、DMA 映射