【實戰】移植QT5.6.0到嵌入式linuxS3C2440單板
歡迎掃碼關注微信公眾號:柒零玖嵌入式,更多嵌入式軟硬體相關分享!
目前網上關於QT5.6的移植教程還不完善,本部落格詳細說明QT5.6.0移植到嵌入式linux單板的詳細步驟。並將移植好的分享在GitHub上。
一、實驗環境
(1)編譯工具鏈
arm-Linux-gcc-4.4.3.tar.gz
(2)linux系統
linux-3.4.2
(3)虛擬機器
16.04.1-Ubuntu
(4)busybox
busybox-1.22.1.tar.bz2
(5)tslib
tslib-1.4.tar.gz
(6)qt5.6 原始碼
qt-everywhere-opensource-src-5.6.0.tar.gz
(7)S3C2440開發板
嵌入式板子是自己在JZ2440的基礎上製作的。完全相容JZ2440。
二、搭建ubuntu虛擬機器系統
參考《百問網精智JZ2440開發板4.3寸LCD版使用手冊》安裝虛擬機器裡常用的軟體。
①更新軟體源
$ sudo apt-get update
②安裝、配置、啟動 ftp 服務。
執行以下命令安裝,安裝後即會自動執行:
$ sudo apt-get install vsftpd
修改 vsftpd 的配置檔案/etc/vsftpd.conf,將下面幾行前面的“#”號去掉。
#local_enable=YES
#write_enable=YES
上面第一行表示是否允許本地使用者登入,第二行表示是否允許上傳檔案。
修改完華之後,執行以下命令重啟 ftp 服務:
$ sudo /etc/init.d/vsftpd restart
③安裝、配置、啟動 ssh 服務。
執行以下命令安裝, 安裝後即會自動執行:
$ sudo apt-get install openssh-server
它的配置檔案為/etc/ssh/sshd_config,使用預設配置即可。
④安裝、配置、啟動 nfs 服務。
執行以下命令安裝,安裝後即會自動執行:
$ sudo apt-get install nfs-kernel-serverportmap
它的配置檔案為/etc/exports,在裡面增加以下內容,以後將通過網路檔案系統訪問
/work/nfs_root 目錄:
/work/nfs_root *(rw,sync,no_root_squash)
修改完華之後,執行以下命令重啟 nfs 服務:
$ sudo /etc/init.d/nfs-kernel-serverrestart
⑤安裝、配置 tftp 服務軟體:
$ sudo apt-get install openbsd-inetdtftpdtftp
開啟/etc/inetd.conf 檔案,裡面有一行如下:
tftp dgram udp wait nobody /usr/sbin/tcpd/usr/sbin/in.tftpd /srv/tftp
把“nobody”改為“root”,把“/srv/tftp”改為“/work/nfs_root”,表示 tftp 目錄。
⑥使用以下命令安裝基本的開發環境:
$ sudo apt-get install build-essentialtexinfo
⑦安裝工具 bison、flex,它們分別是語法、詞法分析器:
$ sudo apt-get install bison flex libtoolautomake autoconf
⑧安裝 C 函式庫的 man 手冊,以後就可以通過類似“man read”的命令檢視函式的用法了:
$ sudo apt-get install manpages-dev
三、安裝交叉編譯器
(1)解壓
tar zxvf arm-linux-gcc-4.4.3.tar.gz -C /
(2)檢視解壓路徑
ls /opt/FriendlyARM/toolschain/4.4.3/bin
(3)修改環境變數
sudo vi /etc/environment
改為:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/FriendlyARM/toolschain/4.4.3/bin"
(4)重啟系統
reboot
(5)檢視版本
arm-linux-gcc –v
gcc version 4.4.3 (ctng-1.6.1)
四、編譯核心
實驗的時候,使用的是我按畢業班自己移植的linux3.4.2,下面說一下按畢業班的資料,如何產生所需核心
(1)解壓核心目錄
tar jxvf linux-3.4.2.tar.bz2
(2)打補丁
patch -p1 < ../ linux-3.4.2_100ask.patch
(3)複製config檔案
cp config_ok .config
(4)配置
make menuconfig
(5)修改分割槽
修改linux-3.4.2/arch/arm/mach-s3c24xx/common-smdk.c的smdk_default_nand_part函式,核心分割槽改為4M
同時修改uboot中include/configs/smdk2440.h中MTDPARTS_DEFAULT 使核心分割槽為4M。
(6)編譯產生uImage
make uImage
五、製作檔案系統
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、解壓&配置&編譯
(1)tar zxvftslib-1.4.tar.gz
(2)sudo mkdir -p/usr/local/tslib
(3)cd tslib
(4)./autogen.sh
(5)./configure--host=arm-linux ac_cv_func_malloc_0_nonnull=yes CC=arm-none-linux-gnueabi-gccCXX=arm-none-linux-gnueabi-g++ -prefix=/usr/local/tslib
(6)make
(7)make install
安裝完成之後,tslib 就安裝在虛擬機器/usr/local/tslib 目錄下
2、更改 tslib 配置檔案
(1)cd/usr/local/tslib/etc/
(2)sudo vi ts.conf
去掉# module_raw input 前面的 “#” 和空格
3、將製作好的 tslib 移動到我們製作的檔案系統
(1)cd /usr/local
(2)sudo tar zcvftslib.tar.gz tslib
(4)mkdir -p/work/my_rootfs/usr/local
(5)cp tslib.tar.gz/work/my_rootfs/usr/local
(6)tar zxvftslib.tar.gz
(7)rm tslib.tar.gz
4、新增 tslib 環境變數
(1)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
5、測試
此時,tslib 就已經移植好了,下載好的核心和檔案系統到開發板,後啟動。
cd /usr/local/tslib/bin
./ts_test 來測試
出現“selected device is not a touchscreen Iunderstand”錯誤
解決方法:
cd /opt/FriendlyARM/toolschain/4.4.3/
grep "EV_VERSION" * -nR 出現:
arm-none-linux-gnueabi/sys-root/usr/include/linux/input.h:32:#defineEV_VERSION 0x010000
改為:
arm-none-linux-gnueabi/sys-root/usr/include/linux/input.h:32:#defineEV_VERSION 0x010001
重新到tslib目錄
make clean
make
make install
更新開發板上的tslib。重新測試即可成功。
七、移植 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
將以下部分
# 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、配置編譯
(1)sudo mkdir -p /usr/local/Qt5.6
(2)cd ../../../回到QT目錄
(3)配置
./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
(4) make -j4(時間很長,曾使用4.3.2報錯,使用4.4.3後解決)
(5)sudo make install(/usr/local/Qt5.6)
4、將移植好的 qt 打包到開發板
cd /usr/local
cp Qt5.6.tar.gz /work/nfs_root
啟動開發板掛載mnt目錄
Cp Qt5.6 /usr/local/
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
紅色部分請根據自己的開發板進行修改,JZ2440 V3 用上面的引數即可。
八、測試Qt應用程式
將windows下編輯好的原始碼拷貝到虛擬機器上,切換到原始碼目錄
(1)/usr/local/Qt5.6/bin/qmake
(2)make
即可生成可執行檔案,拿到開發板測試即可。
嫌費事的話,將qmake 新增到環境變數裡。
在測試過程中發現程式跑起來沒問題,但是有以下兩條錯誤資訊:
QIconvCodec::convertFromUnicode:using Latin-1 for conversion, iconv_open failed
QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_openfailed
大概是缺少libiconv,解決方法:
(1)下載libiconv-1.14.tar.gz
(2)mkdir -p /usr/local/libiconv
(3)cd /usr/local/libiconv
(4)./configure --host=arm-none-linux-gnueabi--prefix=/usr/local/libiconv CC=arm-none-linux-gnueabi-gccLDFLAGS="-L/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/sys-root/lib"--enable-static
(5)make
(6)make install
(7)把虛擬機器目錄/usr/local/libiconv/lib 下的preloadable_libiconv.so 複製到檔案系統的 /lib 下
(8)在 /etc/profile 中新增
export LD_PRELOAD=/lib/preloadable_libiconv.so
九、使Qt支援中文
(1)下載字型檔jiang_dlut_DroidSansFallback.zip
(2)解壓將DroidSansFallback.ttf 放到單板檔案系統/usr/local/Qt5.6/lib/fonts 目錄下。
然後在使用qtcreator 開發qt應用程式時,在專案中新增
QT += gui
包含標頭檔案 #include<QFontDatabase>
程式碼中設定使用的字型。
intid = QFontDatabase::addApplicationFont("/usr/local/Qt5.6/lib/fonts/DroidSansFallback.ttf");
QStringmsyh = QFontDatabase::applicationFontFamilies (id).at(0);
QFontfont(msyh,10);
font.setPointSize(20);
this->setFont(font);
十、實驗操作
開發板上電:
nfs 30000000192.168.1.102:/work/nfs_root/root_ts.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 460000 $filesize
nfs 32000000 192.168.1.102:/work/nfs_root/uImage_nolcd_4.4.3
nand write 32000000 kernel
set bootargs console=ttySAC0,115200root=/dev/mtdblock3 rootfstype=jffs2
save
reset
cd /etc/init.d/
vi rcS
加入:
ifconfig eth0 192.168.1.17
mount -t nfs -o nolock 192.168.1.102:/work/nfs_root /mnt
cd /usr/local/
ls
tslib
更改 tslib 配置檔案
(1)cd /usr/local/tslib/etc/
(2)sudo vi ts.conf
去掉# module_raw input 前面的 “#” 和空格
insmod s3c_ts.ko
cd /usr/local/tslib/bin
./ts_
將單板 /mnt下的QT5.6複製到/usr/local目錄下
cp -rf Qt5.6 /usr/local/
檢視tslib和QT的環境變數:
vi etc/profile(tslib和QT的環境變數)
cd /mnt
cp preloadable_libiconv.so ../lib/
(增加etc/profile環境變數)
cp DroidSansFallback.ttf /usr/local/Qt5.6/lib/fonts/
(增加etc/profile環境變數)
export LD_PRELOAD=/lib/preloadable_libiconv.so
insmod cfbimgblt.ko
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod lcd.ko
./fb_test /dev/fb0
insmod s3c_ts.ko
cd /usr/local/tslib/bin
./ts_calibrate
./arm_43