[Qt配置指南—5]Qt 5.4.2 Configure Options---Qt for Embeded Linux嵌入式Linux

来源:互联网 发布:仓库 厂房 地坪漆 知乎 编辑:程序博客网 时间:2024/05/23 19:15

如有错误,欢迎批评指正!!!


Qt for Embeded Linux


这里着重讨,http://doc.qt.io/qt-5/embedded-linux.html

自Qt 5.0发布以来,Qt不再包含自己的窗口系统(QWS)实现。 对于单进程用例,Qt Platform Abstraction是一个优秀的解决方案。 Wayland可以支持多个图形进程。

有多个平台插件可以在嵌入式Linux系统上使用:EGLFS,LinuxFB,KMS,DirectFB,Wayland。 这些的可用性取决于Qt的配置。 默认平台插件也是特定于设备的。 例如,在许多板上,选择eglfs作为默认板。 如果默认值不合适,则可以使用QT_QPA_PLATFORM环境变量参数来请求另一个插件。 或者,对于快速测试,-platform命令行可以使用相同的语法。


一、配置特定设备

为给定设备构建Qt需要一个工具链和一个sysroot。此外,一些设备需要针对EGL和OpenGL ES 2.0支持的供应商特定的适配代码。这与非加速平台不相关,例如使用LinuxFB插件的平台,这只适用于基于软件的渲染。这意味着Qt Quick 2在这样的设置中不起作用,因为它依赖于OpenGL进行渲染。

目录qtbase / mkspecs / devices包含多个设备的配置和图形适配代码。例如,linux-rasp-pi2-g ++ mkspec包含构建设置,例如Raspberry Pi 2设备的最佳编译器和链接器标志。 mkspec还包含关于eglfs钩子(供应商特定的适配代码)的实现或者对适当的eglfs设备集成插件的引用的信息。通过配置工具的-device参数选择设备。此参数后面的名称必须至少部分匹配设备下的其中一个子目录。

以下是Raspberry Pi 2的示例配置。对于大多数嵌入式Linux板,configure命令看起来类似:

./configure -release             -opengl es2             -device linux-rasp-pi2-g++             -device-option CROSS_COMPILE=$TOOLCHAIN/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-             -sysroot $ROOTFS             -prefix /usr/local/qt5


最重要的参数是-device和-sysroot。通过指定-sysroot,configure的特性检测测试使用的包含文件和库以及Qt本身从指定位置获取,而不是从主机PC的标准位置获取。这意味着在主机上安装开发包没有意义。例如,要获得libinput支持,在主机环境中安装libinput开发头和库是不够的或不必要的。相反,目标体系结构的头和库(例如ARM)必须存在于sysroot中。

在执行交叉编译时也支持pkg-config。 configure会自动设置PKG_CONFIG_LIBDIR以使pkg-config报告编译器和链接器设置基于sysroot而不是主机。这通常功能很好,没有任何进一步的调整。但是,在运行configure之前,必须为主机取消设置环境变量(如PKG_CONFIG_PATH)。否则,Qt构建可能尝试使用来自主机系统的不适当的标头和库。

指定-sysroot会导致在调用编译器时自动设置--sysroot参数。在某些情况下,这是不可取的,可以通过传递-no-gcc-sysroot来禁用配置。

-prefix,-extprefix和-hostprefix控制Qt构建的预期目标目录。在上面的例子中,Qt的ARM构建预计放在目标设备上的/ usr / local / qt5中。请注意,运行make install不会向设备部署任何内容。相反,安装步骤的目标是由extprefix指定的目录,默认为sysroot +前缀,因此是可选的。然而,在许多情况下,“污染”sysroot是不可取的,因此指定-extprefix变得重要。最后,-hostprefix允许从目标的二进制文件中分离主机工具,如qmake,rcc,uic。当给定时,这些工具将安装在指定的目录而不是extprefix。


二、嵌入式Linux设备的平台插件(Platform Plugins for Embedded Linux Devices)

EGLFS:

