当前位置: 代码迷 >> 综合 >> Qtopia4.2.5移植及按键驱动的调试总结
  详细解决方案

Qtopia4.2.5移植及按键驱动的调试总结

热度:0   发布时间:2024-01-11 15:09:33.0

http://blog.csdn.net/Leixin525/archive/2010/12/29/6105703.aspx

 

 

目的:移植 Qtopia4.2.5 devkit8000 ,并调试按键功能

平台: fedroa13 + arm-2008q1

下载资源: qtopia4 可以在 http://ftp.roedu.net/mirrors/ftp.trolltech.com/qtopia/snapshots/ 下载到,我用的是 qtopia-opensource-src-4.2.5-snapshot-20070915

 

(1)       编译 qtopia

Tar zxvf qtopia-opensource-src-4.2.5-snapshot-20070915

Mv qtopia-opensource-src-4.2.5-snapshot-20070915 qtopia-opensource-src-4.2.5

Cd qtopia-opensource-src-4.2.5( 因为我的编译器不是 arm-none-linux-gnueabi 的,所以我在编译的时候要修改编译器 )

修改编译器在这些文件中,我是自己 find 出来的,可能不完全正确,但是我编译运行时没有问题的,如果需要自己修改编译器可以自己查找一下

find ./ -name "*" | xargs grep 'arm-linux-', 然后分析哪些文件需要修改,一般是 qtopia,qtopiacore, 和一些 tools 。我需要修改的文件是

./qtopia-opensource-src-4.2.5/devices/greenphone/mkspecs/qws/linux-greenphone-g++/qmake.conf         qtopia 的配置文件)

./qtopia-opensource-src-4.2.5/devices/greenphone/rootfs/wpa_supplicant/config

./qtopia-opensource-src-4.2.5/devices/greenphone/rootfs/ilib/cross-compile.patch

./qtopia-opensource-src-4.2.5/src/3rdparty/libraries/helix/trolltech/src/build/umakecf/linux-2.2-libc6-armv5te-cross-gcc3.3-iwmmxt-vfp.cf

./qtopia-opensource-src-4.2.5/src/3rdparty/libraries/helix/trolltech/src/build/umakecf/linux-2.2-libc6-arm9-cross-gcc4.cf

./qtopia-opensource-src-4.2.5-snapshot-20070908/src/3rdparty/libraries/helix/trolltech/src/build/umakecf/linux-2.2-libc6-xscale-cross-gcc32.cf

./qtopia-opensource-src-4.2.5-snapshot-20070908/qtopiacore/qt/mkspecs/qws/linux-arm-g++/qmake.conf       qtopiacore 的配置)

将里面的 arm-linux- 全部换成我自己编译器 arm-none-linux-gnueabi-

qtopia4 不能直接在目录中进行 config ,我们需要新建一个目录来进行 config

mkdir ../build

cd ../build

../qtopia-opensource-src-4.2.5/configure -debug -image /opt/qtopia4 -prefix /opt/qtopia4 -xplatform linux-arm-g++ -arch arm -no-qvfb -displaysize 640x480 -no-modem -quicklaunch -no-bluetooth -no-drm -no-infrared -extra-qtopiacore-config "-qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg" -extra-qtopiacore-config "-debug -xplatform qws/linux-arm-g++ -embedded arm -opengl -qconfig qpe -qt-sql-sqlite -depths 4,8,16,32 -qt-kbd-vr41xx -qt-mouse-linuxtp -no-mouse-pc -no-mouse-bus -no-mouse-yopy -no-mouse-tslib -no-mouse-qvfb"

配置选项可以根据自己的需要进行裁剪

出现问题:

(1) The system byte order could not be detected!
Turn on verbose messaging (-v) to see the final report.You can use the -little-endian or -big-endian switch to

解决办法:这个是配置大段或者小端模式,自己在配置选项中加上后还是一样的效果,所以干脆在配置文件中添加

                        Vi vi qtopiacore/qt/configure

