1. 项目概述为什么要在RK3568上折腾双屏同显最近在搞一个基于RK3568的工控项目客户要求在同一个操作界面上一块屏幕放在操作台给操作员用另一块大屏挂在墙上给参观或监控的人看两块屏幕必须显示一模一样的内容。这不就是典型的“双屏同显”需求嘛。RK3568这颗芯片在嵌入式圈子里挺火的性能不错接口也丰富官方资料说支持多路显示输出但真到自己动手配置的时候才发现从芯片能力到最终点亮两块屏中间隔着好几道坎。双屏同显听起来简单不就是把一份图像数据复制到两个显示通道嘛。但在嵌入式Linux系统里这涉及到内核显示驱动框架DRM/KMS、设备树DTS配置、以及显示服务比如Wayland或X11的协同工作。RK3568的显示子系统VOP设计得很灵活支持最多三路独立的Video PortVP这为多屏输出提供了硬件基础。但硬件支持只是第一步软件配置才是大头。你需要搞清楚哪路VP连接了哪个物理接口HDMI、LVDS、MIPI-DSI等如何在设备树里正确描述这种连接关系以及如何让合成器Compositor知道你要克隆输出。这个需求在数字标牌、工业控制台、教育一体机、医疗显示终端等领域非常常见。它不追求扩展桌面那种“异显”的灵活性而是强调显示的可靠性和一致性。对于开发者来说实现双屏同显是深入理解Linux图形栈和Rockchip平台显示框架的一个绝佳实践。接下来我就结合自己的踩坑经验把RK3568配置双屏同显的完整思路、关键步骤和避坑指南详细拆解一遍。2. RK3568显示子系统与双屏同显原理拆解2.1 RK3568 VOP与Video Port硬件架构要配置双屏首先得摸清RK3568显示输出的“家底”。Rockchip把它的显示控制器叫做VOPVideo Output Processor。你可以把它想象成一个功能强大的“图像分发中心”。它的核心工作是从内存Frame Buffer里读取已经渲染好的图像数据然后进行一系列处理比如缩放、色彩空间转换最后通过物理接口发送给显示器。RK3568的VOPv2版本内部包含多个独立的Video PortVP。根据Rockchip的文档RK3568通常有三个VPVP0, VP1, VP2。这才是实现多屏的关键。每个VP都是一个完全独立的显示流水线它可以连接一个物理显示接口。这意味着在硬件层面RK3568有能力同时驱动三块屏幕每块屏幕的内容可以相同同显也可以不同异显。那么VP具体连到了哪些接口上呢这取决于核心板的设计。以市面上常见的开发板为例其映射关系通常是这样的VP0: 通常分配给HDMI TX高清多媒体接口或eDP嵌入式DisplayPort。VP1: 可能分配给LVDS低压差分信号或另一个HDMI如果支持。VP2: 通常分配给MIPI DSI移动产业处理器接口或RGB接口。这里有一个至关重要的概念物理接口与VP的绑定关系是在设备树Device Tree里定义的。开发板厂商会根据自己板子的实际布线在DTS文件中写明例如hdmi节点使用vop属性指向vop0即VP0dsi节点指向vop2。我们的配置工作很大程度上就是在理解和修改这些绑定关系。2.2 双屏同显的软件实现路径在Linux图形系统中实现同显主要有两种思路路径一内核驱动层克隆CRTC Clone这是更底层、更高效的方式。通过修改显示驱动通常是Rockchip的DRM驱动将一个CRTC对应一个VP的输出直接复制到另一个CRTC。这样从帧缓冲区Framebuffer到两个VP的数据流在内核里就完成了复制上层应用无感知。这种方式性能损耗极低两块屏的同步性最好。但需要你熟悉内核驱动代码并进行定制化修改门槛较高且不同内核版本可能适配方式不同。路径二显示服务层复制Compositor Mirroring这是更通用、更常用的方式。我们不在内核里做文章而是让显示服务器的合成器来干这个活。无论是Wayland如Weston还是X11它们的合成器都支持将同一个桌面表面Surface渲染到多个输出Output上。例如在Weston的配置文件weston.ini里你可以指定某个输出作为另一个输出的“镜像”mirror。这种方式不涉及内核修改配置相对灵活通过用户空间的配置文件即可管理是大部分项目首选的方案。对于我们这次的目标考虑到易用性和可维护性我会选择路径二即通过配置显示服务以Wayland/Weston为例来实现双屏同显。这样即使未来内核或驱动有升级我们的配置也能最大程度地保持兼容。2.3 关键约束与前提条件在动手之前必须确认以下几点否则大概率会失败硬件支持你的RK3568核心板及底板必须确实引出了两路可用的显示接口并且接口类型符合你的屏幕需求如HDMILVDS。内核支持你使用的内核必须已经编译并包含了这两路显示接口的驱动如DRM_ROCKCHIP_DSI,DRM_ROCKCHIP_HDMI,DRM_ROCKCHIP_LVDS等。设备树基础配置开发板默认的设备树应该已经正确配置了各个显示接口的引脚复用Pinctrl、供电等基本节点确保单屏显示是正常的。VP资源不冲突你要使用的两个显示接口必须绑定到不同的VP上。比如HDMI用了VP0那么你的第二块屏如LVDS就必须使用VP1或VP2。如果两块屏配置到了同一个VP那是无法同时点亮的。3. 设备树DTS配置详解设备树是告诉内核硬件连接关系的“地图”。实现双屏第一步就是修改设备树确保两个显示接口节点都被启用且分配了正确的VP资源。3.1 定位与修改显示接口节点首先找到你的内核源码中对应你开发板的设备树文件.dts或.dtsi通常位于arch/arm64/boot/dts/rockchip/目录下。文件名通常包含开发板型号如rk3568-evb.dts。我们需要修改两个地方启用第二个屏幕的节点默认情况下为了省电或避免冲突可能只启用了一个显示节点比如只有hdmi节点是status “okay”;。你需要找到第二个屏幕对应的节点比如dsi或lvds将其状态改为“okay”。分配正确的VP检查并确认两个显示节点的rockchip,vop属性指向了不同的VOP即VP。例如// HDMI 节点通常使用 vop0 (VP0) hdmi { status “okay”; rockchip,vop vop0; // 明确指定使用VP0 }; // LVDS 节点需要指定为 vop1 (VP1) 或 vop2 (VP2) lvds { status “okay”; rockchip,vop vop1; // 指定使用VP1 // 注意还需要正确配置 lvds_panel 子节点指定屏幕时序参数 };重要rockchip,vop这个属性非常关键它建立了物理接口与VOP硬件模块的链接。务必确保两个屏幕使用的vop不同。3.2 处理时钟与电源依赖有些显示接口有依赖关系。例如MIPI DSI可能依赖于同一个VP上的另一个接口的时钟。或者某些屏幕需要特定的供电引脚enable-gpios和背光控制backlight节点。你需要根据屏幕规格书和开发板原理图确保这些节点也被正确启用和配置。一个常见的坑是背光不亮。即使屏幕驱动信号正常如果背光PWM或使能GPIO没有配置屏幕也是一片黑。检查设备树中对应屏幕的backlight属性是否指向了一个有效的背光节点如backlight并且该背光节点的状态也是“okay”。3.3 编译与更新设备树修改保存后需要重新编译设备树并更新到开发板。# 在内核源码根目录下 make ARCHarm64 your_board_name.dtb # 例如make ARCHarm64 rk3568-evb.dtb编译生成的.dtb文件在arch/arm64/boot/dts/rockchip/目录下。将其替换掉开发板/boot目录下的原设备树文件具体路径因系统而异可能是/boot/dtbs/rockchip/然后重启。重启后可以通过以下命令验证两个显示接口是否都被内核识别# 查看DRM设备信息应该能看到两个connector连接器 cat /sys/kernel/debug/dri/0/state # 或者使用 modetest 工具需要安装 modetest -M rockchip如果能看到两个状态为connected的connector并且它们的crtc对应VPID不同那么设备树配置就基本成功了。4. 配置Wayland/Weston实现屏幕镜像设备树搞定后硬件层面已经准备就绪两块屏幕应该都能被内核的DRM驱动识别为独立的显示输出。接下来我们需要让图形合成器Weston将图像输出到这两块屏上并设置为同显模式。4.1 Weston核心配置解析Weston的配置文件通常是/etc/xdg/weston/weston.ini或/etc/weston.ini。我们需要在其中定义输出Output行为。一个实现双屏同显的基础配置示例如下[core] # 取消注释以允许后端使用多个GPU/设备如果需要 # gbm-formatargb8888 [output] nameHDMI-A-1 mode1920x108060 transformnormal [output] nameLVDS-1 mode1280x80060 transformnormal # 关键指定此输出为HDMI-A-1的镜像 same-asHDMI-A-1配置项解读[output]: 每个段落定义了一个显示输出。name: 这是输出的名称这是最容易出错的地方。这个名称不是随意写的必须与DRM驱动报告的名称一致。获取准确名称的方法是# 方法1查看 /sys/class/drm/ 目录 ls /sys/class/drm/ | grep card0- # 你会看到类似 card0-HDMI-A-1, card0-LVDS-1 的目录 # 名称就是 - 后面的部分如 HDMI-A-1, LVDS-1 # 方法2使用 weston-info 命令在Weston运行后另一个终端执行 weston-info # 在输出信息中寻找 output: 段落里面有 name: 字段mode: 设置该输出的分辨率和刷新率。格式为宽度x高度刷新率。必须确保这个分辨率在你的屏幕和驱动支持的EDID模式列表中。设置一个不支持的模式会导致该输出无法初始化。transform: 设置旋转normal为不旋转90180270为旋转角度flipped和flipped-180等用于镜像翻转。如果副屏显示方向不对可以调整这个参数。same-as:这是实现同显的关键指令。它告诉Weston当前这个输出如LVDS-1应该显示与same-as指定的输出如HDMI-A-1完全相同的内容。你可以将多个输出same-as到同一个主输出上。4.2 分辨率与时序适配如果两块屏幕的分辨率不同比如主屏是1080p副屏是1280x800Weston会怎么处理在same-as模式下Weston会将主输出的帧缓冲区内容缩放Scale到每个副输出的分辨率上。缩放算法会影响清晰度和性能。为了获得最佳效果建议尽量使用相同分辨率如果硬件允许为两块屏幕选择相同的原生分辨率可以避免缩放带来的性能损失和图像质量下降。调整缩放器Weston的DRM后端支持配置缩放过滤器。你可以在[core]或[output]段落添加scaling-filter选项如scaling-filtersmart双线性插值或scaling-filternearest最近邻可能产生锯齿。根据画面内容文字/图像进行选择。验证EDID对于HDMI屏幕系统通常会通过EDID自动读取最佳分辨率。如果自动识别失败你可以强制指定mode。对于LVDS等屏幕需要在设备树的panel-timing节点中手动定义分辨率时序参数确保与屏幕规格书一致。4.3 启动Weston并验证配置完成后重启Weston服务或者如果Weston是作为显示管理器如Weston-launch启动的则重启系统。# 如果Weston是systemd服务 sudo systemctl restart weston # 或者直接在前台启动调试在已登录的终端下CtrlC可退出 weston --backenddrm-backend.so --tty1 --log/tmp/weston.log启动后观察两块屏幕是否都亮起并显示相同的桌面内容。如果只有一块亮或者Weston启动失败需要查看日志排查。# 查看Weston日志 journalctl -u weston --since “5 minutes ago” # 如果用了systemd cat /tmp/weston.log # 如果前台启动指定了log文件常见启动失败原因name字段错误找不到对应的DRM connector。指定的mode不被支持。两个输出配置到了同一个CRTCVP上这通常意味着设备树rockchip,vop配置有误。权限问题Weston进程没有访问DRM设备/dev/dri/card0的权限。确保用户属于video和input组。5. 高级调试与性能优化5.1 使用DRM调试工具当屏幕不亮或显示异常时内核的DRM调试接口是强大的武器。启用DRM调试日志在启动内核时添加参数drm.debug0x0e或0xff获取最详细日志可以在dmesg中看到DRM驱动初始化和模式设置的详细过程有助于定位硬件初始化失败的原因。使用modetest这个工具是调试DRM的“瑞士军刀”。# 列出所有资源 modetest -M rockchip # 它会显示所有connector, encoder, crtc, plane的信息。重点关注 # - connector: 是否connected支持的modes有哪些 # - crtc: 每个crtc的ID对应一个VP。 # 手动测试显示模式谨慎使用会覆盖当前显示 # modetest -M rockchip -s connector_id[crtc_id]:mode ... # 例如同时设置两个输出 # modetest -M rockchip -s 4341:1920x1080 -s 4442:1280x800检查/sys/kernel/debug/dri/这个目录下的文件实时反映了DRM的状态。# 查看当前状态 cat /sys/kernel/debug/dri/0/state # 检查每个connector的EDID信息HDMI屏 cat /sys/kernel/debug/dri/0/connector/id/edid | edid-decode5.2 同显模式下的性能考量双屏同显意味着GPU或合成器需要处理两倍于单屏的像素输出如果分辨率不同则按实际计算。虽然数据是复制的但扫描输出Scanout和信号生成的工作量是实打实增加的。帧率稳定性在高分辨率如双4K下可能会对RK3568的显示子系统造成压力。使用glmark2-es2-wayland或weston-simple-egl测试帧率观察是否出现卡顿。如果卡顿可以考虑降低分辨率或刷新率。确保内核中CONFIG_DRM_DMA_SYNC等同步机制已开启减少延迟。检查CPU/GPU频率缩放策略确保在显示期间运行在足够高的性能档位。内存带宽双屏显示会占用更多的内存带宽用于帧缓冲区。确保系统内存RAM带宽充足且没有其他外设如GPU、VPU、NPU在疯狂争抢带宽。功耗与发热同时驱动两块屏幕尤其是高亮度屏幕功耗会显著增加。需要评估开发板或产品的电源设计是否满足要求并注意散热。5.3 从同显切换到异显有时你可能需要动态切换显示模式。Weston本身不支持运行时动态修改same-as配置。但你可以通过以下方式实现多配置文件切换准备两个weston.ini文件一个是同显配置一个是异显扩展桌面配置。通过脚本停止Weston替换配置文件再启动Weston。这会有短暂的黑屏。使用扩展桌面直接移除same-as配置并为每个[output]设置不同的位置positionWeston就会将它们组织成一个扩展桌面。[output] nameHDMI-A-1 mode1920x108060 position0,0 # 主屏在(0,0)坐标 [output] nameLVDS-1 mode1280x80060 position1920,0 # 副屏在主屏右侧X坐标偏移主屏宽度编写自定义合成器插件这是最灵活但最复杂的方式。你可以编写一个Weston插件监听DBus信号或读取配置文件动态调用DRM的MODE_SET接口来改变输出模式。这需要对Weston和DRM API有深入理解。6. 常见问题排查与解决方案实录在实际操作中你几乎一定会遇到各种奇怪的问题。下面是我总结的“排坑指南”。6.1 屏幕不亮或只亮一块这是最常见的问题。请按照以下流程图进行排查问题屏幕不亮 | v 1. 检查硬件连接与供电 - 线缆是否插紧屏幕电源是否打开 - 测量屏幕背光电压和信号线电压需万用表。 | v 2. 检查内核驱动加载 - lsmod | grep rockchip 查看相关DRM驱动是否加载。 - dmesg | grep -i “drm\|vop\|hdmi\|dsi\|lvds” 查看启动日志有无错误。 | v 3. 检查设备树配置 - 确认第二个屏幕的节点 status “okay”;。 - **关键**确认两个屏幕的 rockchip,vop 属性指向不同的VOP如vop0, vop1。 - 检查背光(backlight)、使能引脚(enable-gpios)配置。 | v 4. 检查DRM识别状态 - cat /sys/class/drm/card0-*/status 查看连接状态。 - 使用 modetest -M rockchip 确认两个connector是否为 connected。 | v 5. 检查Weston配置 - name 字段是否与 /sys/class/drm/ 下的名称**完全一致**大小写敏感 - 指定的 mode 是否在 modetest 列出的支持模式中 - 查看Weston日志 (journalctl -u weston 或 /tmp/weston.log) 中的错误信息。特别注意一个隐蔽的坑有些LVDS屏幕需要特定的像素时钟Pixel Clock和双通道/单通道配置。这些参数在设备树的panel-timing节点和lvds节点的dual-channel等属性中设置。一个错误的像素时钟值会导致屏幕完全无信号。务必对照屏幕数据手册Datasheet逐项核对。6.2 显示画面异常花屏、偏移、撕裂花屏/雪花信号干扰检查排线是否过长、是否靠近高速信号线。LVDS信号对干扰敏感确保使用屏蔽良好的线缆。时序参数错误设备树中panel-timing的hback-porch,hfront-porch,vback-porch,vfront-porch,hsync-len,vsync-len等参数必须精确。花屏往往是同步信号前沿/后沿设置不对。内存问题帧缓冲区内存访问错误。尝试降低分辨率或刷新率看是否改善。用memtester工具测试内存稳定性。画面偏移或显示不全屏幕参数检查Weston配置或设备树中的分辨率是否与屏幕物理分辨率一致。过扫描Overscan某些电视或显示器默认开启过扫描会导致图像边缘被裁剪。尝试在Weston配置中为该输出添加overscan0选项或在显示器菜单中关闭“过扫描”功能。画面撕裂垂直同步VSync未开启确保Weston合成器开启了VSync。在weston.ini的[core]部分可以尝试添加presentation-timestampstrue。性能不足同显加重了系统负担导致合成帧率跟不上刷新率。按照5.2节的性能优化建议处理。6.3 Weston启动失败或崩溃权限错误最常见的错误是failed to open /dev/dri/card0: Permission denied。确保运行Weston的用户如weston或你的登录用户属于video和input组。可以执行sudo usermod -aG video,input $USER并重新登录。资源冲突如果之前用modetest手动设置了显示模式没有清理可能会占用CRTC资源导致Weston无法初始化。重启系统是最简单的解决方法。配置语法错误weston.ini文件对格式有要求节[section]和键值对keyvalue必须正确。一个多余的空格或错误的缩进都可能导致解析失败。可以使用weston --validate命令如果支持来检查配置文件语法。依赖缺失Weston需要GBMGeneric Buffer Management和EGL库。确保已安装libgbm1,libegl1-mesa等包。可以通过ldd /usr/bin/weston检查动态链接库是否齐全。6.4 系统启动后Weston不自动启动这通常与你的系统初始化系统如systemd和显示管理器配置有关。检查服务状态sudo systemctl status weston或sudo systemctl status display-manager。检查服务依赖Weston服务可能依赖于图形环境如graphical.target和多用户登录multi-user.target。确保系统进入了正确的运行级别runlevel。查看日志使用journalctl -b查看本次启动的所有日志过滤weston相关的错误信息。手动测试尝试在TTY终端如CtrlAltF2手动启动Westonweston --backenddrm-backend.so --tty7看是否能成功。如果手动可以但自动不行问题很可能出在systemd服务文件的环境变量或依赖配置上。折腾RK3568的双屏同显就像在搭一个精密的积木。硬件连线设备树是地基显示服务Weston是图纸任何一个环节出点小差错大楼就盖不起来。整个过程最磨人的不是步骤多而是出错时的那一片漆黑和不知所云的日志。我的经验是一定要分步验证从硬件到内核再到用户空间一层一层地确认。先保证单屏能亮再折腾第二块屏的设备树最后才去修改Weston配置。多用dmesg、modetest和/sys/class/drm/这些调试工具它们给出的信息比瞎猜靠谱得多。一旦调通看着两块屏幕同步亮起那种成就感还是挺足的。这套方法不仅适用于同显稍加改动就能玩转异显、旋转、混合输出把RK3568的显示潜力充分榨出来。