如有错误,欢迎批评指正!!!
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 - 覆盖屏幕的颜 {MOD}深度。在framebuffer设备/ dev / fb0不可用或查询不成功的平台上,使用默认值32。此变量可用于覆盖任何此类默认值。请注意,这仅影响由QScreen报告的颜 {MOD}深度值。它没有连接到EGL配置和用于OpenGL渲染的颜 {MOD}深度。
QT_QPA_EGLFS_SWAPINTERVAL - 默认情况下,将请求交换间隔为1。这使得能够同步到显示垂直刷新。该值可以使用此环境变量覆盖。例如,传递0将禁用交换时的阻塞,导致尽可能快地运行,而不进行任何同步。
QT_QPA_EGLFS_FORCEVSYNC - 设置时,eglfs在帧缓冲设备上请求FBIO_WAITFORVSYNC。
QT_QPA_EGLFS_FORCE888 - 设置时,创建新的上下文,窗口或屏幕外表面时,将忽略红 {MOD},绿 {MOD}和蓝 {MOD}通道大小。相反,插件请求每个通道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=x :指定屏幕的像素大小。插件试图查询的帧缓冲设备物理和逻辑尺寸。然而,这可能并不总是导致正确的结果,因此可能需要显式指定值.。
mmsize=x:毫米的物理宽高
offset=x :偏移量,左上角(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