嵌入式linux下QT3/Embedded的输入设备驱动接口

一、Qt3/Embedded的输入设备的驱动接口实现原理分析
       1、Qt3/Embedded把与底层硬件相关的源文件统一放在src/embedded目录下,所以我们最好也把自己的设备驱动接口文件放到此目录。

2、Qt/Embedded中的输入设备分为鼠标类与键盘类。在3.x版本系列中,鼠标设备的抽象基类为QWSMouseHandler,在src /embedded/qmouse_qws.h中定义,键盘设备的抽象基类为QWSKeyboardHandler,在src/embedded /qkbd_qws.h中定义。对于具体的输入设备我们则从这两个基类重新派生出它的实现类。

3、系统加载过程分析。Qt/Embedded在体系上为C/S结构,任何一个Qt/Embedded程序都可以作为系统中唯一的一个GUI Server存在。当应用程序首次以系统GUI Server的方式加载时,将建立QWSServer实体。在系统加载构造QWSServer时,将会调用QWSServer::openMouse与 QWSServer::openKeyboard函数 (建立QWSServer实体的源文件是src/kernel/qwindowsystem_qws.cpp)。这两个函数分别调用 QMouseDriverFactory::create()与QKbdDriverFactory::create()函数,它们分别是在 src/embedded/qmousedriverfactory_qws.h和src/embedded /qkbddriverfactory_qws.h中定义。这时会根据嵌入式Linux系统的环境变量QWS_MOUSE_PROTO与 QWS_KEYBOARD获得鼠标类设备和键盘类设备的设备类型和设备节点。打开相应设备并返回相应设备的基类句柄指针给系统,系统通过将该基类指令强制转换为对应的具体子类设备指针,获得对具体鼠标类设备和键盘类设备的调用操作。也就是说,我们只要把自己的设备类放在create()函数中即可。调用关系如下:
QWSServer::openMouse() à QMouseDriverFactory::create() à MyMouseHandler ← QWSMouseHandler
鼠标接口的加载过程
QWSServer::openKeyboard() à QKbdDriverFactory::create() à MyKeyboarddHandler ← QWSKeyboardHandler
键盘接口的加载过程

二、在QTE中实现自己的设备驱动接口
    经过上面的分析可以发现,要在QTE中实现自己的设备接口其实是很容易的事情。下面以键盘接口的实现为例,简单介绍一下具体的实现过程,鼠标接口也是差不多的。
在QTE中实现自己的键盘接口只需要三步:
1、从抽象基类QWSKeyboardHandler派生出具体类,如MyKbdHandler。为此我们在QTE的子目录src/embedded中新建两个文件mykbd_qws.h和mykbd_qws.cpp,内容如下:
(1) mykbd_qws.h的内容:
#ifndef MYKBD_QWS_H
#define MYKBD_QWS_H

#include "qkbd_qws.h"  //QT定义抽象基类QWSKeyboardHandler

#ifndef QT_NO_MYKBD   //编译时可以通过定义这个变量从而不编译这个模块

class MyKbdPrivate;   //我们的键盘设备私有类,实现具体的键盘设备操作,如打开键盘、读键盘数据,解析按键等等。

class MyKbdHandler : public QWSKeyboardHandler //供系统调用的键盘句柄
{
public:
    MyKbdHandler(const QString&);
    virtual ~MyKbdHandler();
private:
    MyKbdPrivate *d;
};

#endif // QT_NO_MYKBD
#endif // MYKBD_QWS_H

(2)mykbd_qws.cpp的内容:
#include "mykbd_qws.h"

#ifndef QT_NO_MYKBD

#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 <qsocketnotifier.h>

class MyKbdPrivate : public QObject
{
    Q_OBJECT
public:
    MyKbdPrivate( MyKbdHandler *h, const QString& );
    virtual ~MyKbdPrivate();

    bool isOpen() { return buttonFD > 0; }

private slots:
    void readKeyboardData();

private:
    QString terminalName;
    int buttonFD;
    int kbdIdx;
    int kbdBufferLen;
    unsigned char *kbdBuffer;
    QSocketNotifier *notifier;
    MyKbdHandler *handler;
};

MyKbdPrivate::MyKbdPrivate(MyKbdHandler *h, const QString &device ) : handler(h)
{
    terminalName = device.isEmpty()?"/dev/mykeyboard":device.latin1();
    buttonFD = -1;
    notifier = 0;

    if ((buttonFD = open(terminalName, O_RDWR | O_NDELAY, 0))
    {
        qWarning("Cannot open %s/n", terminalName.latin1());
    }

    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;
}

MyKbdPrivate::~ MyKbdPrivate()
{
    if ( buttonFD > 0 ) {
        ::close( buttonFD );
        buttonFD = -1;
    }
    delete notifier;
    notifier = 0;
    delete [] kbdBuffer;
}

void MyKbdPrivate::readKeyboardData()
{
int n = 0;
int idx = 0;
    n  = read(buttonFD, kbdBuffer+kbdIdx, 4);

    unsigned char *next = kbdBuffer + idx;
    int *code = (int *)next;
    int keycode = Qt::Key_unknown;

    switch ( (*code) & 0xff ) {
        case 11:
        keycode = Qt::Key_Backtab;
        break;
        case 12:
        keycode = Qt::Key_Return;
        break;
        case 13:
        keycode = Qt::Key_Tab;
        break;
        case 14:
        keycode = Qt::Key_Up;
        break;
        case 15:
        keycode = Qt::Key_Down;
        break;

        default:
qDebug("Unrecognised key code %d", *code );
    }

        handler->processKeyEvent( 0, keycode, 0, TRUE, FALSE );
         
}

MyKbdHandler::MyKbdHandler(const QString &device)
{
    d = new MyKbdPrivate( this, device );
}

MyKbdHandler::~MyKbdHandler()
{
    delete d;
}

#include "mykbd_qws.moc"

#endif // QT_NO_MYKBD

2、把MyKbdHandler加入QkbdDriverFactory::create()函数中。在src/embedded /qkbddriverfactory_qws.cpp文件中加入头文件:
#include “mykbd_qws.h”
然后找到QkbdDriverFactory::create()这个函数,在”Qstring  driver = key.lower();”这一行的后面加上以下几行:
#ifndef QT_NO_MYKBD
      if ( driver == “mykbd” || driver.isEmpty() )
            return new MyKbdHandler( device );
#endif
3、重新编译QT/Embedded并把生成的qt库文件下载到开发板上,然后在目标板上设置系统变量,输入命令:export  QWS_KEYBOARD=’MYKBD:/dev/mykeyboard’。
至此QT3/Embedded的键盘设备接口已经完成。

原文来自:
http://blog.mcuol.com/User/lyusheng/Article/4686_1.htm


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/68560/showart_1171680.html

你可能感兴趣的:(嵌入式linux下QT3/Embedded的输入设备驱动接口)