CFG_ENDIAN=Q_LITTLE_ENDIAN (默认是 auto 。也可以改为 Q_BIG_ENDIAN( 大端模式 )

(2) 出现 linux-cunstom-arm-g++.h file not found 的错误,这个错误在编译 qtopia2.2 的时候也出现过

解决办法: cp src/libraries/qtopiabase/custom-linux-cassiopeia-g++.cpp src/libraries/qtopiabase/custom-linux-arm-g++.cpp

                   cp src/libraries/qtopiabase/custom-linux-cassiopeia-g++.h src/libraries/qtopiabase/custom-linux-arm-g++.h

                   配置 Qtopia ok

                   编译: make && make install

                   编译的时候出现一个错误, asm/page.h not found , 其实在 qtopia4.2.5 中没有用到这个头文件,我们只需要注释掉就可以了

                   继续 make && make install 完成,编译完后再 /opt/Qtopia 生成了我们的目标文件

        

         修改按键功能(仅供参考):

                   经常我们的按键是自己设计的 GPIO 按键,因此是没有办法直接工作的,我们需要修改 qtopia 按键操作源码。

                   Qtopia4 按键操作源码在 qtopiacore/qt/src/gui/embedded/ 提供,提供各种鼠标按键操作。

                   我在配置的时候设置按键为 -qt-kbd-vr41xx ,因此对 qkbdvr41xx_qws.cpp 进行修改,主要是参照键盘测试程序进行修改

                   一般需要修改的地方是设备打开,读取哪些操作,直接上代码:

 

原理:我们用自己的设备操作的方法代理 qtopia 默认的设备操作就,这样 qtopia 启动都就可以识别操作我们自定义的设备了!

 

#include "qkbdvr41xx_qws.h"

 

#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_VR41XX)

 

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

#include <fcntl.h>

#include <termios.h>

#include <unistd.h>

#include <errno.h>

 

#include <linux/input.h>           //struct input_event 需要用到 linux/input.h 中的 input_evet 结构体

 

#include <qsocketnotifier.h>

 

#define BITS_PER_LONG (sizeof(long) * 8)                        // 自己驱动操作需要用到的宏

#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)

 

#ifndef EV_SYN

#define EV_SYN 0

#endif

 

 

class QWSVr41xxKbPrivate : public QObject

{

    Q_OBJECT

public:

    QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QString&);

    virtual ~QWSVr41xxKbPrivate();

 

    bool isOpen() { return buttonFD > 0; }

 

private slots:

    void readKeyboardData();

 

private:

    QString terminalName;

    int buttonFD;

    int kbdIdx;

    int kbdBufferLen;

    int version;

    unsigned char *kbdBuffer;

    QSocketNotifier *notifier;

    QWSVr41xxKeyboardHandler *handler;

    struct input_event ev[64];

};

 

QWSVr41xxKeyboardHandler::QWSVr41xxKeyboardHandler(const QString &device)

{

    d = new QWSVr41xxKbPrivate(this, device);

}

 

QWSVr41xxKeyboardHandler::~QWSVr41xxKeyboardHandler()

{

    delete d;

}

 

QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QString &device) : handler(h)

