本章以 Buildroot 系统为主(
root@用户、eglfs后端)。示例中板子 IP 为192.168.1.100,Ubuntu 虚拟机 IP 为192.168.1.200,请替换为实际值。
板子显示后端配置(必读)
RK3576 搭载 Mali GPU,Qt 应用通过 eglfs_kms 后端直接操作 KMS/DRM 输出画面,不需要 X11 或 Wayland。eglfs 要求独占 DRM 设备——如果有其他程序(如 Wayland 合成器)正在使用显示设备,Qt 程序会出现屏幕闪烁和 Could not queue DRM page flip (Device or resource busy) 报错。
关闭 Weston(首次配置,一次性操作)
默认 Buildroot 镜像会自启动 Weston(Wayland 合成器),它会占用 DRM 设备。eglfs 模式下必须关闭它:
# 确认 weston 是否在运行
fuser /dev/dri/card0
# 如果有输出(如 766),说明有进程占用
# 禁用 weston 自启动并重启
chmod -x /etc/init.d/S49weston
reboot2
3
4
5
6
7
重启后 Weston 不再启动,DRM 设备空闲,Qt 程序可以正常独占使用。
如果以后需要恢复 Weston,执行
chmod +x /etc/init.d/S49weston后重启即可。
确认显示设备
ls /sys/class/drm/card0-*
cat /sys/class/drm/card0-*/status2
找到状态为 connected 的设备名称(如 HDMI-A-1),编辑 /etc/qt-eglfs-kms.conf:
{
"device": "/dev/dri/card0",
"hwcursor": false,
"outputs": [
{
"name": "HDMI-A-1",
"mode": "1920x1080"
}
]
}2
3
4
5
6
7
8
9
10
"hwcursor": false禁用硬件光标,避免Failed to move cursor on screen报错刷屏。如需鼠标指针,Qt 会自动改用软件光标。
环境变量
运行 Qt 应用前必须设置:
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
export QT_QPA_EGLFS_KMS_CONFIG=/etc/qt-eglfs-kms.conf
export QT_QPA_FONTDIR=/usr/share/fonts/dejavu
export QT_PLUGIN_PATH=/usr/lib/qt/plugins2
3
4
5
如果是纯触屏场景(不需要鼠标指针),额外设置:
export QT_QPA_EGLFS_HIDECURSOR=1如果需要鼠标和触摸共存,不要设置 HIDECURSOR。KMS 配置中的 "hwcursor": false 会让 Qt 使用软件光标,鼠标指针正常显示且不会触发硬件光标报错。
| 变量 | 说明 |
|---|---|
QT_QPA_PLATFORM | 平台后端,eglfs 通过 EGL/OpenGL ES 直接渲染,不需要 X11 |
QT_QPA_EGLFS_INTEGRATION | 设为 eglfs_kms,通过内核 KMS/DRM 控制显示输出 |
QT_QPA_EGLFS_KMS_CONFIG | KMS 配置文件路径 |
QT_QPA_FONTDIR | 必须指向直接包含 .ttf 文件的目录,Qt 不递归搜索子目录 |
QT_PLUGIN_PATH | Qt 插件路径,包含输入设备(libinput/evdev)和平台插件 |
QT_QPA_EGLFS_HIDECURSOR | 设为 1 隐藏光标,纯触屏场景使用。不设置则显示软件光标 |
建议将这些 export 写入板子的
/etc/profile,免得每次手动设置。
部署方式
SCP + SSH
cmake --build build && scp build/tspi-sysmonitor root@192.168.1.100:/root/ && \
ssh root@192.168.1.100 "/root/tspi-sysmonitor"2
NFS 挂载(推荐)
NFS 配置参见通信通道 — NFS 共享。
CMake 安装路径直接指向 NFS 共享目录,编译即部署:
cmake -B build -DCMAKE_INSTALL_PREFIX=/srv/nfs/qt-dev
# 每次改代码后:
cmake --build build && cmake --install build
# 板子上直接运行(或通过 SSH 触发)
ssh root@192.168.1.100 "/mnt/nfs/bin/tspi-sysmonitor"2
3
4
5
6
7
一键编译并重启板端程序:
cmake --build build && cmake --install build && \
ssh root@192.168.1.100 "pkill -f tspi-sysmonitor 2>/dev/null; /mnt/nfs/bin/tspi-sysmonitor &"2
上述 SSH 命令省略了环境变量,前提是已写入
/etc/profile。否则需在命令前加上完整的 export。
常见 NFS 问题:
- "Connection refused":Ubuntu 防火墙未放行 NFS →
sudo ufw allow from 192.168.1.0/24 to any port nfs - 文件只读:
/etc/exports缺少rw选项 → 修改后sudo exportfs -ra - 程序无法执行:NFS 挂载带了
noexec→ 重新挂载加exec选项
ADB
通过 OTG Type-C 连接 Windows 端。详见 ADB 使用教程。
adb push tspi-sysmonitor /root/
adb shell "chmod +x /root/tspi-sysmonitor && /root/tspi-sysmonitor"2
GDB 远程调试
GDB 来源
Buildroot 默认不编译交叉 GDB,使用 SDK 预置的 aarch64-rockchip1031-linux-gnu-gdb(GCC 10.3 附带),调试 GCC 12.4 编译的程序没有问题。
编译 Debug 版本
cmake -B build \
-DCMAKE_TOOLCHAIN_FILE=/home/lckfb/TaishanPi-3-Linux/buildroot/output/rockchip_rk3576/host/share/buildroot/toolchainfile.cmake \
-DCMAKE_PREFIX_PATH=/home/lckfb/TaishanPi-3-Linux/buildroot/output/rockchip_rk3576/staging/usr/lib/cmake \
-DCMAKE_BUILD_TYPE=Debug
cmake --build build2
3
4
5
调试流程
板子上启动 gdbserver(如果没有 gdbserver,需在 Buildroot 中启用 BR2_PACKAGE_GDB_SERVER):
gdbserver :2345 /root/tspi-sysmonitorUbuntu 虚拟机连接:
/home/lckfb/TaishanPi-3-Linux/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-rockchip1031-linux-gnu-gdb build/tspi-sysmonitor
(gdb) target remote 192.168.1.100:2345
(gdb) break main
(gdb) continue2
3
4
5
Core Dump 分析
# 板子上
ulimit -c unlimited && ./tspi-sysmonitor
# Ubuntu 虚拟机取回分析
scp root@192.168.1.100:/tmp/core-* /tmp/
aarch64-rockchip1031-linux-gnu-gdb build/tspi-sysmonitor /tmp/core-tspi-sysmonitor-1234
(gdb) bt2
3
4
5
6
7
常见问题排查
| 错误信息 | 原因 | 解决 |
|---|---|---|
cannot open shared object file: libQt5Widgets.so.5 | Qt 库不在搜索路径 | export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH |
Could not find the Qt platform plugin "eglfs" | 平台插件路径未设置 | find / -name "libqeglfs.so" 找到后设置 QT_QPA_PLATFORM_PLUGIN_PATH |
Could not create the EGL display | GPU 驱动未加载 | 检查 ls /dev/dri/ 和 dmesg | grep -i mali,临时用 linuxfb 回退 |
Permission denied | 缺执行权限或 NFS noexec | chmod +x 或重新挂载 NFS 加 exec |
下一步
下一步:Buildroot 应用内置