Qt移植学习之路 QT4.5.3至mini2440

移动开发
Qt移植学习之路 QT4.5.3至mini2440是本文介绍的内容,关于移植我们应该接触过很多相关内容,先来看本文介绍。

本文介绍的是Qt移植学习之路 QT4.5.3至mini2440,终于成功移植QT 4.5.3至mini2440,并能运行QT自带的应用程序,总得来说还算很顺利,下面是我移植的全部过程。

首先,我交待一下我的开发环境:

宿主机:Fedora9 

主机Gcc:gcc 版本 4.3.0 20080428 (Red Hat 4.3.0-8) (GCC)

交叉编译器:arm-linux-gcc-4.3.2 (友善光盘自带)

开发板:mini2440(NAND 128M  SDRAM 64M)

移植步骤:

1.准备源码包

从ftp://ftp.qt.nokia.com/qt/source/ 下载:qt-embedded-linux-opensource-src-4.5.3.tar.gz和

qt-x11-opensource-src-4.5.3.tar.gz

前者是移植到开发板上运行的,后者是方便在X86机上开发应用程序,待一切调试成功再经交叉编译后下载到开发板上运行。

从网上下载tslib-1.4.tar.gz包,这包用于管理触摸屏,例如可用于它来校正触摸屏,并保存校正数据。

2.编译安装tslib-1.4

把tslib-1.4 COPY到Fedora9的 /opt下,在Fedora9的终端下执行:

  1. #cd /tmp  
  2. # tar zxvf tslib-1.4.tar.gz       ――――――――(最后在/tmp下解压生成tslib)  
  3. #cd  tslib   
  4. #./autogen.sh  
  5.     #./configure --prefix=/home/mytslib/ --host=arm-linux ac_cv_func_malloc_0_nonnull=yes 
  6.     #make  
  7. #make install 

成功后可在/home下生成mytslib,进入mytslib可以看到有bin include lib etc四个文件夹。我们暂时先不理它,在接下来的移植过程中才用到这些文件夹。

3. 编译安装QT-X11-4.5.3

QT-X11-4.5.3是运行于linux平台下用于仿真QT应用程序的软件,这样你便可以在linux平台下把你应用程序都调试好,然后再利用QT4.5.3把应用程序编译成ARM版本下载至开发板,这样你就可以在开发板上运行你的QT应用程序了。

下面是安装步骤:

首先把qt-x11-opensource-src-4.5.3.tar.gz 拷贝到Fedora9下的/tmp目录下,接着执行:

  1. #tar zxvf qt-x11-opensource-src-4.5.3.tar.gz  
  2. #cd qt-x11-opensource-src-4.5.3  
  3. #./configure  
  4.     #gmake      //一般用时2-3小时,如果你的机子配置不太低的情况下  
  5. #gmake install 

安装OK后,在/usr/local/目录下生成Trolltech目录,这就是我们要用于在x86平台(Fedora9)下开发应用程序时所依赖的一些目录。现在你可以进入/usr/local/Trolltech/Qt-4.5.3/examples下,进入一个例子,比如进入/usr/local/Trolltech/Qt-4.5.3/examples/widgets/analogclock下,你会发现,这个例子都已经编译好了,在Fedora9的终端下直接运行:

  1. #./analogclock –qvfb  

则在Fedora9的屏幕上出现下图:

Qt移植学习之路 QT4.5.3至mini2440

也许你会想,我是否能重新编译一遍analogclock呢?因为analogclock目录下有一个Makefile,于是执行:

  1. #make clean  
  2. #qmake –project   

唉,你会发现,提示说找不到命令“qmake”,怎么办呢?很简单,因为我们还没有设置环境变量,当然会找不到命令啦。  

让我们来设置一下QT-X11-4.5.3的环境变量,首先进入你的安装QT-x11-4.5.3目录:

  1. #cd /opt/qt-x11-opensource-src-4.5.3 

在此目录下建立一个名为:qt_x11_setenv.sh的shell文件,内容如下:

  1. #!bin/bash  
  2. PATH=/usr/local/Trolltech/Qt-4.5.3/bin:$PATH  
  3.     QTDIR=/usr/local/Trolltech/QT-4.5.3  
  4.     MAINPATH=$QTDIR/man:$MAINPATH  
  5.     LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH  
  6. export PATH QTDIR MAINPATH   LD_LIBRARY_PATH  
  7. echo "     set qt-x11 env. successful    " 