{

    terminalName = device;

    if (terminalName.isEmpty())

        terminalName = "/dev/event0";                        // 修改指向自己的驱动设备文件

    buttonFD = -1;

    notifier = 0;

 

    unsigned long bit[EV_MAX][NBITS(KEY_MAX)];

    unsigned short id[4];

    char name[256]="Unknown";

 

    buttonFD = open(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);

    if (buttonFD < 0) {

        qWarning("Cannot open %s/n", qPrintable(terminalName));

        return;

    }

 

    if(ioctl(buttonFD,EVIOCGVERSION,&version)){                 // 驱动的版本

        qWarning("Cannot get version");

    }

    qDebug("Input driver version is %d.%d.%d/n",

                 version >> 16, (version >> 8) & 0xff, version & 0xff);

 

    //input device ID :

    ioctl(buttonFD,EVIOCGID,id);                                                //ID

    qDebug("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x/n",

                id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]);

 

    ioctl(buttonFD,EVIOCGNAME(sizeof(name)),name);      //NAME

    qDebug("input device name : /"%s/"/n",name);

 

    memset(bit,0,sizeof(bit));                                             // 初始化设备空间

    ioctl(buttonFD,EVIOCGBIT(0,EV_MAX),bit[0]);

    qDebug("..................memset................/n");

 

    if (buttonFD >= 0) {

        notifier = new QSocketNotifier(buttonFD, QSocketNotifier::Read, this);

        connect(notifier, SIGNAL(activated(int)),this,

                SLOT(readKeyboardData()));

    }

 

    kbdBufferLen = 80;

    kbdBuffer = new unsigned char [kbdBufferLen];

    kbdIdx = 0;

}

 

QWSVr41xxKbPrivate::~QWSVr41xxKbPrivate()

{

    if (buttonFD > 0) {

        ::close(buttonFD);

        buttonFD = -1;

    }

    delete notifier;

    notifier = 0;

     delete [] kbdBuffer;

}

 

void QWSVr41xxKbPrivate::readKeyboardData()

{

    int n = 0 ;

    int i = 0 ;

    int keycode = 0 ;

    int mycode = 0 ;

 

    qDebug("......QWSVr41xxKbPrivate::readKeyboardData()......");

 

    n = read(buttonFD,ev,sizeof(struct input_event)*64);                      // 读设备

 

    qDebug("read device : read() ....");

 

    if(n < (int)sizeof(struct input_event)){

         qDebug("event : error reading ...");

    }

 

    for(i=0;i<n/sizeof(struct input_event);i++){

         if(ev[i].type==EV_SYN){

             qDebug("----------------------Config Sync-----------------------");

         }else{

             mycode = ev[i].code ;

        }

 

        switch (mycode){                                                                        //mycode 是获取的驱动传过来的 keycode

            case 188:                                                                           //keycode 是传给 Qtopia keycode

                keycode = Qt::Key_Up;

                break;

            case 193:

                keycode = Qt::Key_Right;

                break;

            case 6:

                keycode = Qt::Key_Down;

                break;

            case 194:

                keycode = Qt::Key_Left;

                break;

            case 14:

                keycode = Qt::Key_Context1;

                break;

            case 62:

                keycode = Qt::Key_Back;

                break;

            case 88:

                 keycode = Qt::Key_Select;

                break;

            case 87:

                keycode = Qt::Key_Menu;

                break;

                      case 68:

                                     keycode = Qt::Key_1;

                                     break;

                      case 67:

                                     keycode = Qt::Key_2;

                                     break;

                      case 66:

                                     keycode = Qt::Key_3;

                                     break;

                      case 65:

                                     keycode = Qt::Key_4;

                                     break;

                      case 192:

                                     keycode = Qt::Key_5;

                                     break;

                      case 191:

                                     keycode = Qt::Key_6;

                                     break;

                      case 190:

                                     keycode = Qt::Key_7;

                                     break;

                      case 189:

                                     keycode = Qt::Key_8;

                                     break;

                      case 10:

                                     keycode = Qt::Key_9;

                                     break;

                      case 9:

                                     keycode = Qt::Key_0;

                                     break;

                      case 8:

                                     keycode = Qt::Key_multiply;

                                     break;

            default:

                qDebug("Unrecognised key sequence %d", (int)mycode);

        }

         qDebug("keycode number %d : " , keycode);                                                // 处理 keycode 事件

        handler->processKeyEvent(0, keycode, 0, true, false);

    }

}

 

#include "qkbdvr41xx_qws.moc"

 

#endif // QT_NO_QWS_KBD_VR41XX