EGL是OpenGL和本地窗口系统之间的接口。 Qt可以使用EGL进行上下文和表面管理,但是API不包含平台特定:创建本地窗口(这不一定是屏幕上的实际窗口)仍然必须通过平台特定的方法来完成。 因此需要板或GPU特定的适配代码。 这样的适配或者作为eglfs钩提供,其可以是编译到平台插件中的单个源文件,或者作为动态加载的EGL设备集成插件。

EGLFS是一个平台插件,用于在没有实际窗口系统(如X11或Wayland)的EGL和OpenGL ES 2.0之上运行Qt5应用程序。 除了Qt Quick 2和原生OpenGL应用程序,它还支持软件渲染窗口(例如QWidget)。 在后一种情况下,小部件的内容使用CPU呈现为图像,然后上传到纹理并由插件合成。


这在支持GPU的嵌入式设备中鼓励使用。


EGLFS强制第一个顶级窗口(无论是QWidget或QQuickView)成为全屏。此窗口也被选择为根窗口小部件窗口,其中所有其他顶级窗口小部件(例如对话框,弹出菜单或组合框下拉列表)被合成。这是必要的,因为使用EGLFS总是有一个本地窗口和EGL窗口表面,这些属于首先创建的窗口部件或窗口。当主窗口存在于应用程序的整个生命周期中,并且所有其他窗口小部件都是非顶级窗口或者在显示主窗口之后创建时,这种方法工作得很好。

基于OpenGL的窗口还有其他限制。从Qt 5.3开始,eglfs支持单个全屏GL窗口(例如,基于OpenGL的QWindow,QQuickView或QGLWidget)。不支持打开其他OpenGL窗口或将这些窗口与基于QWidget的内容混合,并且会以错误消息终止应用程序。

如果需要,可以使用以下环境变量配置eglfs:

QT_QPA_EGLFS_FB - 覆盖帧缓冲设备。默认值为/ dev / fb0。在大多数嵌入式平台上,这不是很相关,因为framebuffer仅用于查询设置,如显示维度。但在某些设备上,此参数提供了指定在多个显示设置中使用的显示的能力,类似于LinuxFB中的fb参数。

QT_QPA_EGLFS_WIDTH和QT_QPA_EGLFS_HEIGHT - 包含屏幕宽度和高度(以像素为单位)。虽然eglfs尝试从帧缓冲设备/ dev / fb0确定维度,但这不总是工作,手动指定大小可能变得必要。

QT_QPA_EGLFS_PHYSICAL_WIDTH和QT_QPA_EGLFS_PHYSICAL_HEIGHT - 物理屏幕宽度和高度(以毫米为单位)。在帧缓冲设备/ dev / fb0不可用或查询不成功的平台上,基于默认DPI为100计算值。此变量可用于覆盖任何此类默认值。

QT_QPA_EGLFS_DEPTH - 覆盖屏幕的颜色深度。在framebuffer设备/ dev / fb0不可用或查询不成功的平台上,使用默认值32。此变量可用于覆盖任何此类默认值。请注意,这仅影响由QScreen报告的颜色深度值。它没有连接到EGL配置和用于OpenGL渲染的颜色深度。

QT_QPA_EGLFS_SWAPINTERVAL - 默认情况下,将请求交换间隔为1。这使得能够同步到显示垂直刷新。该值可以使用此环境变量覆盖。例如,传递0将禁用交换时的阻塞,导致尽可能快地运行,而不进行任何同步。

QT_QPA_EGLFS_FORCEVSYNC - 设置时,eglfs在帧缓冲设备上请求FBIO_WAITFORVSYNC。

QT_QPA_EGLFS_FORCE888 - 设置时,创建新的上下文,窗口或屏幕外表面时,将忽略红色,绿色和蓝色通道大小。相反,插件请求每个通道8位的配置。这在默认选择每像素小于32或24位的配置但已知不适合的设备上是有用的,例如由于带状效应。而不是更改所有应用程序,此变量提供了一个更容易的快捷方式强制24/32 bpp配置的给定设备。