保存退出,在终端执行:

  1. #source qt_x11_setenv.sh 

终端回显:set qt-x11 env. successful

  1. #echo $QTDIR 

终端回显:/usr/local/Trolltech/QT-4.5.3 ――――――说明:环境变量设置成功。

在这之后,我们再执行一下:

  1. #qmake –project    (建立*.pro文件)   
  2. #qmake          (产生Makefile文件)   
  3. #make            (编译产生可执行程序) 

如果没有错误将生成analogclock可执行程序,终端执行:

  1. #./analogclock –qvfb   

看看是否出现画面了~~~~~~~~~~

注意一点:

在每次进入qt-x11-linux-opensource-src-4.5.3目录中要 #source setenv-x11.sh

把环境变量设置好,否则又会出现无法编译。

成功后,是不是有点迫不及待地想自己试验一个QT程序呢,让我们来编写一个hello程序吧!

  1. #cd qt-x11-linux-opensource-src-4.5.3/ /opt/qt-x11-opensource-src-4.5.3/examples/  
  2. #mkdir hello  
  3. #vi hello.cpp     

然后把下列源程序COPY到hello.cpp中。

  1. #include <QApplication>   
  2. nclude <QPushButton> 
  3.  int main(int argc, char *argv[])  
  4.       {  
  5.            QApplication app(argc,argv);  
  6.            QPushButton b("Hello World !");  
  7.               b.show();  
  8.               QObject::connect(&b,SIGNAL(clicked()),&app,SLOT(quit()));  
  9.                return app.exec();  
  10.         } 

进入前记得执行source setenv-x11.sh

 

  1. # qmake –project (产生hello.pro文件)  
  2. #qmake            (产生Makefile文件)  
  3. #make              (执行Makefile以生成可执行程序) 

如果不出错在当前目录下生成hello可执行程序,既然生成了,那还等什么,执行吧。

  1. #./hello –qvfb   

我执行后就出图了,你的呢?

Qt移植学习之路 QT4.5.3至mini2440

其实图是可以拉大的,你试试!

4.编译安装QT4.5.3

首先我们建立两个目录用来存放接下来编译出来的一些目标文件,在Fedora9的根目录下建立mini2440 和 tslib两个目录,终端执行:

  1. #cd /  
  2. #mkdir mini2440   
  3. #mkdir tslib 

接下来我们把qt-embedded-linux-opensource-src-4.5.3.tar.gz COPY到/tmp下, 终端执行:

 

  1. #cd /tmp  
  2. #tar zxvf qt-embedded-linux-opensource-src-4.5.3.tar.gz   
  3. #cd qt-embedded-linux-opensource-src-4.5.3 
  1. #./configure -prefix /mini2440  -release -shared -fast -pch -no-qt3support -qt-sql-sqlite -no-libtiff -no-libmng -qt-libjpeg   
  2. -qt-zlib -qt-libpng -qt-freetype -no-openssl -nomake examples -nomake demos -nomake tools -optimized-qmake -no-phonon -no-nis  
  3.  -no-opengl -no-cups -no-xcursor -no-xfixes -no-xrandr -no-xrender -no-xkb -no-sm -no-xinerama -no-xshape -no-separate-debug-info   
  4. -xplatform qws/linux-arm-g++ -embedded arm -depths 16 -no-qvfb -qt-gfx-linuxfb -no-gfx-qvfb -no-kbd-qvfb -no-mouse-qvfb -qt-kbd-usb   
  5. -confirm-license -qt-mouse-tslib -I/home/mytslib/include -L/home/mytslib/lib 

上面最后一句“-I/home/mytslib/include -L/home/ mytslib/lib ”指明我们刚才编译出来触摸屏的库文件及头文件存放路径。它前面的“-qt-mouse-tslib”表示将使用触摸屏。

然后执行:

  1. #gmake  
  2. #gmake install 

上面编译时间较长,一般要2到3个小时。

这样,嵌入式版本的qt4装成功了,若想进行交叉编译,首先也得改变环境变量,所以也可以在当前目录下建一个环境变量的文件setenv-embedded.sh 如下:

  1. #gedit setenv-embedded.sh 

这时跳出一个编辑文本输入:

  1. PATH=/mini2440/bin:$PATH  
  2. QTDIR=/mini2440  
  3. MAINPATH=$QTDIR/man:$MAINPATH  
  4. LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH  
  5. export PATH QTDIR MAINPATH   LD_LIBRARY_PATH 

