移植QT5.6到嵌入式开发板(史上最详细的QT移植教程)
目前网上的大多数 QT 移植教程还都停留在 qt4.8 版本,或者还有更老的 Qtopia ,但是目前 Qt 已经发展到最新的 5.7 版本了,我个人也已经使用了很长一段时间的 qt5.6 for windows ,本文就来介绍一下QT在嵌入式环境的搭建。
移植以到 JZ2440 为例,使用韦老大提供的 ubuntu9.10 虚拟机作为移植环境。当然,其它虚拟机也是可以的,我同样在 ubuntu14.04 移植成功,只不过需要额外装一些库,后面我会简单提及。
此外,我尝试使用 4.3.2 版本的交叉编译工具编译 Qt5.6 ,编译过成功很多错误,编译成功之后使用 qt 编译应用程序时也存在问题,因此我是用的是友善提供的 4.4.3 版本的交叉编译工具。建议新手使用与我相同的编译环境。
因为我们更换了编译工具,因此,我们有接下来的4个工作。
1、重新编译内核
2、制作文件系统
3、移植tslib
4、移植qt
教程涉及的资料:
1、交叉编译器
arm-linux-gcc-4.4.3.tar.gz .链接:http://pan.baidu.com/s/1nvJF8ud 密码:oi57
2、针对于 JZ2440 的内核补丁以及源码
linux-2.6.22.6.tar.bz2
.链接:http://pan.baidu.com/s/1gf0oZn1 密码:jrp6
linux-2.6.22.6_jz2440.patch 链接:http://pan.baidu.com/s/1c1CWgTE 密码:uwuu
4.3寸LCD_mach-smdk2440.c 链接:http://pan.baidu.com/s/1boZsKwf 密码:1xml
3、busybox
busybox-1.22.1.tar.bz2 .链接:http://pan.baidu.com/s/1cee6CI .密码:lv81
4、tslib .
tslib-1.4.tar.gz
5、qt5.6 源码 链接:http://pan.baidu.com/s/1jINj3IQ 密码:6kkc
qt-everywhere-opensource-src-5.6.0.tar.gz 链接:http://pan.baidu.com/s/1kVnV9oN 密码:r7cm
一、更换交叉编译器
首先,将下载好的文件全部放在 /work 目录下
1、解压交叉编译器
sudo tar zxvf arm-linux-gcc-4.4.3.tar.gz -C / #展开在根目录
ls /opt/FriendlyARM/toolschain/4.4.3/bin #检查是否生成了编译目录
2、设置环境变量
sudo vi /etc/environment
将现在原有的交叉编译器路径替换为我们新解压的交叉编译器,举例:
- #PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/tools/gcc-3.4.5-glibc-2.3.6/bin"//注释
- PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/FriendlyARM/toolschain/4.4.3/bin" //增加
后期测试时我发现这里是有问题的,由于我的安装目录都指定的是 usr 目录,需要 root 权限,然而在 environment 中设置的环境变量导致使用 root 权限 make install 过程中出现了个别的 command not found ,于是我将环境变量放到了 /etc/profile 中,这个文件是对所有用户生效的。至于environment
百度了一下是系统环境变量按说应该没问题,但是的确出现了问题。索性还是大家还是直接搞到 profile 中吧。
3、重启虚拟机
4、检查是否更换成功
arm-linux-gcc -v
如图,更换完毕,我们的编译器就变为 4.4.3 版本了。
二、重新编译内核
如果你不是jz2440也没关系,使用你曾经移植好的内核,重新编译即可,注意内核需要开启EABI的支持,如果你是jz2440,按照下面的步骤操作即可。
1、解压
tar jxvf linux-2.6.22.6.tar.bz2
2、打补丁
cd linux-2.6.22.6
patch -p1 < ../linux-2.6.22.6_jz2440.patch
如果你是 4.3 寸的 JZ2440 ,替换 LCD 驱动,3.5寸跳过此步
mv ../4.3寸LCD_mach-smdk2440.c arch/arm/mach-s3c2440/mach-smdk2440.c
3、配置内核支持 EABI
make menuconfig
kernel features->
<*>use the arm eabi to .... //选中这一项
4、修改 makefile ,不改的话 4.4.3 编译器编译时会报错
vi Makefile
由于友善在制作这款交叉编译工具时指定了最低内核版本(2.6.32.2)的限制,所以我们如果不加修改直接编译启动内核时会出现 kernel too
old 的错误信息,无法启动。这里使用一个投机取巧的办法,强制对 2.6.22.6
内核的版本进行修改,更改内核版本号对内核编译是有影响的,真正移植的时候还是建议选择高版本内核。
Makefile 最开始的地方就是版本号:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 22
EXTRAVERSION = .6
中的 SUBLEVEL = 22 改为 SUBLEVEL = 32
//找到一下几行 ,这里是因为 4.4.3 的编译器不支持 gdwarf2 这个选项
ifdef CONFIG_DEBUG_INFO
CFLAGS += -g
AFLAGS += -gdwarf2
endif
//注释掉 AFLAGS += -gdwarf2
5、编译
make uImage -j4
编译完的uImage 在 /arch/arm/boot 目录下
三、制作文件系统
1、解压
tar jxvf busybox-1.22.1.tar.bz2
2、配置
make menuconfig
Busybox Settings ->
general configuration ->
[*] don't use /usr //选中它 否则会破坏虚拟机
build options->
cross comliler prefix = arm-linux- //选择交叉编译工具
installtion options->
busybox installation prefix = /work/my_rootfs //指定安装路径
3、编译&安装
mkdir -p /work/my_rootfs //安装路径
make
make install
cd /work/my_rootfs
ls //查看是否安装成功
编译安装完毕之后,我们的文件系统就生成在 /work/my_roofs 目录下了
4、创建 /etc/inittab
mkdir -p /work/my_rootfs/etc
vi /work/my_rootfs/etc/inittab
# /etc/inittab
# 启动脚本/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
# 启动 shell
::askfirst:-/bin/sh
# 重启关机前 卸载文件系统
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
5、创建 /etc/init.d/rcS
mkdir -p /work/my_rootfs/etc/init.d
vi /work/my_rootfs/etc/init.d/rcS
# 这是一个脚本文件,用/bin/sh解析
#!/bin/sh
# 挂载文件系统
mount -a
# 使用内存文件系统
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# 设置IP
#/sbin/ifconfig eth0 192.168.1.17 #nfs不需要
# 挂载 /etc/fstab 中的文件系统
mount -a
exec /etc/rc.local
6、创建rc.local
vi /work/my_rootfs/etc/rc.local
#!/bin/sh
. /etc/profile //注意.后边有个空格!
7、创建/etc/fstab
vi /work/my_rootfs/etc/fstab
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
8、构建 /dev 目录
mkdir -p /work/my_rootfs/dev
cd /work/my_rootfs/dev
sudo mknod console c 5 1
sudo mknod null c 1 3
9、创建其它目录
mkdir proc mnt tmp sys root usr
10、拷贝Lib
cd /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib
cp *.so* /work/my_rootfs/lib -d
cd /opt/FriendlyARM/toolschain/4.4.3/lib
cp *.so* /work/my_rootfs/lib -d
四、移植 tslib
1、解压&配置&编译
如果不是使用的韦老大的虚拟机可能还需要安装一下几个包 autoconf automake libtool
#sudo apt-get install autoconf automake libtool
tar zxvf tslib-1.4.tar.gz
sudo mkdir -p /usr/local/tslib
cd tslib
./autogen.sh
./configure --host=arm-linux ac_cv_func_malloc_0_nonnull=yes
CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++
-prefix=/usr/local/tslib
make
sudo make install
如果编译过程中遇到 undefined reference to 'rpl_malloc',前面配置完成之后修改 config.h.in 文件,注释掉文件最后的 #undef malloc ,重新 make 即可。
安装完成之后,tslib 就安装在虚拟机 /usr/local/tslib 目录下
2、更改 tslib 配置文件
cd /usr/local/tslib/etc/
sudo vi ts.conf
去掉# module_raw input 前面的 “#” 和空格
3、将制作好的 tslib 移动到我们制作的文件系统
cd /usr/local
sudo tar zcvf tslib.tar.gz tslib
mkdir -p /work/my_rootfs/usr/local
cp tslib.tar.gz /work/my_rootfs/usr/local
tar zxvf tslib.tar.gz
rm tslib.tar.gz
4、添加 tslib 环境变量
vi /work/my_rootfs/etc/profile
#!/bin/sh
export T_ROOT=/usr/local/tslib
export LD_LIBRARY_PATH=/usr/local/tslib/lib:$LD_LIBRARY_PATH
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_PLUGINDIR=$T_ROOT/lib/ts
export TSLIB_CONFFILE=$T_ROOT/etc/ts.conf
export POINTERCAL_FILE=/etc/pointercal
export TSLIB_CALIBFILE=/etc/pointercal
此时,tslib 就已经移植好了,你可以挂载 nfs 文件系统启动,cd /usr/local/tslib/bin
./ts_test 来测试
按照教程制作应该没有问题,我在使用高版本内核的时候遇到“selected device is not a touchscreen I
understand”错误,百度了一下,是由于内核和编译器的一个宏定义不一致导致的,vi include/Linux/input.h
EV_VERSION 为 0x0100000 ,从新编译内核特别是触摸驱动。
五、移植 qt5.6
1、解压
tar zxvf qt-everywhere-opensource-src-5.6.0.tar
2、修改编译配置
cd /work/qt-everywhere-opensource-src-5.6.0/qtbase/mkspecs/linux-arm-gnueabi-g++
vi qmake.conf
针对于 2440 增加:
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t
march 指的 cpu 架构,针对 2440 来说是 armv4t
mtune 指的 cpu 名字,针对 2440 来说是 arm920t
如果你是 A8 的板子 ,可以参考下边的配置
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a8
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a8
如果你是 A9 的板子 ,可以参考下边的配置
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a9
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a9
将以下部分
# modifications to g++.conf
QMAKE_CC = arm-linux-gnueabi-gcc
QMAKE_CXX = arm-linux-gnueabi-g++
QMAKE_LINK = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabi-g++
# modifications to linux.conf
QMAKE_AR = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabi-objcopy
QMAKE_NM = arm-linux-gnueabi-nm -P
QMAKE_STRIP = arm-linux-gnueabi-strip
修改为:-lts 是指在链接时链接 tslib 库
# modifications to g++.conf
QMAKE_CC = arm-none-linux-gnueabi-gcc -lts
QMAKE_CXX = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK_SHLIB = arm-none-linux-gnueabi-g++ -lts
# modifications to linux.conf
QMAKE_AR = arm-none-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-none-linux-gnueabi-objcopy
QMAKE_NM = arm-none-linux-gnueabi-nm -P
QMAKE_STRIP = arm-none-linux-gnueabi-strip
3、配置编译
sudo mkdir -p /usr/local/Qt5.6
cd ../../../
./configure -prefix /usr/local/Qt5.6 \
-opensource \
-release \
-confirm-license \
-xplatform linux-arm-gnueabi-g++ \
-shared \
-qt-zlib \
-no-gif \
-qt-libjpeg \
-no-nis \
-no-opengl \
-no-cups \
-no-glib \
-no-dbus \
-no-rpath \
-no-sse2 -no-sse3 -no-ssse3 -no-sse4.1 -no-sse4.2 \
-no-avx \
-no-openssl \
-nomake tools \
-qreal float \
-qt-libpng \
-tslib \
-nomake examples \
-I /usr/local/tslib/include \
-L /usr/local/tslib/lib
make -j4
sudo make install
如果使用的不是韦老大的虚拟机编译过程中可能报关于libxcb的错误,查看 qtbase/src/plugins/platforms/xcb 底下的 readme 安装相应的库就可以了。
4、将移植好的 qt 打包到开发板
cd /usr/local
sudo tar zcvf Qt5.6.tar.gz Qt5.6
cp Qt5.6.tar.gz /work/my_rootfs/usr/local/
tar zxvf Qt5.6.tar.gz
rm Qt5.6.tar.gz
rm -r doc include bin mkspecs qml translations
5、设置qt相关的环境变量
此部分可以参考qt官方问文档:http://doc.qt.io/qt-5/embedded-linux.html ,这我这仅仅是设置支持了触摸屏,你可以参考官方设置支持键盘,鼠标等等。
在文件系统 /etc/profile 里添加
export QTEDIR=/usr/local/Qt5.6
export LD_LIBRARY_PATH=/usr/local/Qt5.6/lib:$LD_LIBRARY_PATH
export QT_QPA_GENERIC_PLUGINS=tslib
export QT_QPA_FONTDIR=$QTEDIR/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTEDIR/plugins
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=480x272:mmSize=480x272:offset=0x0:tty=/dev/tty1
export QT_QPA_FB_TSLIB=1
红色部分请根据自己的开发板进行修改,我手头的开发板是 3.5 寸 320*240 的 LCD,JZ2440 V3 用上面的参数即可。
此时,qt
已经移植完毕,你可以打包放入你的 nfs 目录启动进行测试了,至于制作 yaffs2 jffs2
等文件系统请参考:http://blog.csdn.net/lizuobin2/article/details/52589215
,qt库比较大,烧录的时候可能比较困难,可以先将QT去除,打包成文件系统大约之后20M不到,烧录到开发板之后,启动内核,通过nfs
tftp等工具,再将打包好的Qt传到板子上展开即可。
六、测试Qt应用程序
我个人习惯先用 windows 版本的 qt 写好程序,调试没问题之后直接拿到虚拟机上编译,windows 版本的 qt 安装非常简单,就跟安装个QQ一样毫不费力,这里就不再赘述了。
将windows下编辑好的源码拷贝到虚拟机上,切换到源码目录
/usr/local/Qt5.6/bin/qmake
make
即可生成可执行文件,拿到开发板测试即可。
嫌费事的话,将 qmake 添加到环境变量里。
在测试过程中我发现程序跑起来没问题,但是有以下两条错误信息:
QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open failed
QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_open failed
大概是缺少 libiconv
下载 链接:http://pan.baidu.com/s/1c22xb4O 密码:pbld
mkdir -p /usr/local/libiconv
./configure --host=arm-none-linux-gnueabi --prefix=/usr/local/libiconv
CC=arm-none-linux-gnueabi-gcc
LDFLAGS="-L/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/sys-root/lib"
--enable-static
make
sudo make install
把安装目录/lib 下的 preloadable_libiconv.so 文件系统的 /lib 下, 在 /etc/profile 中添加
export LD_PRELOAD=/lib/preloadable_libiconv.so
7、使Qt支持中文
在测试过程中很悲剧的发现移植好的qt不支持中文,强大度娘给了我答案。
下载字库 链接:http://pan.baidu.com/s/1bp9QFQv 密码:2u81
将DroidSansFallback.ttf 放到文件系统 /usr/local/Qt5.6/lib/fonts 目录下,虽然Qt自带了很多字库了,但是都没有中文的。
然后在使用qt creator 开发qt应用程序时,在项目中添加
QT += gui
包含头文件 #include <QFontDatabase>
代码中设置使用的字体。
int id = QFontDatabase::addApplicationFont("/usr/local/Qt5.6/lib/fonts/DroidSansFallback.ttf");
QString msyh = QFontDatabase::applicationFontFamilies (id).at(0);
QFont font(msyh,10);
font.setPointSize(20);
this->setFont(font);
文章写了很久了,感谢有众多朋友的信任,参考本文进行了一系列的尝试,在此过程中也发现了文章中的不足,以及网盘中文件系统中的一些不足,恰巧最近有机会,重新做了一份内核,文件系统,以及配套的
uboot,并将它们放在了github上持续更新。如有需要,请下载:
这个文件系统相对完善,开机会自动校准(第一次),然后运行一个简单的Qt桌面程序,暂时没有放其它应用程序。文件系统中已经带有ftpserver工具,大家可以使用filezila进行文件传输,加密方式选择(仅ftp...不安全),端口21,用户root,没有密码。文件系统庞大,还是建议先将qt等一些东西拷贝出来再传进去。
如果你想让你的开发板支持 ssh 请参考:
http://blog.csdn.net/lizuobin2/article/details/52664339
如果你想让你的开发板支持串口(rz)传输文件请参考:
http://blog.csdn.net/lizuobin2/article/details/52601617
如果你想让你的开发板想虚拟机一样在命令行显示用户名请参考:
http://blog.csdn.net/lizuobin2/article/details/52664657
嵌入式QT相关的设计开发需求,请联系我QQ:271526143
移植QT5.6到嵌入式开发板(史上最详细的QT移植教程)的更多相关文章
- 利用官方的ucosiii包中测试板的工程移植到属于自己的开发板(stmf103ZE)上
ucosIII官方下载地址:https://www.micrium.com 第一:是不是ucosIII:第二,工具链是不是keil(我用的是keil,如何用的是IAR就选有IAR的):第三MCU是不是 ...
- 史上最详细的CocoaPods安装教程
虽然网上关于CocoaPods安装教程多不胜数,但是我在安装的过程中还是出现了很多错误,所以大家可以照下来步骤装一下,我相信会很好用. 前言 在iOS项目中使用第三方类库可以说是非常常见的事,但是要正 ...
- 黄聪:史上最详细的kali安装教程没有之一
首先在vm里面新建虚拟机,直接选择典型,然后下一步. 1 2 然后到了这一步,选择中间的安装程序光盘镜像文件,然后去文件里面找你自己下载的镜像,这时候可能系统会出现无法检测此光盘镜像中的操作系 ...
- Eclipse安装教程 ——史上最详细安装Java &Python教程说明
参考链接:https://blog.csdn.net/zichen_ziqi/article/details/73995755
- 史上最详细的codeblocks安装教程!!!
codeblocks下载地址:https://www.cnblogs.com/yinbiao/p/8489748.html 下面是codeblocks具体的安装教程:
- 【4412嵌入式开发板学习笔记】认识uboot
转自迅为讨论群:http://www.topeetboard.com 重要说明:这份笔记不是4412开发配套的,是我在网上看视频的时候下载上课老师的笔记后修改的.所以我试了一下笔记上的uboot命令, ...
- ARM嵌入式开发板
iTOP-4412 ARM嵌入式开发板----主要特点 iTOP-4412开发平台是北京迅为电子研发设计的嵌入式开发板平台,核心板配备64位双通道2GB DDR3,16GBEMMC存储,三星原厂S5M ...
- 嵌入式开发板iTOP4412学习开发板
网站:http://www.topeetboard.com 淘宝:https://item.taobao.com/item.htm?_u=okcahs0f42a&id=38712193806 ...
- 学习嵌入式开发板的Android平台体系结构和源码结构
本文转自迅为论坛资料:http://www.topeetboard.com 推荐学习嵌入式开发板平台:iTOP-4412开发板 下面这张图出自Google官方,展示了Android系统的主要组成部分. ...
随机推荐
- HDU 6183 Color it
线段树. 假设只有一种颜色,因为每次询问有一个$x$一定是$1$,那么我可以想办法找出每一个$y$最小的$x$是多少,如果最小的都不符合,那么一定不符合,因为更新变成了单点更新,询问是区间询问最小值, ...
- [I/O]javaI/O工作机制
摘要:IO问题可以说是当今web应用中面临的主要问题之一.因为在这个数据爆发的时代,海量的数据在网络到处流动,而在这个过程中都会涉及IO问题,可以说IO问题已经成为web应用的瓶颈之一.如何优化?以此 ...
- JavaSE1
<The Pragmatic Programmer><The Mythical Man-month><Clean Code><The Clean Coder& ...
- Redis_NoSql分布式数据库CAP原理
前文简单介绍了NoSql数据库的四大分类以及常用的数据库技术,本文简单介绍分布式数据库CAP原理. 一.传统的CAID是什么 1. A(Atomicity)原子性:事务里的所有操作要么全部做完,要么都 ...
- 【BZOJ 1398】 1398: Vijos1382寻找主人 Necklace (最小表示法)
1398: Vijos1382寻找主人 Necklace Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 308 Solved: 129 Descrip ...
- luogu P3383 【模板】线性筛素数
题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行 ...
- [APIO2014]序列分割 --- 斜率优化DP
[APIO2014]序列分割 题目大意: 你正在玩一个关于长度为\(n\)的非负整数序列的游戏.这个游戏中你需要把序列分成\(k+1\)个非空的块.为了得到\(k+1\)块,你需要重复下面的操作\(k ...
- CVE-2017-7269—IIS 6.0 WebDAV远程代码执行漏洞分析
漏洞描述: 3月27日,在Windows 2003 R2上使用IIS 6.0 爆出了0Day漏洞(CVE-2017-7269),漏洞利用PoC开始流传,但糟糕的是这产品已经停止更新了.网上流传的poc ...
- 不思议迷宫:逆向后的放置play
前言 前置准备 目标分析 逆向加密逻辑 定位sign与key 解密luac 反编译luajit的bytecode 开启上帝模式 前言 看了fatezero的<阴阳师:一个非酋的逆向旅程& ...
- nginx+php-fpm 配置和错误总结
<strong>空白页面:</strong>需要这个参数: fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_scrip ...