QT_QPA_EGLFS_DEBUG - 设置时,在调试输出上将打印一些调试信息。例如,输入QSurfaceFormat和所选EGL配置的属性在创建新上下文时打印。与Qt Quick的QSG_INFO变量一起,这可以为与EGL配置相关的故障排除提供有用的信息。

QT_QPA_EGLFS_INTEGRATION - 除了编译的钩子之外,还可以以动态加载的插件的形式提供设备或供应商特定的适配。此环境变量强制执行特定的插件。例如,将其设置为eglfs_kms将使用KMS / DRM后端。这只是一个选项,当没有在设备makepecs中指定静态或编译的钩子。在实践中,传统的编译钩子很少使用,几乎所有后端都迁移到插件。设备仍然包含相关的EGLFS_DEVICE_INTEGRATION条目:该特定设备的首选后端的名称。这是可选的,但是非常有用,以避免在目标系统中存在多个插件的情况下设置此环境变量。在桌面环境中,根据DISPLAY环境变量的存在,KMS或X11后端具有优先级。注意,在一些板上使用none的特殊值而不是实际的插件。这表明不需要特殊的集成来使用EGL与帧缓冲区,因此不必加载插件。


LinuxFB:

直接写入到帧缓冲,仅支持软件渲染。

允许指定附加设置通过传递QT_QPA_PLATFORM环境变量或者-platform命令行选项。如:

QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1指定帧缓冲设备/dev/fb1而不是fb0。

fb=/dev/fbN :指定的帧缓冲设备。多个显示设置,这通常允许在不同的显示器上显示应用程序。暂时没有办法使用来自一个Qt应用程序的多个帧缓存。

size=<width>x<height> :指定屏幕的像素大小。插件试图查询的帧缓冲设备物理和逻辑尺寸。然而,这可能并不总是导致正确的结果,因此可能需要显式指定值.。

mmsize=<width>x<height>:毫米的物理宽高

offset=<width>x<height> :偏移量,左上角(0,0)

nographicsmodeswitch:不切换虚拟终端到图形模式。如果在图形模式,闪烁光标和屏幕消隐通常禁用。当设置此参数时,这些参数也会被跳过.。

tty=/dev/ttyN:重写虚拟控制台。仅在nographicsmodeswitch未设置时生效。


Input:

在目前没有窗口的系统中,鼠标、键盘、触摸设备通过evdev或者使用帮助库如lininput或者tslib直接获取数据。注意,设备节点/dev/input/event*能够被用户可读。eglfs和Linuxfb包含所有的输入处理代码。


使用libinput

libinput是一个能够处理输入设备的库。能够提供可替换Qt自己的evdev功能。为了使用该功能,需要Qt配置时使能libudev和lininput。键盘支持需要xkbcommon。在使用EGLFS和LinuxFB是,默认包含。如果libinput不可用或者QT_QPA_EGLFS_NO_LIBINPUT被设置,使用Qt再带evdev处理。


输入使用EGLFS和linuxFB,不使用lininput

设备节点名被设置在环境变量:QT_QPA_EVDEV_MOUSE_PARAMETERS, QT_QPA_EVDEV_KEYBOARD_PARAMETERS and QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS。同样內建输入处理可以禁用,设置QT_QPA_EGLFS_DISABLE_INPUT or QT_QPA_FB_DISABLE_INPUT 置为1。在某些触摸屏上,坐标必须旋转,通过设置QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS to rotate=180。


鼠标Mouse

鼠标光标的出现不论QT_QPA_EGLFS_HIDECURSOR (for eglfs) or QT_QPA_FB_HIDECURSOR (for linuxfb)有没有被设置,基于libudev的Qt总是报告至少一个鼠标可用。当libudev不支持时,除非明确通过环境变量关闭显示,否则鼠标一直出现。

热插拔仅在Qt配置libudev时生效。在应用运行时可连接断开设备。


键盘Keyboard

evdev键盘处理支持额外参数。

/dev/input/...:指定输入设备名,否则通过libudev或者查找所用可用节点。