保存退出。每次进行qt4-embedded的交叉编译前先# source setenv-embedded.sh,注意我们在编译QT应用程序时要用到上述变量。下文会提到。

#p#

4. 移植相关库文件至开发板

首我们得准备一个文件系统,我是根据友善提供的文档制作了一个文件系统,路径为/opt/studyarm/rootfs, 其中rootfs就是我的根文件系统。

首先在rootfs 的根目录下建立两个目录:

在开发板的终端下执行:

  1. #cd /  
  2. #mkdir mini2440  
  3. #mkdir tslib 

接下来我们要COPY我们刚才编译生成的一些库文件及配置文件至开发板上的mini2440, tslib。我是用NFS方式挂载文件系统的,当然你可以用其它下载方式把目标库文件等下载到你的开发板就行。

因为是用NFS挂载方式,所以我在Fedora9终端上执行:

  1.    #cp –rf /home/mytslib/lib  /opt/studyarm/rootfs/tslib/  
  2.    #cp –rf /home/mytslib/etc /opt/studyarm/rootfs/tslib/  
  3.    #cp –rf /mini2440/lib /opt/studyarm/rootfs/mini2440/  
  4. #cp –rf /home/mytslib/etc /opt/studyarm/rootfs/tslib  
  5. #cp /home/mytslib/bin/ts_calibrate /opt/studyarm/rootfs/bin  
  6. #cp /home/mytslib/bin/ts_test /opt/studyarm/rootfs/bin  
  7. 编辑开发板/etc/profile,用来在在开发板上设置环境变量,开发板终端输入内容如下:  
  8. Cat >> /etc/profile/ << EOF 
  9. (当然也可以一个一个变量敲入,但是这种方法设置的变量在断电重新上电后又得设置一遍很麻烦,所以把变量直接写入/etc/profile后,系统启动时会自动更新变量,很简便)  
  10. export  QTDIR=/mini2440  
  11. export  T_ROOT=/tslib  
  12. export  PATH=$QTDIR/bin:$PATH  
  13. export  TSLIB_CONSOLEDEVICE=none 
  14. export  TSLIB_FBDEVICE=/dev/fb0  
  15. export  TSLIB_TSDEVICE=/dev/ event0  
  16. export  TSLIB_PLUGINDIR=$T_ROOT/lib/ts  
  17. export  TSLIB_CONFFILE=$T_ROOT/etc/ts.conf  
  18. export  TSLIB_CALIBFILE=/etc/pointercal  
  19. export  QWS_MOUSE_PROTO=tslib:/dev/event0  
  20. export  LD_LIBRARY_PATH=$T_ROOT/lib:$QTDIR/lib  
  21. EOF 

终端输入上述变量设置后,再执行一下:source /etc/profile使系统更新一遍刚设置的系统环境变量。

验证变量设置是否成功:

在开发板终端下执行:

#echo $QTDIR  如果显示  #/mini2440,则说明设置成功了,在QT的移植过程中环境变量的设置是非常重要的,如果设置的不正确会出现很多问题。

比如说:在参考别人QT移植的文章时,有人环境变量设置与我的不同,主要有如下几个:

  1. export  TSLIB_FBDEVICE=/dev/input/fb0    
  2. export  TSLIB_TSDEVICE=/dev/input/event0  
  3. export  QWS_MOUSE_PROTO=tslib:/dev/input/event0 

注意到没有:他们的环境变量中,fb0,event0设备都在/dev/input下,而我查看了我的/dev下没有input目录,所以这点要根据自已所做文件系统的实际情况来设置这些变量。

接下来我们还得设置一下触摸屏的配置文件ts.conf. 它在哪里呢?前面我们把mytslib下的etc目录COPY到了开发板的/tslib/下,那么tslib一共就有bin及etc两个目录,而ts.conf就在etc目录下,开发板下用vi /tslib/etc/ts.conf

把# module_raw collie 前面的“#”号去掉,然后把该行移至行首,最后我的配置文件如下:

  1. module_raw collie  
  2. module pthres pmin=1 
  3. module variance delta=30 
  4. module dejitter delta=100 
  5. module linear   

自执行source /etc/profile后,开发板的环境变量就完全设置好了,并且QT4.5.3的移植也基本完成了,这所以说基本,是因为现在可以运行QT程序了,但是还需要进一步的做一些移植,比如说字库,中文显示等等。接下来将验证tslib及QT4.5.3是否移植成功。

5. 测试触摸屏校正

