基于2440的Qt环境移植,且开发Qt跨平台程序


1、tslib编译和安装

其他不多说,jz2440出厂移植的是Qtopia-free-2.2.0,在Qtopia 4.*版本中,默认的Tslib版本为Tslib 1.4。在Qtopia 2.*版本中,默认的Tslib版本为Tslib 1.3

tslib-1.4.tar.gz下载链接http://vdisk.weibo.com/s/AcUHxOERV2k0


1.1编译tslib库

下载完成后,在命令行输入

tar -xzf tslib-1.4.tar.gz

cd进入该目录

首先安装以下依赖

sudo apt-get install autoconf

sudo apt-get install automake

sudo apt-get install libtool

如果不安装依赖执行.autogen.sh则会出现找不到文件中的libtoolize,aclocal,autoheader,automake

echo -n "Libtoolize..."
libtoolize --force --copy
echo "Done."
echo -n "Aclocal..."
aclocal
echo "Done."
echo -n "Autoheader..."
autoheader
echo "Done."
echo -n "Automake..."
automake --add-missing --copy
echo "Done."
echo -n "Autoconf..."
autoconf

安装完成后,接着执行

./autoge.sh

配置tslib

./configure --host=arm-linux --prefix=/usr/local/tslib  ac_cv_func_malloc_0_nonnull=yes    这边我直接安装到/usr/local/tslib

编译tslib

make   (确保是交叉编译器,因为i我们要给ARM平台用的 这边用的arm-linux-gcc)

make过程中没出现什么问题(如果有 自行谷歌,百度)

安装tslib

执行make installz则会把tslib库安装到配置时的目录下

安装完成可以看到bin etc include lib目录

测试tslib 等等在测试


2 移植Qt

思路先理清楚,首先下载qt-everywhere-opensource-src-4.8.6.tar.gz,接着配置源码,编译源码,安装源码

下载qt-everywhere-opensource-src-4.8.6.tar.gz

链接地址:http://mirrors.ustc.edu.cn/qtproject/archive/qt/4.8/4.8.6/

下载完成后,

解压:tar -xzf qt-everywhere-opensource-src-4.8.6.tar.gz

cd到目录

编写autogen.sh脚本文件

#!/bin/sh
./configure \
-opensource \
-confirm-license \
-release -shared \
-embedded arm \
-xplatform qws/linux-arm-g++ \
-depths 16,18,24,32 \
-fast \
-optimized-qmake \
-pch \
-qt-sql-sqlite \
-qt-libjpeg \
-qt-zlib \
-qt-libpng \
-qt-freetype \
-system-libjpeg \
-little-endian -host-little-endian \
-no-qt3support \
-no-libtiff -no-libmng \
-no-opengl \
-no-mmx -no-sse -no-sse2 \
-no-3dnow \
-no-openssl \
-no-webkit \
-no-qvfb \
-no-phonon \
-no-nis \
-no-opengl \
-no-cups \
-no-glib \
-no-xcursor -no-xfixes -no-xrandr -no-xrender \
-no-separate-debug-info \
-nomake examples -nomake tools -nomake docs \
-qt-mouse-tslib \
-I/usr/local/tslib/include \
-L/usr/local/tslib/lib \
-D__ARM_ARCH_5TEJ__ 

exit


这边着重说说 qt-libjpeg 和system-jpeg,待会要用到这个小知识点

qt-libjpeg是指使用qt自己编译的库文件,比如qt资源文件中的jpeg格式的文件

system-jpeg是指使用本地jpeg格式的图片文件

配置会出现

The tslib functionality test failed!
 You might need to modify the include and library search paths by editing
 QMAKE_INCDIR and QMAKE_LIBDIR in
 /home/zdw/qt-everywhere-opensource-src-4.8.6/mkspecs/qws/linux-arm-g++.

解决方法:

cd到该目录/home/zdw/qt-everywhere-opensource-src-4.8.6/mkspecs/qws/linux-arm-g++.

打开qmake.conf文件

修改成

#
# qmake configuration for building with arm-linux-g++
#


