tslib移植
准备工作
开发板有uboot搭建tftp服务器,开发板可通过服务器下载内核并启动;nfs工具,开发板可通过nfs工具加载到主机(电脑)的rootfs;触摸屏可使用,在cat触摸屏设备,有触摸动作时能获取到反馈信息。查看输入设备:ls /dev/input/event1测试输入设备:cat /dev/input/event1安装tslib
Tslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能。tslib本来是一个用于校正电阻触摸屏的工具,电容屏虽然不需要校正,但是qt基于了该库,所以即使电容触摸屏,我们要移植tslib。
下载tslib-1.4(网上较多,此处不提供下载链接);解压tslib源码 tar -xvf tslib-1.4.tar.gz环境检测:进入到解压目录 ./autogen.sh
报错: ./autogen.sh: 4: ./autogen.sh: autoreconf: not found 是因为该工具需要依赖3个软件autoconf、automake 、libtool而ubuntu中默认没有,则需要安装,电脑联网,输入sudo apt-get install autoconf automake libtool安装工具;
输入指令echo "ac_cv_func_malloc_0_nonnull=yes">arm-linux.cache创建一个目录做tslib安装目录: mkdir /opt/tslib生成makefile并指定了一些配置如安装路径、安装工具等: ./configure --prefix=/opt/tslib --host=arm-linux --cache-file=arm-linux.cache编译:make安装:make install
部署到开发板
实际上我们刚刚在编译的时候已经设定了使用交叉编译工具链,编译的结果就是用于开发板。现在只需直接拷贝到开发板中即可。
将安装在opt目录下的tslib(动态库.so 、配置文件、bin文件)全部拷贝到开发板;定义tslib运行需要的环境变量
export TSLIB_TSDEVICE=/dev/input/event1 //导出触摸设备路径
export TSLIB_CALIBFILE=/tslib/etc/pointercal //导出校正生成的文件路径。
export TSLIB_CONFFILE=/tslib/etc/ts.conf //导出配置文件路径
export TSLIB_PLUGINDIR=/tslib/lib/ts //导出插件路径
export TSLIB_CONSOLEDEVICE=none //不要控制台
export TSLIB_FBDEVICE=/dev/fb0 //
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tslib/lib //
export TS_INFO_FILE=/sys/class/input/input2/uevent //
这些环境变量可以手动逐条添加,但太麻烦,应该添加到/etc/profile中,在启动时自动执行;
tslib测试
运行 ./ts_calibrate测试校正程序。
报错:No raw modules loaded. ts_config: No such file or directory
解决:在tslib目录下的etc/ts.conf文件中的module_raw input打开(删除#),注意前面不能有空格。
报错:tslib移植-selected device is not a touchscreen I understand 错误解决
解决:原因是tslib中的输入系统和内核input系统版本不匹配,需要将arm交叉编译工具中的头文件库中的linux/input.h中的EV_VERSION 宏改为0x010001
vi /usr/local/arm/arm-q3/arm-none-linux-gnueabi/libc/usr/include/linux/input.h
将define EV_VERSION 0x010000改为define EV_VERSION 0x010001
重新编译tslib库再重新部署后即可。
arm平台的qt安装
下载qt5.6.2源码包,并解压,( 在课程中提了,文件名qt-everywhere-opensource-src-5.6.2.tar.gz)在/opt目录下创建一个qt5.6.2文件夹,用来做qt的安装目录。
配置qmake:修改qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf文件;
添加如下内容:
#hdz addedQT_QPA_DEFAULT_PLATFORM = linuxfbQMAKE_CFLAGS_RELEASE += -O2 -march=armv7-aQMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a
修改如下内容,工具链名称一定要与本机安装的名称相同
# modifications to g++.confQMAKE_CC = arm-linux-gcc -ltsQMAKE_CXX = arm-linux-g++ -lts -ldlQMAKE_LINK = arm-linux-g++ -lts -ldlQMAKE_LINK_SHLIB = arm-linux-g++ -lts -ldl
修改如下内容
# modifications to linux.confQMAKE_AR = arm-linux-ar cqsQMAKE_OBJCOPY = arm-linux-objcopyQMAKE_NM = arm-linux-nm -PQMAKE_STRIP = arm-linuxi-strip
编译译前配置
可以参考./configure --help的提示来配置
黄色部分需要自己修改,/opt/QT5.6.2指的是安装的路径,-I和-L是指定的tslib的路径,这个也要与前面部署tslib的路径相同。\为换行接续符,注意\后面不能有空格。
./configure -prefix /opt/qt5.6.2 -opensource -confirm-license\-release -shared -accessibility -c++std c++98 -xplatform\linux-arm-gnueabi-g++ qpa linuxfb -linuxfb -qreal float -pch\-qt-zlib -qt-libjpeg -qt-libpng -no-sse2 -no-largefile\-no-qml-debug -no-glib -no-gtkstyle \-no-opengl -nomake tools -nomake examples -tslib \-skip qt3d -skip qtcanvas3d -skip qtdoc -skip qtwayland \-I /opt/tslib/include -L /opt/tslib/lib
编译make
错误1:找不到dlopen或者dlsym
解决:在编译器后面加ldl arm-linux-g++ -ldl
错误2:undefined reference to `__sync_add_and_fetch_4'
解决:
参考qt5.3.2移植到arm上出undefined reference to '__sync_sub_and_fetch_4的错
apt-get install libtool(通常在安装tslib时已安装);
创建一个文件夹mkdir /home/hudaizhou/sound_code/QT5.8.0/linux-atomic
将课程共享的linux-atomic.c拷贝到该目录。
执行以下2条命令,利用libtool生成liblinux-atomic.a(注意生成的目录名叫.libs所以是隐藏的):
libtool --tag=CC --mode=compile arm-linux-gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atomic.lo linux-atomic.clibtool --tag=CC --mode=link arm-linux-g++ -g -O2 -o liblinux-atomic.la linux-atomic.lo
拷贝生成的.libs/ liblinux-atomic.a到/opt/linux-automic
cp .libs/liblinux-atomic.a /opt/linux-automic // 注意/opt/linux-automic是自己事先创建的
在QT源码下修改:./qtscript/src/script/Makefile
在LIBS = 的结尾添加 -L/opt/linux-automic -llinux-atomic
编译安装:make install
完成后就可以在/opt/qt5.6.2目录下看到安装的内容。
截止目前我们arm平台的qt就安装完成了,安装的文件我们电脑端交叉编译的时候需要用到,开发板中也需要用到,所以在部署的时候需要对该目录下的文件进行拷贝。
桌面电脑qt开发环境搭建
qtcreator安装
qtcreator是一个电脑端的qt应用开发IDE,用于我们在电脑端开发和调试应用。
下载qt-opensource-linux-x64-5.6.2.run(qt课程工具中包含有)直接安装即可。安装完成后,qtcreator在~/Qt5.6.2/Tools/QtCreator/bin目录下;
添加交叉编译工具链
我们写的应用程序通常需要在电脑的ubun运行,方便调试,待调试完成后,放在开发板上运行,我们知道电脑是x86平台,而开发板是arm平台,两平台运行的程序不同,因此我们需要分别编译,在电脑调试时使用MinGW编译成x86平台运行的可执行文件,而要在开发板运行则需要使用gcc编译成arm平台运行的可执行文件。
工具-选项-构建和运行,必须先添加编译器、qt versions、构建套件。因此我们需要在电脑qtcreator中安装2套编译器。MinGW在安装qtcreator时已经安装了,我们只需补充安装gcc相关工具即可。
设定交叉编译工具链
交叉编译工具链,实际就是arm平台的编译工具gcc,他负责把代码编译链接成arm平台下的可执行文件,指定电脑中交叉编译工具链目录,例如我的电脑安装目录/usr/local/arm/arm-q3/bin/arm-linux-gcc。名称可任意设置,如arm-linux-gcc,其余的可以不填。
选择qt versions
qt versions译做qt版本,这个名词不太贴切,他其实是一系列的工具库,最关键的库就是qmake,qmake是一个项目管理工具,可以自动生成makefile。
添加/opt/qt5.6.2/bin/qmake即可。
选择qtkit
qtkit中文叫构件套件,他包含了套件名称、文件系统名称、设备类型、设备、sysroot、C/C++ 编译器、调试器、Qt 版本等信息。他把编译器和调试器进行组合,常见的组合如:MinGW 编译器 + GDB 调试器、GCC 编译器 + GDB 调试器(Ubuntu)。设置如下。
在开发板中运行QT应用
qt库部署
前面已经实现了把源码交叉编译成了arm平台下的可执行程序,按理说我们交叉编译的程序就可以在开发板运行,但实际还是不行,因为qt应用程序运行时要依赖很多的库,要想能正常运行就必须把电脑qtcreator在进行交叉编译代码时依赖的arm平台库等一系列的文件也拷贝到开发板中。
在开发板文件系统(~/sound_code/rootfs/rootfs)中创建一个文件夹用来放库: mkdir QT5.6.2
将我们在电脑端部署的arm平台qt中的库拷贝到创建的目录中:
cp /opt/qt5.6.2/lib/ ./ -rf
cp /opt/qt5.6.2/plugins/ ./ -rf
导出环境变量
qt库拷贝过去后,开发板系统并不能找到,需要我们把路径添加到环境变量,实际上qt运行时需要设置多个环境变量,如下:
export LD_LIBRARY_PATH=/QT5.6.2/lib:$LD_LIBRARY_PATH //导出lib路径
export QT_QPA_PLATFORM_PLUGIN_PATH=/QT5.6.2/plugins //导出plugins路径
export QT_QPA_FONTDIR=/QT5.6.2/lib/fonts //导出fonts路径
export QT_QPA_FB_TSLIB=1 //使用tslib作为输入
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event1 //指定输入设备,一定要与tslib设定的一样。
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=1024x600:mmSize=1024x600:offset=0x0:tty=/dev/tty1
size就是显示屏分辨率,mmSize是显存大小,
为了每次开机能自动去导入环境变量,应该和tslib的环境变量导出一样操作,放在/etc/profile中。
开发板中运行程序
报错:error while loading shared libraries: libstdc++.so.6
解决:提示找不到c++库,是因为我们没拷贝c++的库,在交叉编译工具链中,路径:/usr/local/arm/arm-q3/arm-none-linux-gnueabi/libc/usr/lib。拷贝到开发板/QT5.6.2/lib。
报错:using Latin-1 for conversion, iconv_open failed
解决:缺少一个运行时库preloadable_libiconv.so,交叉编译得到这个后放进去/lib目录下即可。
参考:/wangyuanfei555/article/details/47399771
移植libiconv中遇到的问题及解决:
报错: ./stdio.h:1010:1: error: ‘gets’ undeclared here (not in a function)
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
解决:找到那一行,注释掉。另外编译好的库是intel80386架构的,不是ARM的,不能用,要交叉编译才行。
解决:先看配置好的Makefile,找交叉编译工具链的全局变量。但是本项目的Makefile中没有CC等这些定义,像这种一般就是通过环境变量来设置的。交叉编译libiconv,参考:/wuyu92877/article/details/52472810编译libiconv错误提示gets相关的,参考:/ownfire/article/details/47276219
./configure -prefix=$PWD/_install --host=arm-none-linux-gnueabi
make CROSS_COMPILE=arm-linux-none-gnueabi- ARCH=arm
export LD_PRELOAD=/lib/preloa