在开发板终端下执行:

  1. #ts_calibrate      ---------触摸较正程序 

运行该程序后,屏幕将出现五点校正画面,依次点击五点后,将生成触摸屏校正数据文件/etc/pointercal.

  1. #ts_test         ----------触摸屏拖曳测试程序 

运行后屏幕出现drag,draw  依次选择后进行测试,同时终端下出现拖曳后的取点数据。

6.运行QT应用程序以验证QT4.5.3是否移植成功

我们要编译一些例子程序,同时将它们下载至开发板运行。

在终端下首先检测一下环境变量,因为在qt-embedded-linux-opensource-src-4.5.3下编译应用程序要依赖于它所生成的一些库,我们在前面第3步,不是在主机/mini2440下生成了一些库和其它文件么?其中/mini2440/lib我们移植到了开发板,这些库和其它目录中的文件我们编译QT应用程序时也是要依赖它们的,所以环境变量路径是否设置正确直接影响应用程序编译是否成功。

主机终端执行:

#echo $QTDIR  ――――回显为“/mini2440”则说明环境变量设置OK,如果回显为空,或者为其它路径,则要source setenv-embedded.sh一下,不明白的请回到第3步再看一遍。

环境变量测试没问题,那么就可以编译QT程序了。

  1. #cd  ……/ qt-embedded-linux-opensource-src-4.5.3/ examples/mainwindows/application/  
  2. #qmake –project      (如果提示无“qmake”命令,则肯定是你的环境变量的路径设置不正确,或者source setenv-embedded.sh一下即可)  
  3. #qmake     (成生Makefile)  
  4. #make      (生成可执行程序) 

至此,如果你没发生什么错误应该可以在application下看到“application”的可执行程序了,把它下载到你的开发板下并执行:

  1. #./application –qws    

现在可以看到屏幕上的对话框了吧?可能显示的不是很“正”,(但可以用触摸笔把它拖到屏中央),并且字也不是看得很清。

你可以编译其它自带的例子运行试试看。

接下来的工作就是如何把修正字体等其它工作。但初步移植算是成功了。

7. QT自带例子运行出现错误

编译home/qt-4.5.3/qt-embedded-linux-opensource-src-4.5.3/examples/widgets/imageviewer

成功后,下载板子后运行,出现:Segmentation fault,但多运行几次发现可以运行,也就是说偶尔会出现不能运行的错误,这是一个经典问题。很多文章介绍说是编译器的问题。

有的网友说:EABI的编译器编译出来的Qt-4.5的程序都会出现段错误。原因不明。这个我不敢苟同,因为我试了很多自带的例子,用带EABI的编译器arm-linux-gcc-4.3.2-EABI是可以运行的。

百度了一下,发现有价值的文章不多,下引自一网友的BLOG:http://zhubangbing.blog.163.com/blog/static/52609270200993015132315/

c/c++/qt中的段错误(segment fault)

关于内存的那些话就不说了,被一帮会装会转载的人说烂了,这里只说我在写程序时遇到段错误的原因,如何解决的,总之一句话,涉及到指针的,你不能在未定义,未初始化,未 “new” 之前使用,否则等待你的肯定是 segment fault,然后程序直接退出

1. 类A在执行中可能会几次用到用到类B,也可能只有一次用到,也可能一次都不用,这种情况下我的习惯就是在类A的构造函数中初始化B类对象为NULL,然后在用的地方先判断B是否实例化,未实例化,实例化,然后使用,delete B类对象时也要先判断下B是否实例化
    因为这里已经初始化了类B的对象,使用时容易出的错误是在判断是否实例化时,如果在判断类本身是否实例化之前,判断了(或者说使用了)类B的成员函数/成员变量,出现段错误,因为这个类不存在,其成员函数/变量也不存在