grap:使能捕获输入设备。

keymap:指定用户键盘文件名。

enable-compose:使能合成。

repeat-delay:设置用户键重复延时。

repeat-rate:设置用户键重复速度。


在没有禁用其终端会话的嵌入式Linux系统上,按键上的行为可能会引起混乱,因为输入事件由Qt应用程序和tty处理。 为了克服这个问题,可以使用以下选项:

        EGLFS和LinuxFB试图通过将tty的键盘模式设置为K_OFF来禁用应用程序启动时的终端键盘。这可以防止击键进入终端。如果由于某种原因需要恢复标准行为,请将环境变量QT_QPA_ENABLE_TERMINAL_KEYBOARD设置为1。请注意,这只有在从远程控制台启动应用程序(例如,通过ssh)并且终端键盘输入保持启用时才有效。

        另一种方法是通过在QT_QPA_EVDEV_KEYBOARD_PARAMETERS中传递grab = 1来使用evdev键盘处理程序的grab参数。这导致试图在输入设备上抓取。如果抓取成功,则只要Qt应用程序正在运行,系统中的其他组件都不会从中接收事件。这种方法更适合远程启动的应用程序,因为它不需要访问tty设备。

        最后,对于许多专门的嵌入式Linux映像,首先启用标准终端会话没有意义。有关如何禁用它们,请参阅构建环境的文档。例如,当使用Yocto项目生成图像时,取消设置SYSVINIT_ENABLED_GETTYS导致在任何虚拟终端上没有运行getty进程,因此没有输入。


如果默认的内置键盘映射不够,可以通过keymap参数或使用eglfs特定的loadKeymap()函数指定一个不同的键盘映射。后者允许在运行时切换键映射。注意,这需要使用eglfs的内置键盘处理程序; 当通过-plugin命令行参数加载键盘处理程序时,不支持。


注意:特殊系统组合键(例如控制台切换(Ctrl + Alt + Fx)或zap(Ctrl + Alt + Backspace))目前不受支持,并被忽略。


要生成自定义键映射,可以使用kmap2qmap实用程序。 这可以在qttools模块中找到。源文件必须是标准的Linux kmap格式,这是内核的loadkeys命令理解的。这意味着可以使用以下源生成qmap文件:

        Linux控制台工具(LCT)项目。
        Xorg X11键映射可以使用ckbcomp实用程序转换为kmap格式。
        由于kmap文件是纯文本文件,它们也可以手工制作。


kmap2qmap是一个命令行程序,需要至少2个文件作为参数。 最后一个是生成的.qmap文件,而所有其他都被解析为输入.kmap文件。 例如:

kmap2qmap i386/qwertz/de-latin1-nodeadkeys.kmap include/compose.latin1.inc de-latin1-nodeadkeys.qmap


注意:kmap2qmap不支持Linux内核支持的所有(伪)符号。 当转换标准键盘映射时,将显示有关Show_Registers,Hex_A等的多个警告; 这些消息可以安全地忽略。


触摸屏

对于一些电阻式,单点触摸触摸屏,可能需要回退到使用tslib,而不是依赖于Linux多点触摸协议和事件设备。 对于现代触摸屏这不是必要的。 可以通过将环境变量QT_QPA_EGLFS_TSLIB或QT_QPA_FB_TSLIB设置为1来启用tslib支持。要更改设备,请在命令行中设置环境变量TSLIB_TSDEVICE或传递设备名称。 注意,tslib输入处理程序生成鼠标事件并支持单一触摸,而evdevtouch也生成真正的多点触摸QTouchEvent事件。


平板电脑

evdevtablet插件提供了对Wacom和类似的基于笔的平板电脑的基本支持。 它仅生成QTabletEvent事件。 要启用它,请在环境中传递QT_QPA_GENERIC_PLUGINS = evdevtablet,或者在命令行上传递-plugin evdevtablet参数。 如果Qt的自动设备发现(基于libudev或/ dev / input / event *的演练)不起作用或行为不端,则插件可以获取设备节点参数,例如QT_QPA_GENERIC_PLUGINS = evdevtablet:/ dev / event1。


