tag 标签: wayland

相关博文
  • 热度 6
    2020-11-20 09:39
    3247 次阅读|
    0 个评论
    By Toradex 秦海 1). 简介 嵌入式平台多屏显示是比较常见的功能,在 NXP iMX6 上面,由于使用了基于 fbdev/X11 的显示接口驱动和显示服务,可以比较方便的通过 framebuffer 方式来实现多屏显示, Qt 也提供了想 eglfs 或者 linuxfs 这样的组件来对接。而基于 NXP 新的 iMX8 平台,由于使用了 DRM/KMS 显示接口驱动和 Wayland 显示服务,多屏显示的实现思路可能有如下几种,而本文就演示基于 Qtwayland 组件来实现双屏独立显示。 ./ 通过底层 IPU 驱动来实现,主要可以比较灵活的实现如 clone 模式等,但难度比较大,需要对 iMX8 底层 IPU 驱动有比较深入的了解 ./ 如果是通过 iMX8 双通道 LVDS ,连接两个单通道的 LVDS 屏幕,可以通过 device tree ldb 节点 ”dual-mode” 来实现 clone 显示 ./ iMX8 默认的 wayland/Weston compositor 默认支持多屏扩展模式显示,但是 9.0 以下版本无法对应用程序窗口进行定位, 9.0 以后引入了 Kiosk shell 支持,则可以通过应用程序窗口定位到不同屏幕实现多屏独立显示的效果 ./ 使用 Qtwayland 组件构建 wayland compositor ,可以方便的实现多屏独立显示,在多屏都是同样分辨率前提下,也可以实现 clone 显示 本文所使用的 ARM 嵌入式平台来自于 Toradex 基于 NXP 最新的 iMX8 SoC (基于 Cortex-A72+A53 和 Coretex-M4 架构)的 ARM 计算机模块 Apalis iMX8QM 4GB WB IT 。 2). 准备 a).Apalis iMX8QM4GB WB IT ARM 核心版配合 Ioxra 载板 ,连接调试串口 UART1 (载板 X22 )到开发主机方便调试。 b). Apalis iMX8 支持 HDMI 和 LVDS 显示接口,分别连接如下两个屏幕 ./ 13.3 inch HDMI panel 显示屏,分辨率 1920x1080 ,支持 USB 接口电容式触摸,将触摸接口连接到 Ixora 载板 USB 接口 ./ 10.1 inchLVDS 显示屏 ,分辨率 1280x800 ,支持 I2C 接口电容式触摸,将触摸接口连接到 Ixora 载板 X24 连接器 c). USB UVC 标准摄像头连接到 Ixora 载板用于 Gstreamer 测试 3). Apalis iMX8 Ycoto Linux 编译部署以及配置 a). Apalis iMX8 Ycoto Linux 通过 Ycoto/Openembedded 框架编译,具体的配置方法请参考 这里 ,参考如下修改后编译 Reference-Multimedia image 镜像 ------------------------------- # local.conf ,增加 eglfs 和 kms 支持 + PACKAGECONFIG_append_pn-qtbase = " sql-sqlite eglfs kms" + PACKAGECONFIG_append_pn-qtmultimedia = " gstreamer" + ACCEPT_FSL_EULA = "1" # layers/meta-toradex-demos/recipes-images/images/tdx-reference-multimedia-image.bb ,增加 SDK populate + inherit populate_sdk populate_sdk_qt5 # compile Reference-Multimedia image $ bitbake bitbake tdx-reference-multimedia-image # compile SDK bitbake tdx-reference-multimedia-image -c populate_sdk ------------------------------- b). Ycoto Linux image 部署 参考 这里 通过 Toradex Easy installer 将上面编译好的 image 更新部署到模块,版本为目前最新的 Ycoto Linux V5.1 c). 显示配置 ./ HDMI 默认即可正常显示,如果有显示器 EDID 读取问题不能成功显示,可以通过下面方法通过软件 firmware 方式手动加载 EDID ,更多关于显示的配置请参考 这里 ------------------------------- # cp EDID binary file to rootfs $ mkdir /lib/firmware/edid $ cp 1920x1080.bin /lib/firmware/edid # set uboot kernel command line # setenv defargs ‘pci=nomsi drm.edid_firmware=HDMI-A-1:edid/1920x1080.bin’ # saveenv && reset ------------------------------- ./ LVDS 显示, Ycoto Linux V5.1 默认 device tree 下 LVDS 是 disable 的,需要通过下面方式加载对应 device tree overlay 来 enable , device tree overlay 的更多说明请参考 这里 ------------------------------- # overlay files path root@apalis-imx8:~# ls /media/mmcblk0p1/overlays/ apalis-imx8_atmel-mxt_overlay.dtbo apalis-imx8x_parallel-rgb_overlay.dtbo apalis-imx8_lvds_overlay.dtbo display-edt5.7_overlay.dtbo apalis-imx8x_ad7879_overlay.dtbo display-edt7_overlay.dtbo apalis-imx8x_atmel-mxt_overlay.dtbo display-fullhd_overlay.dtbo apalis-imx8x_display-lt161010_overlay.dtbo display-lt161010_overlay.dtbo apalis-imx8x_display-lt170410_overlay.dtbo display-lt170410_overlay.dtbo # add lvds and i2c touch(atmel) related overlay file to /media/mmcblk0p1/overlays.txt fdt_overlays=overlays/apalis-imx8_lvds_overlay.dtbo overlays/display-lt170410_overlay.dtbo overlays/apalis-imx8_atmel-mxt_overlay.dtbo ------------------------------- ./ 触摸设备测试,通过 ”evetst” 命令 ------------------------------- # list all devices root@apalis-imx8:~# evtest No device specified, trying to scan all of /dev/input/event* Available devices: /dev/input/event0: sc-powerkey /dev/input/event1: gpio-keys /dev/input/event2: HID 27c0:0818 /dev/input/event3: USB 2.0 Camera: HD USB Camera /dev/input/event4: Atmel maXTouch Touchscreen # from above output ./ event2 is HDMI display USB HID capacitive touch device ./ event4 is LVDS display I2C capacitive touch device ------------------------------- 4). Qtwayland compositor 编译部署 a). Qt Qtwayland 组件可以非常方便的使用 QML 语言开发定制化的 wayland compositor ,详细说明请见 这里 ,也提供了很多 sample project 供参考 b). 本文测试所使用的 qtwayland compositor 来自于 Toradex Europe FAE Stefan Eichenberger ,源代码请参考 这里 ,这是一个用于双屏显示的 qtwayland compositor c). 参考 这里 说明使用上面章节 3.a 编译出的 SDK 文件配置 qtcreator 交叉编译环境,下载 dual-screen qtwayland compositor 代码后进行编译,生成 dual-screen 可执行二进制文件上传到 Apalis iMX8 系统中 d). 使用编译好的 dual-screen qtwayland compositor 替换系统默认的 weston compositor ./ 创建 dual-screen.sh 执行脚本文件 ------------------------------- # copy dual-screen binary to /usr/bin $ cp dual-screen /usr/bin/ # create dual-screen.sh script, detailed content in below $ vi /usr/bin/dual-screen.sh # add executable permission $ chmod +x dual-screen.sh ------------------------------- ./ dual-screen.sh – 由于系统包含三个 input 设备,两个触摸设备和一个 USB 摄像头,在启动过程中,其对应的 event 号码可能会变化,因此脚本前面先对 “kms.conf” 文件里面的设置和系统启动后的设备 event 进行比对,如果一致则直接启动 compositor ,如不一致则需要先修改 ”kms.conf” 文件后再启动 compositor 。这里使用的 ts0/ts1 symbol 链接则是在下面 udev rule 文件中定义的。 ------------------------------- # get system touch device event number while do sleep 0.1 done ts0=$(readlink /dev/input/ts0) while do sleep 0.1 done ts1=$(readlink /dev/input/ts1) # compare with kms.conf settings while do sleep 0.1 done ts_hdmi=$(sed -n 8p /etc/kms.conf|cut -d '"' -f4|cut -d '/' -f4) ts_lvds=$(sed -n 13p /etc/kms.conf|cut -d '"' -f4|cut -d '/' -f4) # modify kms.conf if seetings is not consistent with system event if ;then sed -i "8 s/event.*/$ts0\"\,/g" /etc/kms.conf fi if ;then sed -i "13 s/event.*/$ts1\"\,/g" /etc/kms.conf fi # execute qtwayland compositor /usr/bin/dual-screen & ------------------------------- ./ 创建 systemd service 文件 ------------------------------- # /lib/systemd/system/qtwayland@.service Description=Qt Wayland Compositor RequiresMountsFor=/run Conflicts=plymouth-quit.service After=systemd-user-sessions.service plymouth-quit-wait.service User=%i PAMName=login Environment="QT_QPA_EGLFS_KMS_CONFIG=/etc/kms.conf" Environment="QT_QPA_EGLFS_INTEGRATION=eglfs_kms" Environment="QT_QPA_PLATFORM=eglfs" Environment="QT_QPA_EGLFS_KMS_ATOMIC=1" Environment="QT_QPA_EGLFS_NO_LIBINPUT=1" StandardError=journal PermissionsStartOnly=true IgnoreSIGPIPE=no ExecStart=/usr/bin/dual-screen.sh # 通过 /etc/kms.conf 文件来配置 KMS 显示接口设备, ”touchDevice” 参数对应 3.c 章节中测试的 event ,更多关于 Qt eglfs DRM/KMS 的配置说明请参考 这里 。 $ vi /etc/kms.conf { "device": "/dev/dri/card0", "hwcursor": true, "pbuffers": false, "outputs": } ------------------------------- ./ 创建新的 udev rule 替换系统默认的 weston udev rule ------------------------------- # remove default weston udev rule $ rm /etc/udev/rules.d/71-weston-drm.rules # add qtwayland rule $ vi /etc/udev/rules.d/71-qtwayland-drm.rules # connect HDMI HID touchscreen and LVDS I2C touchscreen with fix symlink SUBSYSTEM=="input" KERNEL=="event*" ATTRS{name} =="HID 27c0:0818", SYMLINK+="input/ts0" SUBSYSTEM=="input" KERNEL=="event*" ATTRS{name} =="Atmel maXTouch Touchscreen", SYMLINK+="input/ts1 # start qtwayland compositor ACTION=="add", SUBSYSTEM=="graphics", KERNEL=="fb0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="qtwayland@root.service" ACTION=="add", SUBSYSTEM=="drm", KERNEL=="card0", TAG+="systemd", ENV{SYSTEMD_WANTS}+="qtwayland@root.service" ------------------------------- e). 测试 qtwayland compositor ------------------------------- # disable default wayland qt demo app systemd service $ systemctl disable wayland-app-launch $ reboot ------------------------------- 重启后,可以看到下面双屏显示结果, qtwayland compositor 启动成功 5). Gstreamer 测试 a). 分别运行两个 gstreamer pipeline ,然后 qtwayland compositor 会将第一个运行的 pipeline 显示在 HDMI 显示器上面,第二个运行的显示在 LVDS 显示器上面 b). Gstreamer pipeline 1 - USB 摄像头播放,关于 gstreamer 使用的更多说明请参考 这里 ------------------------------- $ gst-launch-1.0 v4l2src device=/dev/video2 ! 'image/jpeg,width=1920,height=1080,frame rate=30/1' ! jpegdec ! videoconvert ! waylandsink fullscreen=1 sync=false & ------------------------------- c). Gstreamer pipeline 2 – gstreamer 测试 pipeline ------------------------------- $ gst-launch-1.0 videotestsrc ! waylandsink fullscreen=1 ------------------------------- d). 实际运行效果如下 6). Qt 应用测试 a). 分别使用一个 Qt Widget 应用和一个 Qt Quick 应用进行测试 ./ Qt Widget 应用 – 读取系统时间和 CPU 温度,同时调用 sqlite 数据库进行保存的应用,详细说明请参考 这里 ,将编译好的可执行 binary “qt-sqlite” 上传到 Apalis iMX8 ./ Qt Quick 应用 – 调用 qtmultimedia 组件播放视频以及摄像头,详细说明请参考 这里 ,将编译好的可执行 binary “videotest” 上传到 Apalis iMX8 b). 创建应用启动脚本 ------------------------------- $ vi /usr/bin/qtwayland-app-launch.sh #!/bin/sh if test -z "$XDG_RUNTIME_DIR"; then export XDG_RUNTIME_DIR=/run/user/`id -u` if ! test -d "$XDG_RUNTIME_DIR"; then mkdir --parents $XDG_RUNTIME_DIR chmod 0700 $XDG_RUNTIME_DIR fi fi # wait for qtwayland while ; do sleep 0.1; done sleep 1 /home/root/videotest -url file:///home/root/ready-player-one-trailer-2_h720p.mov & sleep 1 /home/root/qt-sqlite & ------------------------------- c). 创建开机自启动 systemd service 文件 ------------------------------- $ vi /lib/systemd/system/qtwayland-app-launch.service Description=Start a Qt wayland application After=qtwayland@root.service Requires=qtwayland@root.service Restart=on-failure Type=forking Environment="QT_QPA_PLATFORM=wayland" ExecStart=/usr/bin/qtwayland-app-launch.sh RestartSec=1 WantedBy=multi-user.target ------------------------------- d). enable service 并测试 ------------------------------- $ systemctl enable qtwayland-app-launch $ reboot ------------------------------- e). 重启后效果如下,两个屏幕的触摸都可以分别正常使用 5). 总结 本文在 iMX8 嵌入式平台下使用 Qtwayland 工具测试了 HDMI/LVDS 双屏独立显示功能。 参考文档 https://developer.toradex.cn/knowledge-base/display-output-resolution-and-timings-linux https://doc.qt.io/qt-5/embedded-linux.html#embedded-eglfs https://github.com/eichenberger/qt-dual-screen-compositor