include(../../common/linux.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
include(../../common/qws.conf)


QMAKE_INCDIR=/usr/local/tslib/include
QMAKE_LIBDIR=/usr/local/tslib/lib


# modifications to g++.conf
QMAKE_CC                = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-gcc
QMAKE_CXX               = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-g++
QMAKE_LINK              = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-g++
QMAKE_LINK_SHLIB        = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-g++


# modifications to linux.conf
QMAKE_AR                = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-ar cqs
QMAKE_OBJCOPY           = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-objcopy
QMAKE_STRIP             = /opt/gcc-3.4.5-glibc-2.3.6/bin/arm-linux-strip


load(qt_config)

意思就是修改成交叉编译器的绝对路径

重新sudo ./autogen.sh

接着 往下看, 就是传说中的make了

这是我在编译时遇到的问题


/qthread_unix.o thread/qthread_unix.cpp thread/qthread_unix.cpp:125: error: thread-local storage not supported for this target
解决方法:
解決方式: 開啟qthread_unix.cpp,在122行後undefine HAVE_TLS,使原本124行的#ifdef HAVE_TLS不成立 gedit src/corelib/thread/qthread_unix.cpp
加入內容:
#ifdef HAVE_TLS

#undef HAVE_TLS
#endif


{standard input}:311: Error: register or shift expression expected -- `orr r2,r1,lsl#16'
{standard input}:321: Error: register or shift expression expected -- `orr r3,r1,lsl#16'
{standard input}:329: Error: register or shift expression expected -- `orr r2,ip,lsl#16'
{standard input}:467: Error: register or shift expression expected -- `orr r2,r1,lsl#16'
{standard input}:475: Error: register or shift expression expected -- `orr r3,r0,lsl#16'
make[1]: *** [.obj/release-shared-emb-arm/ftbbox.o] Error 1
解決方式: 開啟ftconfig.h,修改第330行的內容
gedit src/3rdparty/freetype/include/freetype/config/ftconfig.h
修改內容:
(原本的為)  "orr %0, %2, lsl #16\n\t" /* %0 = %2 << 16 */
(修改後為)  "orr %0, %0, %2, lsl #16\n\t" /* %0 = %2 << 16 */


../3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h:328:6: #error "Not supported ARM architecture"
解决方法:
在configure 时在后面加上 -D__ARM_ARCH_5TEJ__


../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h: In function 'int QTWTF::atomicIncrement(volatile int*)':
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h:253: error: '__sync_add_and_fetch' was not declared in this scope
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h: In function 'int QTWTF::atomicDecrement(volatile int*)':
../3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h:254: error: '__sync_sub_and_fetch' was not declared in this scope
解決方式: 開啟Threading.h,將第251、253、254行變成註解
gedit src/3rdparty/javascriptcore/JavaScriptCore/wtf/Threading.h
修改後內容:
//#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
//
//inline int atomicIncrement(int volatile* addend) { return __sync_add_and_fetch(addend, 1); }
//inline int atomicDecrement(int volatile* addend) { return __sync_sub_and_fetch(addend, 1); }

如果有其他错误自行谷歌百度(加油,相信你可以的)

至此编译成功。



接着安装

sudo make install 

默认安装到ubuntu的根文件系统下的/usr/local/Trolltech/QtEmbedded-4.8.6-arm(建议不要修改安装路径,意思就是修改了也是安装到这边,不是耍你,我自己也被Qt/E耍了)

安装以后,出现以下目录


至此,Qt和tslib-1.4都编译安装好了

但是如何才能让2440用起来?当然就是制作文件系统,如何制作最小根文件系统,请看韦东山老师的一期视频,这里假设有最小根文件系统

首先,我们挂接nfs网络根文件系统,用作调试,(要注意的点是,ubuntu防火墙要关,如果是虚拟机的话要设置成桥接模式)

1、ubuntu下安装 nfs服务

sudo apt-get nfs-kernel-server

然后 打开/etc/目录下的exports文件

gedit /etc/exports

添加

/home/zdw/fs_qt4.8.5 *(rw,sync,no_root_squash,no_subtree_check) //路径填自己的

重启ubuntu或者 /etc/init.d/nfs-kernel-server restart

2、在开发板上进入uboot命令行 设置bootargs参数

set bootargs noinitrd root=/dev/nfs/ nfsroot=192.168.1.127:/home/zdw/fs_qt4.8.6 ip=192.168.1.126:192.168.1.127:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0

(其中:192.168.1.126为开发板的IP,192.168.1.127为ubuntu的IP,192.168.1.1为网关)

重启开发板,即可挂接最小根文件系统


以下都是对最小根文件系统进行操作

工作目录为最小根文件系统中

3、上面不是安装了tslib1.4,这边就要用起来了

/usr/local/tslib/bin/目录下的文件ts_calibrate和ts_test拷贝到根文件系统的bin目录下

将/usr/local/tslib/lib文件下除去pkgconfig目录外其他所有文件拷贝到最小根文件系统/lib目录下

将/usr/local/tslib/etc下的ts.conf拷贝到最小根文件系统的/etc下,修改ts.conf文件。

下面是ts.conf文件的第一行与第二行

# Uncomment if you wish to use the linux input layer event interface

# module_raw input

去掉# module_raw input前面的注释,一定要注意中间的空格也去掉,module顶格。

然后在etc目录下创建profile脚本文件添加以下内容(注意JZ2440的触摸屏设备结点为event0,LCD设备节点为fb0)

#!/bin/sh
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

保存

设置可执行权限

chmod +x etc/profile

然后打开etc/init.d/rcS

gedit etc/init.d/rcS

添加/etc/profile

重启开发板

执行ts_calibrate

开发板就会出现校准屏幕,同时串口输出坐标信息。

etc目录下就会出现pointeral校准文件

至此tslib移植成功

5、移植QtEmbedded-4.8.6-arm

将ubuntu的文件系统/usr/local/Trolltech目录下QtEmbedded-4.8.6-arm拷贝到根文件系统下usr/local目录下


接着设置环境变量


cd到最小根文件系统目录下

在最小根文件系统下打开/etc/profile脚本文件

gedit  etc/profile

添加以下内容

export QWS_SIZE=480x272

export set QTDIR=/usr/local/QtEmbedded-4.8.6-arm   #目录名要与拷贝的Qt文件名一致
export set LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export set PATH=$QTDIR/bin:$PATH   
export set MANPATH=$QTDIR/man:$MANPATH             
export set QT_QWS_FONTDIR=/usr/local/QtEmbedded-4.8.6-arm/lib/fonts
export set QWS_MOUSE_PROTO=tslib:/dev/event0


由于开发Qt程序需要用图片库所以继续添加以下内容

#使用Qt自带的编译的图片库
export LD_LIBRARY_PATH=/usr/local/QtEmbedded-4.8.6-arm/plugins/imageformats:$LD_LIBRARY_PATH
export QT_PLUGIN_PATH=/usr/local/QtEmbedded-4.8.6-arm/plugins


这些内容根据Qt程序要用到什么东西就添加库路径就好了

重启开发板

至此算是Qt移植成功了



在开发板上cd到/usr/local/QtEmbedded-4.8.6-arm/demos目录下

执行示例代码

cd textedit

./textedit -qws

必须加-qws



下面介绍制作移植Qt后根文件系统映像


目标板是JZ2440 DRAM为64M


用dnw或者tftp下载超过64M的东西都会失败

我们编译的Qt都要80几M制成映像那就要变成90几M所以肯定下载不成功

所以想到的就是裁剪,毕竟是linux裁剪是经常事


这边采用的不是配置上还减少,因为现在剩下的可以用Qt开发的功能也是少得可怜(这边提一下 不能开发QWidget,没有配置-qwidget)

首先编译好的Qt目录下的bin对运行在ARM板子上是没有意义的,所以删除(21.9M呢)

demos目录也没用,删除

最后剩下imports include lib mkspecs plugins 目录就可以了

mkspecs目录下也是一些文件没用,没猜错的话就用得上qws目录下的linux-arm-g++目录下的文件

其他也可以删(没试过 只是删除把win的删了)

根据要运行的Qt程序删除一些没有用到的库(这个要求你要懂一些Qt基本东西)(就是程序用到哪些类 你在lib目录下别删和类相同的库文件)

include目录也是一样(删除一些没用的头文件)


现在制成文件系统映像大概小于64M了接近62M左右

就可以下载到2440板子上这边用的是tftp下的

我也是遇到这样的问题

Warning: unable to open an initial console. Failed to execute /linuxrc.  Attempting defaults... Kernel panic - not syncing: No init found.  Try passing init= option to kernel.

原因是我从内存中拷贝到文件系统地址方式的问题


tftp 30000000 fs_qt4.8.6.yaffs2
nand erase root  擦除root分区
nand write.yaffs 30000000 260000 $(filesize)

这样就可以了


然后

重启开发板 遇到不能执行Qt程序和触摸屏测试程序

遇到段错误

,一开始觉得不可能啊 怎么会这样 我又重新挂接nfs根文件系统又没问题,我重新看了配置问题,感觉应该是校准问题,我删了重启开发板执行ts_calibrate程序,就解决问题

为防止日后出现相同问题

在etc目录下的profile脚本文件添加 -e针对单个文件()

if [ ! -e /etc/pointercal ] //如果etc目录下没有pointercal执行文件
then
/bin/ts_calibrate
fi

如果想要开机执行Qt程序也是在脚本中添加

/video/video -qws &


接下去安装嵌入式Qt开发环境

下载qtcreator     资源qt-creator-linux-x86-opensource-2.6.0.bin

下载链接:http://pan.baidu.com/s/1pKOfzbP 或者到官网下,百度谷歌

安装qtcreator 

sudo qt-creator-linux-x86-opensource-2.6.0.bin

自己选择安装目录

跟window系统软件安装一样,后面可用设置ubuntu桌面快捷方式具体实现方式参考如下

gedit Qt4.8.6.desktop

[Desktop Entry]
Categories=Development;
Comment[zh_CN]=
Comment=
Exec=/home/zdw/Qt/Qt5.5/Tools/QtCreator/bin/qtcreator  解释:这里放的是qtcreator的具体文件路径
GenericName[zh_CN]=IDE
GenericName=IDE
Icon=/home/zdw/Qt/Qtlcon.png  解释:这里放的是桌面快捷方式的图标路径
MimeType=
Name[zh_CN]=Qt5.5   解释:这里放的是桌面快捷方式的名称
Name=Qt5.5 
Path=
StartupNotify=true
Terminal=false
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=warsllon


或者直接添加环境变量

export PATH=/usr/local/qtcreator-2.6.0/bin:$PATH

这样就可以在终端直接输入qtcreator打开Qt的IDE了


配置交叉编译器

打开IDE在菜单栏下点击工具 接着点击选项

分到构建和运行



在Qt版本这里选择 我们之前编译安装的路径下的bin目录下的qmake,这个用来管理Qt工程文件的




这里换到Compilers 选择编译器路径,就是ARM平台的编译器,不过这是Qt框架是由C++写的所以C++的编译器是g++


这边这么设置吧 

接下来就可以开开心心玩转Qt跨ARM平台即2440了


编译Qt程序 点击IDE中的主界面的锄头


至此环境搭建好了



关于视频监控 我是采用定时器刷新视频服务器的图像信息

mainWindow.cpp文件内容

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QPixmap"
#include "QLabel"
#include "QDir"
#include "QFile"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    img=new QImage;
    scaledimg=new QImage;
    showTime=new QTimer;
    showTime->setInterval(50);//毫秒级
    Mkdirfile();
    QObject::connect(showTime,SIGNAL(timeout()),this,SLOT(flushPic()));
    manager = new QNetworkAccessManager(this);
    QObject::connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(slot_replyFinished(QNetworkReply*)));
    button_movieIsClicked = false;
}


MainWindow::~MainWindow()
{
    delete ui;
    QFile::remove("/root/mjpg-streamer/temp1.jpg");
}
void MainWindow::Mkdirfile()
{
    if(!QDir("/root/mjpg-streamer").exists())
    {
        QDir dir;
        dir.mkpath("/root/mjpg-streamer");
    }
}
void MainWindow::flushPic()
{
    request.setUrl(QUrl(PU));
    manager->get(request);
}
void MainWindow::slot_replyFinished(QNetworkReply *reply)
{
    if(button_movieIsClicked==true)
    {
    QPixmap pix;
    QByteArray data = reply->readAll();
    pix.loadFromData(data,"JPG");
    pix.save("/root/mjpg-streamer/tmp1.jpg","JPG",100);//文件名 图像格式 压缩率图片质量
    if(!(img->load("/root/mjpg-streamer/tmp1.jpg")))
    {
        showTime->stop();
        QMessageBox::information(this,tr("failed"),tr("open failed"));
        button_movieIsClicked=false;
        return;
    }
    *scaledimg=img->scaled(640,480,Qt::KeepAspectRatio);
    ui->PicLabel->setPixmap(QPixmap::fromImage(*scaledimg));
    }
    else
    {
        QPixmap pixmap(":/new/prefix1/背景.jpg");
        ui->PicLabel->setPixmap(pixmap);
    }
}
void MainWindow::on_ButtonMovie_clicked()
{
    Address=ui->AddressLineEdit->text();
    Port=ui->PortlineEdit->text();
    PU="http://"+Address+":"+Port+"/?action=snapshot";
    if(button_movieIsClicked==false)
    {
        button_movieIsClicked=true;
        ui->ButtonMovie->setText("finished");
        showTime->start();
    }
    else
    {
        button_movieIsClicked=false;
        ui->ButtonMovie->setText("video");
        showTime->stop();
    }
}

mainWindow.h文件内容

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QMainWindow>
#include "QtNetwork/QNetworkAccessManager"
#include "QtNetwork/QNetworkReply"
#include "QtNetwork/QNetworkRequest"
#include "QMessageBox"
#include "QTimer"
#include "QImage"


namespace Ui {
class MainWindow;
}


class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    QImage *img;
    QImage *scaledimg;
    QTimer *showTime;
    QNetworkAccessManager *manager;
    QNetworkRequest request;
    QString PU,Address,Port;
    bool button_movieIsClicked; //控制显示“视频”或者“结束”
    void Mkdirfile();


    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


public slots:
    void slot_replyFinished(QNetworkReply*reply);
    void flushPic();
    
private slots:
    void on_ButtonMovie_clicked();


private:
    Ui::MainWindow *ui;
};


#endif // MAINWINDOW_H


至于Qt可执行程序如何弄到2440上 比如挂载nfs服务



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值