4. modetest 工具介绍
modetest 是 Linux DRM/KMS 子系统中最核心的调试工具之一,被嵌入式显示驱动开发者称为“显示界的瑞士军刀”。它能够直接与 DRM 设备交互,枚举显示资源(CRTC、Encoder、Connector、Plane)、测试显示模式、执行 Page Flip 和 VBlank 事件监听,而无需依赖任何图形栈(如 X11/Wayland/SurfaceFlinger)。在 RK3588 平台开发中,modetest 是验证显示通路、排查驱动故障的首选工具。
适用场景: 驱动移植初期验证 Framebuffer 是否正常输出、MIPI/HDMI/DP 接口是否枚举、分辨率是否匹配、多屏同显/异显配置、以及 VBlank 中断是否工作。
4.1 modetest 来源
modetest 是 libdrm 测试工具集的一部分,源码托管在 drm 子项目下。它不是一个独立的软件包,而是随 libdrm 一起编译发布的实用程序。
| 项目 | 说明 |
|---|---|
| 上游仓库 | https://gitlab.freedesktop.org/mesa/drm |
| 源码路径 | drm/tests/modetest/ |
| 依赖库 | libdrm、libkms、pthread |
| RK3588 SDK 位置 | external/libdrm/tests/modetest/ |
| License | MIT |
关键提示: RK3588 的 Android SDK 和 Linux SDK(如 RK3588_LINUX_SDK)均预置了 libdrm 源码。如果目标文件系统没有 modetest 二进制,只需交叉编译 libdrm 的 tests 子目录即可生成。
4.2 编译方法
modetest 的编译分为本地编译和交叉编译两种场景。在 RK3588 开发中,通常使用交叉编译生成 ARM64 二进制,然后推送到目标板执行。
4.2.1 本地编译(x86 开发机验证)
# 安装依赖
sudo apt-get install meson ninja-build libdrm-dev
# 获取源码
git clone https://gitlab.freedesktop.org/mesa/drm.git
cd drm
# 使用 meson 构建
meson setup builddir
ninja -C builddir
# 编译完成后,modetest 位于 builddir/tests/modetest/
4.2.2 交叉编译(RK3588 ARM64 目标)
# 设置交叉编译工具链(以 RK3588 SDK 为例)
export CROSS_COMPILE=aarch64-linux-gnu-
export CC=${CROSS_COMPILE}gcc
export AR=${CROSS_COMPILE}ar
export STRIP=${CROSS_COMPILE}strip
# 配置 meson 交叉编译
meson setup builddir \
--cross-file /path/to/aarch64-cross-file.txt \
-Dtests=true
ninja -C builddir
# 提取 modetest 并 strip
${STRIP} builddir/tests/modetest/modetest
# 将 modetest 推送到 RK3588 板卡
adb push builddir/tests/modetest/modetest /data/
交叉编译文件示例(aarch64-cross-file.txt):
[binaries]
c = '/usr/bin/aarch64-linux-gnu-gcc'
cpp = '/usr/bin/aarch64-linux-gnu-g++'
ar = '/usr/bin/aarch64-linux-gnu-ar'
strip = '/usr/bin/aarch64-linux-gnu-strip'
pkgconfig = '/usr/bin/aarch64-linux-gnu-pkg-config'
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'
4.3 基本用法
modetest 的基本调用格式为:
modetest [-M <card>] [-c] [-e] [-p] [-f] [-s <connector_id>:<mode>] [-v] [-a]
以下是最常用的操作模式:
| 操作 | 命令示例 | 说明 |
|---|---|---|
| 枚举所有资源 | modetest -M rockchip -c -e -p -f |
列出 Connector、Encoder、CRTC、Plane 和 Framebuffer |
| 显示测试画面 | modetest -M rockchip -s 38:1920x1080-60@AR24 |
在 Connector 38 上输出 1920x1080@60Hz 彩条 |
| 监听 VBlank | modetest -M rockchip -v 38 |
监听指定 CRTC 的 VBlank 事件 |
| Atomic 模式测试 | modetest -M rockchip -a -s 38:1920x1080-60@AR24 |
使用 Atomic API 提交显示配置 |
注意: Connector ID(如 38)是动态分配的,每次驱动加载或热插拔后可能变化。务必先执行
modetest -c 获取当前有效的 Connector ID。
4.4 常用参数解析
modetest 的参数体系覆盖了 DRM/KMS 的全部核心操作。以下按功能分类详细解析:
4.4.1 资源枚举类参数
| 参数 | 全称 | 功能描述 | 输出示例(RK3588) |
|---|---|---|---|
-c |
--connector | 枚举所有 Connector,包括类型、状态、物理尺寸、支持的 CEA/VESA 模式列表 | Connector 38 (HDMI-A-1) connected, 1920x1080, 1280x720, ... |
-e |
--encoder | 枚举所有 Encoder,显示其 ID、类型、可能的 CRTC 掩码 | Encoder 37 (TMDS) possible_crtcs: 0x1 |
-p |
--plane | 枚举所有 Plane,包括主平面、叠加平面、光标平面及其格式支持 | Plane 56 (Primary) formats: AR24, XR24, NV12, ... |
-f |
--fb | 枚举当前已创建的 Framebuffer 对象 | Framebuffer 1 (1920x1080, AR24) |
4.4.2 显示测试类参数
| 参数 | 格式 | 功能描述 | RK3588 实战建议 |
|---|---|---|---|
-s |
<conn_id>:<mode>[@<format>] |
在指定 Connector 上设置显示模式并输出彩条测试画面 | 常用:-s 38:1920x1080-60@AR24 |
-s 多屏 |
<conn_id>@<crtc_id>:<mode> |
指定 CRTC 与 Connector 的绑定关系,用于多屏异显 | -s 38@56:1920x1080 -s 39@57:1280x720 |
-P |
<plane_id>@<crtc_id>:<w>x<h>+<x>+<y> |
在指定 CRTC 上配置 Plane 的位置和尺寸,用于叠加测试 | -P 56@56:640x480+100+100 |
-F |
pattern |
指定测试画面模式:smpte(彩条)、tiles(棋盘)、gradient(渐变) | -F smpte 为默认彩条 |
4.4.3 调试与事件类参数
| 参数 | 功能描述 | 典型输出 |
|---|---|---|
-v |
监听 VBlank 事件,打印时间戳和帧序列号 | crtc 56: seq 12345, time 1234567890.123456 |
-a |
使用 Atomic API 提交所有配置(推荐在 RK3588 上使用) | Atomic commit succeeded |
-D |
启用 DRM 调试日志(需内核开启 DRM_DEBUG) | [drm:drm_atomic_commit] committing |
-M |
指定 DRM 主设备节点,默认 /dev/dri/card0 |
-M rockchip 或 -M /dev/dri/card1 |
-R |
执行 Page Flip 测试,循环切换 Framebuffer | Page flip count: 100 |
4.4.4 模式字符串详解
-s 参数中的模式字符串遵循以下格式:
<connector_id>:<width>x<height>[-<refresh>][@<fourcc_format>]
| 字段 | 示例 | 说明 |
|---|---|---|
| connector_id | 38 | 通过 -c 获取的 Connector 编号 |
| width x height | 1920x1080 | 分辨率,必须被 Connector 的 mode list 支持 |
| -refresh | -60 | 刷新率(Hz),可选,不指定则使用第一个匹配分辨率的模式 |
| @fourcc_format | @AR24 | 像素格式,AR24=ARGB8888, XR24=XRGB8888, NV12=YUV420 |
RK3588 实战经验:
- HDMI 输出常用
AR24或XR24,MIPI DSI 常用AR24或RG16。 - 如果指定模式不被支持,modetest 会报错
mode not found,此时先用-c查看可用模式列表。 - 多屏同显时,使用相同的 CRTC ID 绑定多个 Connector;多屏异显时,每个 Connector 绑定不同的 CRTC。
- Atomic 模式(
-a)在 RK3588 上能更准确地反映驱动状态,建议作为首选测试方式。
4.5 实战:RK3588 上首次使用 modetest
以下是在 RK3588 开发板上首次使用 modetest 的完整操作序列:
- 确认 DRM 设备节点存在:
ls /dev/dri/ # 预期输出: card0 card1 renderD128 - 枚举所有显示资源:
modetest -M rockchip -c -e -p -f - 从输出中找到目标 Connector ID(例如 HDMI 输出为 Connector 38,状态为 connected)。
- 输出测试画面:
modetest -M rockchip -s 38:1920x1080-60@AR24 - 观察屏幕是否出现彩条,同时终端打印 VBlank 事件信息。