1. 程式人生 > >【實戰】移植QT5.6.0到嵌入式linuxS3C2440單板

【實戰】移植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