NXP iMX8基于Qtwayland配置双屏显示

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 iMX8QM 4GB WB IT ARM核心版配合Ioxra 载板,连接调试串口UART1(载板X22)到开发主机方便调试。


b). Apalis iMX8支持HDMI和LVDS显示接口,分别连接如下两个屏幕

./ 13.3 inch HDMI panel 显示屏,分辨率1920x1080,支持USB接口电容式触摸,将触摸接口连接到Ixora 载板USB接口

./ 10.1 inch LVDS 显示屏,分辨率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 [ ! -e /dev/input/ts0 ]

do

sleep 0.1

done

ts0=$(readlink /dev/input/ts0)


while [ ! -e /dev/input/ts1 ]

do

sleep 0.1

done

ts1=$(readlink /dev/input/ts1)


# compare with kms.conf settings

while [ ! -e /etc/kms.conf ]

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 [ "$ts_hdmi"!="$ts0" ];then

sed -i "8 s/event.*/$ts0\"\,/g" /etc/kms.conf

fi


if [ "$ts_lvds"!="$ts1" ];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

[Unit]

Description=Qt Wayland Compositor   

RequiresMountsFor=/run

Conflicts=plymouth-quit.service

After=systemd-user-sessions.service plymouth-quit-wait.service


[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": [

      { "name": "HDMI1",

        "mode": "1920x1080",

        "touchDevice": "/dev/input/event2",

        "virtualIndex": 0, "primary": true

      },

      { "name": "LVDS1",

        "mode": "1280x800",

        "touchDevice": "/dev/input/event4",

        "virtualIndex": 1

      }

  ]

}

-------------------------------

./ 创建新的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 [ ! -e  $XDG_RUNTIME_DIR/wayland-0 ] ; 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

[Unit]

Description=Start a Qt wayland application

After=qtwayland@root.service

Requires=qtwayland@root.service


[Service]

Restart=on-failure

Type=forking

Environment="QT_QPA_PLATFORM=wayland"

ExecStart=/usr/bin/qtwayland-app-launch.sh

RestartSec=1


[Install]

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 

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容