本文记录了QT4.8图形界面在全志A40I/T3 SDK平台上的移植过程,说明过程中可能会技术瑕疵,希望大家提供宝贵意见。
本文移植的平台来自于盈鹏飞嵌入式的CoM-X40I/T3A平台(处理器分别时是全志的A40I/T3)。
以下是盈鹏飞嵌入式CoM-X40I核心模块的简要介绍:
CoM-X40I产品特性:
采用Allwinner公司Cortex-A7四核A40i处理器,运行最高速度为1.2GHZ;
支持Mali-400MP2 GPU,支持OpenGL ES 2.0 / OpenVG 1.1 standard
支持1080P视频编码,支持H.264,VP8;多格式1080P 60fps视频解码 (H.265,H.264,VC-1, MPEG-1/2/4, VP8)
支持双屏异显;支持HDMI V1.4A/RGB888/LVDS,分辨率最高1920x1080;T3处理器不支持HDMI;
支持512-2G Bytes DDR3 SDRAM;
支持EMMC 4G-64G大容量电子盘,可启动;
支持SDIO3.0,USB2.0 HOST&OTG,2路I2C,6路UART,2路SPI,2路PWM
支持双路以太网,一路10/100M;一路10/100/1000M;
可定制宽温产品,替换AM335X
稳定的操作系统的支持,可预装Android7.0或者LINUX 3.10(可预装Preempt Linux系统);
超小体积,邮票孔设计160pins, 尺寸为:45*45MM
以下是以CoM-X40I为核心板主板-SBC-X40I的功能图:
以下为基于A40I/T3 SDK平台的QT4.8移植和应用开发连载(一)内容:
1 准备工作
本文适用于盈鹏飞嵌入式全志系列核心板系列产品,例如CoM-X40I/T3A,下面以CoM-X40I+SBC-X40I主板为例进行说明:
移植前的准备如下:
硬件资源:CoM-X40I+SBC-X40I主板
开发主机平台:X64+UBUNTU 16.04
qt源码: qt-everywhere-opensource-src-4.8.7.tar.gz(QT4的最后版本,已经包含在盈鹏飞嵌入式的SDK中)
触摸屏库:tslib1.4.tar.gz(已经包含在盈鹏飞嵌入式的SDK中)
交叉编译工具:gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf.tar.xz(已经包含在盈鹏飞嵌入式的SDK中)
1.1 CoM-X40I+SBC-X40I硬件的准备
主板供电12V电源,并通过KIT-CP2102转换板(USB-TO-UART)把计算机和主板的终端串口(CN9)连接起来,设置好KIT-CP2102的工作模式(特别注意要交叉连接,并设置KIT-CP2102N为usb转ttl模式):
注意: 因SBC-X40I的终端串口是LVTTL电平,所以务必通过KIT-CP2102的RXD/RXD/GND信号连接主板,否则终端串口会出现乱码。
KIT-CP2102的信号定义如下:KIT-CP2102设置为USB-2-TTL模式如下:
注意: 1)Status状态指示灯在正常工作时常亮;
2)TX发送指示灯和RX接收指示灯在正常收发时会闪动;
开始测试之前,如果是第一次使用Kit-CP2102转接板,需要去Silicon Labs官网下载此芯片对应的安装驱动CP210x USB to UART Bridge VCP Drivers - Silicon Labs (silabs.com),确保Kit-CP2102转接板连接到PC端,电脑能够正确识别到设备。打开设备管理器,确认KIT-CP2102所对应的COM端口号(如下图的KIT-CP2102的端口号是COM9,后续设置SecureCRT使用):
打开串口调试终端SecureCRT,选择对应的COM 端口号(本示例中为COM9),设置波特率为115200,8N无校验位。建立串口连接,如下图所示。
将Linux系统启动卡插入主板TF卡槽,将主板上电启动,系统将会自动登录root用户,串口终端会打印如下类似启动信息。
如果以上信息都正常(主板可正常上电,终端可正常输入指令),那么移植QT的硬件环境已经准备完毕。
1.2 全志A40I LINUX SDK简要介绍
以下是LinuxSDK 源码目录结构及说明:
在SDK下目录下有一个build.sh脚本,通过该脚本执行如下三步,即可编译出烧录的固件,这三步是:
(Host#表示主机命令提示符)
Host# ./build.sh config
Host# ./build.sh
Host# ./build.sh pack
这里要说明的是三点:
1.该SDK不需要单独装编译器或者设置编译器的环境变量。每次编译过程,都是临时配置编译器,而且编译过程中的环境变量也只针对当前终端有效,一旦关闭当前终端,环境变量即失效。这个和早一些年常规的编译器配置有区别。编译器所在目录如下:
SDK\out\sun8iw11p1\linux\common\buildroot\host\opt\ext-toolchain。
其中<SDK>表示SDK所在路径;
2. 编译前先执行配置指令./build.sh config,配置过程如下:
Config 具体配置如下:
Welcome to mkscript setup progress
All available chips:
0.sun8iw11p1
Choice: 0
All available platforms:
0. linux
Choice: 0
All available kernel:
0. linux-3.10
Choice: 0
All available boards:
0. t3-p1
1. sbc-x40i
Choice: 1(选择sbc-x40i主板)
All available rootfs:
0. buildroot
1. buildroot-201611
Choice: 1
select buildroot-201611
All available float:
0. gnueabi
1. gnueabihf(选择gnueabihf编译器)
Choice: 1
select gnueabihf
All available qt version:
0. 5.9.0
1. 5.9.7
2. 4.8.7
Choice: 0(选择qt的版本是5.9.0)
select 5.9.0
create misc_config gnueabihf
配置完成后,会在<SDK>目录下生成两个编译的辅助配置文件,一个是.buildconfig文件,一个是misc_config文件。这两个文件是设置后续设置编译环境变量的关键。
3)文件重点抉择了qt编译的版本和液晶屏参数的选择,示例文件内容及说明如下:
export LICHEE_CHIP=sun8iw11p1
export LICHEE_PLATFORM=linux
export LICHEE_KERN_VER=linux-3.10
export LICHEE_ARCH=arm
export LICHEE_BOARD=sbc-x40i
export LICHEE_BUILD_ROOT=buildroot-201611
export LICHEE_GNUEABI=gnueabihf
export LICHEE_QTVER=4.8.7
export LICHEE_FEX_CONFIGS=lvds1024x600_lcd
export LICHEE_USER_ROOTFS_MISC_CONFIGS=a40i
这里重点说明两个参数,一个是export LICHEE_QTVER=4.8.7,这个参数给的是QT4.8.7,该参数决定了后续编译中涉及到的QT版本是4.8.7。如果是=5.9.0,那么后续编译的是QT5.9.0版本相关。另外一个是export LICHEE_FEX_CONFIGS=lvds1024x600_lcd,这个决定了编译出来固件支持屏幕的参数。这个参数最后对应<SDK>/tools/pack/chips/sun8iw11p1/configs/sbc-x40i目录下的fex文件。这个文件是执行./build.sh pack打包指令的使用文件。例子中的参数是lvds1024x600_lcd,因此对应的fex文件是sys_config_lvds1024x600_lcd.fex。同理,如果export LICHEE_FEX_CONFIGS=hdmi,那么对应的fex文件是sys_config_hdmi.fex。
4)文件是一个后续编译QT程序时的配置文件,编译过程中要设置编译QT的环境变量和编译器,都由该文件决定。示例文件内容及说明如下:
MISC_CHIP=sun8iw11p1
MISC_BOARD=sbc-x40i
MISC_GNUEABI=gnueabihf
MISC_FBDEV=fbdev_hf
MISC_SDKLIB=libs_hf
MISC_CEDARXLIB=lib_hf
MISC_QTVER=4.8.7
MISC_OUTPUT_CONFIG=lvds1024x768_lcd
MISC_LICHEE_USER_ROOTFS_MISC_CONFIG=a40i
SDK中包含了一些qt演示程序,这些代码在如下目录中:
在<SDK>/buildroot-201611/target/user_rootfs_misc/a40i/qt_demo/,
以其中一个程序编译脚本为例(官方SDK提供的QT程序Launcher),该程序位于 <SDK>/buildroot-201611/target/user_rootfs_misc/a40i/qt_demo/Launcher目录下,由一个编译脚本makeLauncher,脚本的内容如下:
#!/bin/sh
. ../../../../../../misc_config
LICHEE_TOOL=out/${MISC_CHIP}/linux/common/buildroot/host/opt/ext-toolchain/bin
export LICHEE_CHIP=${MISC_CHIP}
export FBDEV=${FBDEV}
export SDK_LIB=${SDK_LIB}
export CEDARX_LIB=${CEDARX_LIB}
export PATH=$PATH:$PWD/../../../../../../$LICHEE_TOOL/
../../../../../../buildroot-201611/dl/qt-everywhere-opensource-src-5.9.0/Qt-5.9.0/bin/qmake -o Makefile Launcher.pro
make -j32
很明确的看到misc_config文件中的相关环境变量起到的作用。
5) 全志官方的SDK中,只有编译qt5.9库的脚本-comp_qtLib-590_only.sh,盈鹏飞嵌入式根据全志的使用习惯新增加了编译QT4.8库的编译脚本-comp_qtLib-487_only.sh。一般编译的过程是先保证能能够编译通过并打包生成固件,在执行这个编译qt库的脚本。编译时,只要在<SDK>目录下执行./comp_qtLib-590_only.sh或者comp_qtLib-487_only.sh即可。但是,在执行comp_qtLib-487_only.sh之前,一般要先编译tslib库。如果您定制QT4.8的库不需要触摸,那么则不用编译tslib库。
6)库到底是否需要?电阻式触摸屏必须使用tslib库,而电容式触摸屏则不一定需要。在qt4.8中,支持触摸屏的解决方案只有tslib,不管是电容式触摸还是电阻式触摸都依赖tslib,因此它是必要的。在qt5.x中,电阻屏的控制依然需要tslib,而电容屏的控制则可以使用qt5.x中自带的evdevtouch,它对多点触摸支持更好。从触摸效果来说,tslib对电容式触摸支持的不那么好,因为它只有单点触摸。
7) 编译的QT代码和tslib代码一般放在<SDK>/buildroot-201611/dl目录下,因为编译脚本中都使用了相对路径,如果你放到其他位置,那么编译脚本要重新定位目录。以下是编译tslib脚本的内容:
#!/bin/bash
source ../../../misc_config
AW_LICHEE_ROOT=$PWD/../../../
export TSLIB_BUILD_ROOT=$PWD
export TSLIB_INSTALL_DIR=$AW_LICHEE_ROOT/tslib1.4
export PATH=$AW_LICHEE_ROOT/out/${MISC_CHIP}/linux/common/buildroot/host/usr/bin/:$PATH
export SYSROOT=$AW_LICHEE_ROOT/out/${MISC_CHIP}/linux/common/buildroot/host/usr/arm-buildroot-linux-${MISC_GNUEABI}/sysroot
export CROSS_COMPILE_DIR=$AW_LICHEE_ROOT/out/${MISC_CHIP}/linux/common/buildroot/host/opt/ext-toolchain/bin/
export CROSS_COMPILE=$CROSS_COMPILE_DIR/arm-linux-${MISC_GNUEABI}-
export PATH=$CROSS_COMPILE_DIR:$PATH
function makeall
{
./autogen.sh
echo "ac_cv_func_malloc_0_nonnull=yes">arm-linux-gnueabihf.cache
./configure --prefix=$TSLIB_INSTALL_DIR --host=arm-linux-gnueabihf --cache-file=arm-linux-gnueabihf.cache CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++
mkdir -p $TSLIB_INSTALL_DIR
make
make install
}
function makeinstall
{
# make -C $TSLIB_BUILD_ROOT install
local TSLIB_TARGET_INSTALL=$AW_LICHEE_ROOT/out/${MISC_CHIP}/linux/common/buildroot/target/usr/local/tslib1.4
mkdir -p $TSLIB_TARGET_INSTALL
cp -rf $TSLIB_INSTALL_DIR/* $TSLIB_TARGET_INSTALL
}
makeall
makeinstall
这个脚本说明如下几点:
TSLIB_INSTALL_DIR目录是当tslib编译完成后,执行make install时,将编译好的库拷贝到该目录。如果不配置该目录,那么tslib的库将会默认安装到编译主机的/usr/local/lib目录下。
因为整个SDK的编译并不需要root权限,而编译主机/usr/local/lib这个路径是必须具有root权限才能访问的,因此我们设置TSLIB_INSTALL_DIR=$AW_LICHEE_ROOT/tslib1.4;
TSLIB_TARGET_INSTALL目录是当tslib编译完成后,需要把编译好的库,打包到板的根文件系统中,这个根文件系统是保存在如下目录:
<SDK>/out/${MISC_CHIP}/linux/common/buildroot/target/;
TSLIB则保存在如下目录下:
<SDK>/out/${MISC_CHIP}/linux/common/buildroot/target/usr/local/tslib1.4
当执行./build.sh指令时,会把该<SDK>/out/${MISC_CHIP}/linux/common/buildroot/target/
目录下的所有文件压缩成根文件系统,最后当执行./build.sh pack指令时,将该根文件系统最后打包成固件。