调试输入设备
通过启用qt.qpa.input日志记录规则,例如通过将QT_LOGGING_RULES环境变量设置为qt.qpa.input = true,可以将一些信息打印到调试输出。 这对于检测正在使用的设备或对设备发现问题进行故障排除非常有用。


使用自定义鼠标光标图像

eglfs自带了一组32x32大小的鼠标光标图像。 如果这些不足够,可以通过将QT_QPA_EGLFS_CURSOR环境变量设置为JSON文件的名称来提供自定义光标集。 该文件还可以通过Qt的资源系统嵌入到应用程序中。

例如,可以如下指定每行具有8个光标图像的嵌入光标图集:

{  "image": ":/cursor-atlas.png",  "cursorsPerRow": 8,  "hotSpots": [      [7, 2],      [12, 3],      [12, 12],      ...  ]}


请注意,图像应在图集中紧密包装:光标的宽度和高度根据总图像大小和cursorPerRow设置决定。 Atlases必须为所有支持的光标提供一个图像。


显示输出:

当连接多个显示器时,从一个单一Qt应用程序中定向其中一个或多个的支持级别在平台插件之间不同,并且通常取决于设备及其图形堆栈。


eglfs与eglfs_kms后端

当KMS / DRM后端正在使用时,eglfs报告QGuiApplication :: screens()中的所有可用屏幕。 应用程序可以通过QWindow :: setScreen()以不同的窗口定位不同的屏幕。 请注意,每个屏幕的一个单个全屏窗口的限制仍然适用。

当开始在给定的嵌入式设备上开发时,通常需要验证设备和驱动程序的行为,并且连接的显示器正常工作。 一个简单的方法是使用hellowindow示例。 使用-platform eglfs --multiscreen --timeout参数启动它会在每个连接的屏幕上显示一个旋转的Qt徽标几秒钟。

KMS / DRM后端还支持通过JSON文件的自定义配置。 将环境变量QT_QPA_EGLFS_KMS_CONFIG设置为文件的名称以启用此功能。 该文件还可以通过Qt资源系统嵌入到应用程序中。 示例配置如下:

{  "device": "/dev/dri/card1",  "hwcursor": false,  "pbuffers": true,  "outputs": [    {      "name": "VGA1",      "mode": "off"    },    {      "name": "HDMI1",      "mode": "1024x768"    }  ]}


这里我们配置指定的设备

它不会使用硬件光标(回退到通过OpenGL渲染鼠标光标;默认硬件光标被启用,因为它们更有效率)
它将使用标准EGL pbuffer表面(默认情况下禁用此选项并使用gbm表面)来回退QOffscreenSurface,
VGA接口上的输出被禁用,而HDMI被激活,分辨率为1024x768。
此外,这样的配置还禁用通过libudev查找设备,而是使用指定的设备。

对于故障排除,从KMS / DRM后端启用调试日志可能很有用。 为此,请启用分类日志记录规则qt.qpa.eglfs.kms。


eglfs与eglfs_kms_egldevice后端

通常在Tegra设备上使用的此后端类似于上述KMS / DRM后端,除了它依赖于EGLDevice和EGLStream扩展而不是GBM。

有关此方法的技术细节,请查看此演示文稿。

从Qt 5.7开始,这个后端与基于GBM的后端共享其许多内部实现。这意味着支持多个屏幕和通过QT_QPA_EGLFS_KMS_CONFIG的高级配置。但是,某些设置(如硬件光标)可能不适用。

默认情况下,后端将找到第一个可用的显示并选择与之对应的EGL层。必要时,可以通过将QT_QPA_EGLFS_LAYER_INDEX环境变量设置为所需图层的索引来覆盖。要查看哪些层可用,并调试潜在的启动问题,请启用日志记录类别qt.qpa.eglfs.kms。在一些情况下,即使当屏幕报告已经设置了期望的分辨率时,可能有必要执行在应用启动时设置的视频模式。这通常是优化的,但如果屏幕保持关闭,请尝试将环境变量QT_QPA_EGLFS_ALWAYS_SET_MODE设置为非零值,然后重新启动应用程序。