例子:
A 的构造函数中有这样一句this->m_b = NULL;//将B类对象 m_b初始化为NULL ,此处B类为QThread的子类使用中

  1. void new_b()  
  2. {  
  3.     if(!this->m_b)  
  4. {  
  5.     this->m_b = new B;  
  6.     this->m_b->start();  
  7.     .....  
  8. }  
  9. }  
  10. void delete_b()  
  11. {  
  12.     if(this->m_b||this->m_b->isRunning())//delete B 类对象时判断条件  
  13.     {  
  14.             while(!this->m_b->isFinished())  
  15.             {  
  16.                 this->m_b->quit();  
  17.                 this->m_b->wait(500);  
  18.             }  
  19.             delete this->m_b;  
  20.             this->m_b = NULL;  
  21.     }  

这样使用时,在只调用一次delete_b()时,可能不会出问题,因为这个时候m_b可能已经实例化了,所以程序只要判断到 this->m_b 为真,就会认为if条件为真,然后往下执行,但是问题是,如果调用了两次 delete_b()或者在调用之前m_b没有 new_b(),那么判断时this->m_b为假,程序就会继续判断this->m_b->isRunning()是否为真,这就出现段错误了,因为m_b未 “new”

2.两个线程共用缓存

我们的项目中音频的发送和接收是用两个线程实现的,线程的结束时间是不可控的,线程达到结束条件时肯定需要做清理工作,比如缓存的释放,设备关闭,如果一个线程结束时没有判断另外一个是否结束,清理了共用的缓存,而另外一个线程又去访问了这个缓存,就出现了段错误

在友善ARM9论坛上发现一篇可能可以解决段错误的文章:

http://www.arm9home.net/read.php?tid-2993-fpage-0-toread--page-2.html

程序 qt-embedded-linux-opensource-src-4.5.0/src/gui/embedded/qscreenlinuxfb_qws.cpp
作如下修改:

  1. 410行:  
  2. /*            //EmbedSky_del start 20091208  
  3.     canaccel = useOffscreen();  
  4.     if(canaccel)  
  5.         setupOffScreen();  
  6. */            //EmbedSky_del end 20091208  
  7.     canaccel = false;  
  8.  
  9. 706行:  
  10. /*                //EmbedSky_del start 20091208  
  11.     if (canaccel) {  
  12.         *entryp=0;  
  13.         *lowest = mapsize;  
  14.         insert_entry(*entryp, *lowest, *lowest);  // dummy entry to mark start  
  15.     }  
  16. */                //EmbedSky_del end 20091208  
  17.     canaccel = false

可能解决segmentation fault问题,请大家测试

[ 此帖被lpc2292在2010-03-24 14:37重新编辑 ]

有网友试验过上面修改embedded/qscreenlinuxfb_qws.cpp的方法,并成功解决此错误,我暂时没有去试,因为要重新编译一遍QT,几个小时下来,够让人等的。
下面引自一网友的文章,简单的说明了一下段错误的产生原因,及调试方法。

qt 段错误,简单调试方法

如果Qt程序不大也不小,有些地方难免会出现声明指针后没有具体实现的情况。这种情况下Qt在编译阶段是不会出现错误的,但是运行的时候会出现“段错误”,其他什么都不会显示。

而段错误就是你的指针访问了没有分配地址的空间,或者是指针为NULL。

在这种情况下想快速确定是哪个地方出现的错误应该用gdb调试debug信息,但是我对那东西还不熟悉,还没具体研究过(等我程序写的大体像个样子再说)。不过懒人我找到了一个简单的方法......

在主程序中加入qDebug("Msg");一步一步跟踪进实现函数,就会知道到底是哪个地方出现问题了。这个东西还挺管用的,对于我这样的初学者就足够了。

小结:关于Qt移植学习之路 QT4.5.3至mini2440的内容介绍完了,希望本文对你有所帮助。

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-06-27 17:15:33

Qt creator Qt Creator

2011-06-13 11:07:22

QT 移植

2011-06-24 13:08:34

Qt Qt 4.5.3 移植

2011-06-21 14:34:30

Qt Designer mini2440

2011-06-28 13:02:06

Qt Qt 4.7.3 ARM

2011-06-20 10:27:24

Mini2440 Qtopia Qt

2011-06-17 09:58:26

Qt Chapter QObject

2011-06-17 10:19:11

Qt QWidge QSetting

2011-06-13 11:24:55

QT MPlayer 移植

2011-04-22 09:32:56

开发板Ubuntu串口

2011-07-05 13:32:45

QT Mysql 驱动

2011-07-02 13:24:39

QT Linux

2011-06-15 18:20:20

Qt 移植 Android

2011-06-13 15:57:26

linux QT QTOPIA

2011-06-24 08:46:37

Linux Qt x11 4.5

2011-07-04 10:56:10

Qt 移植 编译

2011-06-29 10:46:01

Qt Eembedded Linux

2011-07-04 15:13:31

QT MPlayer 移植

2011-06-30 16:08:05

Qt 字库 QPF

2011-06-30 15:51:39

点赞
收藏

51CTO技术栈公众号