eglfs与其他后端

通常基于直接经由供应商的EGL实现来定向帧缓冲器或组合API的其他后端通常提供对多个显示器的有限或不支持。 在基于i.MX6的具有Vivante GPU的板上,QT_QPA_EGLFS_FB环境变量可用于指定要缓冲的帧缓冲区,类似于linuxfb。 在Raspberry Pi上,QT_QPA_EGLFS_DISPMANX_ID环境变量可用于指定要输出的屏幕。 该值对应于DISPMANX_ID_常量之一,请参阅Dispmanx文档。 注意,与KMS / DRM不同,这些方法通常将不允许从相同应用输出到多个屏幕。 或者,也可以使用驱动程序特定的环境变量或内核参数来控制所使用的帧缓冲区。 请参考嵌入式开发板的文档。


视频内存:

具有固定数量的专用视频内存的系统在运行基于Qt Quick的Qt应用程序或类似QOpenGLWidget之类的类之前可能需要特别小心。 默认设置可能不足以用于这样的应用,特别是当它们在高分辨率(例如,全高清)屏幕上显示时。 在这种情况下,他们可能以意想不到的方式开始失败。 建议确保至少有128 MB的GPU内存可用。 对于没有为GPU保留的固定内存量的系统,这不是一个问题。

linuxfb

使用fb plugin参数指定要使用的帧缓冲设备。


Unix信号处理程序:

面向控制台的平台插件如eglfs和linuxfb默认安装信号处理程序来捕获中断(SIGINT),挂起和继续(SIGTSTP,SIGCONT)和终止(SIGTERM)。这样,当应用程序由于kill或Ctrl + C或Ctrl + Z而终止或暂停时,可以恢复键盘,终端光标以及可能的其他图形状态。 (尽管只有在设置了QT_QPA_ENABLE_TERMINAL_KEYBOARD时,才能通过键盘终止或挂起,如上面输入部分所述)。然而,在一些情况下,捕获SIGINT可能是不期望的,因为它可能与例如远程调试冲突。因此,提供环境变量QT_QPA_NO_SIGNAL_HANDLER以选择退出所有内置信号处理。

字体:

Qt通常使用fontconfig来提供对系统字体的访问。如果fontconfig不可用,Qt将回退到使用QBasicFontDatabase。在这种情况下,Qt应用程序将在Qt的lib / fonts目录中查找字体。 Qt将自动检测预呈现的字体和TrueType字体。可以通过设置QT_QPA_FONTDIR环境变量来覆盖此目录。

有关支持的格式的详细信息,请参阅嵌入式Linux字体的Qt。

注意:Qt不再在lib / fonts目录中提供任何字体。这意味着由平台(系统映像)提供必要的字体。


嵌入式Linux设备上的窗口系统的平台插件:

XCB

这是在常规桌面Linux平台上使用的X11插件。在一些嵌入式环境中,提供X和xcb的必要开发文件,这个插件的功能就像在普通PC桌面上。

注意:在某些设备上,在X下没有EGL和OpenGL支持,因为EGL实现与Xlib不兼容。在这种情况下,XCB插件是在没有EGL支持的情况下构建的,这意味着Qt Quick 2或其他基于OpenGL的应用程序不能与此平台插件配合使用。它仍然可以用于运行软件渲染的应用程序(例如基于QWidget)。

作为一般规则,不建议在嵌入式设备上使用XCB。像eglfs的插件可能提供更好的性能和硬件加速。

Wayland

Wayland是一个轻量级的窗口系统;或者更精确地,它是用于客户端与显示服务器通信的协议。

Qt Wayland模块提供了一个wayland平台插件,允许Qt应用程序连接到Wayland合成器。

注意:在使用Weston参考合成器时,您可能会遇到触摸屏输入问题。有关更多信息,请参阅Qt Wiki。

0 0
原创粉丝点击