串口键盘在Qt上的移植

来源:互联网 发布:kali linux 性能 编辑:程序博客网 时间:2024/04/28 16:53

项目中用到Qt进行开发,其中键盘部分电路自己设计,所以qt自带的键盘驱动无法直接使用,需要进行一些简单的移植才可以。

键盘电路是用单片机扫描方式,通过串口与系统的连接。为了修改方便,直接拿qkbdtty_qws.cpp进行修改,同时修改的还有qkbdtty_qws.h和qkbddriverfactory_qws.cpp,这几个文件都在src/gui/embedded下面。

为了串口传送的数据具有一定的完整性,我在串口发送键值时,采用的是一次发送2字节,即键值和键值的反码,接收后方便校验。

编译方法:代码修改完成后,只编译gui的库即可,即到gui目录下make,所作的改动都在qt的libQtGui.so里面,编译完成后拷贝该库到目标板即可。当然,Qt的系统配置里面键盘要配置为tty,一般在profile里面配置。

下面是源码:

qkbddriverfactory_qws.cpp文件修改部分如下:

# ifndef QT_NO_QWS_KBD_TTY
    if (driver == QLatin1String("tty") || driver.isEmpty())
        return new QWSMyKeyboardHandler(device);
# endif


qkbdtty_qws.cpp源码:


#include "qkbdtty_qws.h"

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

#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 <private/qcore_unix_p.h>

#include <qsocketnotifier.h>


#include<stdio.h>      
#include<stdlib.h>     
#include<string.h>



int UART_Open(int fd,char* port)
{

  fd = open( port, O_RDWR|O_NOCTTY|O_NDELAY);
//fd = open( port, O_RDWR);
  if (FALSE == fd){
perror("Can't Open Serial Port");
  return(FALSE);
  }
  if(fcntl(fd, F_SETFL, 0) < 0){
printf("fcntl failed!\n");
    return(FALSE);
  } else {
           //    printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
  }
  if(0 == isatty(STDIN_FILENO)){
  printf("standard input is not a terminal device\n");
        return(FALSE);
  }
  return fd;
}
void UART_Close(int fd)
{
close(fd);
}
int UART_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
{
    
    int   i;
      int   status;
  int   speed_arr[] = { B115200,B57600,B38400, B19200, B9600, B4800, B2400, B1200, B300,
                        B115200,B57600,B38400, B19200, B9600, B4800, B2400, B1200, B300
                      };
    int   name_arr[] = {
       115200,57600,38400,  19200,  9600,  4800,  2400,  1200,  300,
       115200,57600,38400,  19200,  9600, 4800, 2400, 1200,  300
  };  
struct termios options;


if(tcgetattr( fd,&options)  !=  0){  
   perror("SetupSerial 1");     
   return(FALSE);  
    }
for(i= 0;i < sizeof(speed_arr) / sizeof(int);i++) {
if  (speed == name_arr[i]) {        
      cfsetispeed(&options, speed_arr[i]);  
      cfsetospeed(&options, speed_arr[i]);   
}
    }    
//options.c_cflag |= CLOCAL;
//options.c_cflag |= CREAD;
switch(flow_ctrl){
case 0 :
options.c_cflag &= ~CRTSCTS;
break;    
    case 1 :
    options.c_cflag |= CRTSCTS;
    break;
    case 2 :
    options.c_cflag |= IXON | IXOFF | IXANY;
    break;
}
    
options.c_cflag &= ~CSIZE;
switch (databits){   
case 5 :
    options.c_cflag |= CS5;
    break;
    case 6    :
    options.c_cflag |= CS6;
    break;
    case 7    :     
        options.c_cflag |= CS7;
        break;
    case 8:     
        options.c_cflag |= CS8;
        break;   
           default:    
        fprintf(stderr,"Unsupported data size\n");
        return (FALSE);
}
switch (parity) {   
    case 'n':
    case 'N':
        options.c_cflag &= ~PARENB;  
        options.c_iflag &= ~INPCK;     
        break;  
    case 'o':   
    case 'O':    
        options.c_cflag |= (PARODD | PARENB);  
        options.c_iflag |= INPCK;              
        break;  
    case 'e':  
    case 'E':   
        options.c_cflag |= PARENB;        
        options.c_cflag &= ~PARODD;        
        options.c_iflag |= INPCK;       
        break;
    case 's':
    case 'S':
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        break;  
        default:   
        fprintf(stderr,"Unsupported parity\n");    
        return (FALSE);
}  
switch (stopbits){   
    case 1:    
        options.c_cflag &= ~CSTOPB;  
        break;  
    case 2:    
        options.c_cflag |= CSTOPB;  
           break;
    default:    
             fprintf(stderr,"Unsupported stop bits\n");  
             return (FALSE);
}
    
   // options.c_oflag &= ~OPOST;
/*RAW mode*//*Input*/
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Ñ¡ÔñÔ­ÊŒÊäÈë·š
    options.c_iflag &= ~(ICRNL | INLCR | IGNCR);
 
    /*Output*/
    options.c_oflag &= ~OPOST; //Ñ¡ÔñÔ­ÊŒÊýŸÝÊä³ö   
    options.c_oflag &= ~(INLCR | IGNCR | ICRNL);
    options.c_oflag &= ~(ONLCR | OCRNL);

    options.c_cc[VTIME] = 0;  //阻塞
    options.c_cc[VMIN] = 2;   //最少接收2个字符

    tcflush(fd,TCIFLUSH);

    if(tcsetattr(fd,TCSANOW,&options) != 0){
    perror("kbd com set error!\n");   
    return (FALSE);  
    }
    ioctl(fd, TIOCMGET, &status);
 
    //ĬÈÏDTR, DSR ÓÐЧ
    status |= TIOCM_DTR;
    status |= TIOCM_DSR;
 
    ioctl(fd, TIOCMSET, status);
return (TRUE);  
}
int UART_Init(int fd, int speed,int flow_ctrlint ,int databits,int stopbits,char parity)
{

if (FALSE == UART_Set(fd,speed,flow_ctrlint,databits,stopbits,parity)) {        
return FALSE;
    } else {
       return  TRUE;
       }
}

int UART_Send(int fd, char *send_buf,int data_len)
{
    int ret;
    
    ret = write(fd,send_buf,data_len);
    if (data_len == ret ){    
   return ret;
    } else {    
   tcflush(fd,TCOFLUSH);    
   return FALSE;
        
    }
    
}
//////////////////////////////////////////////////////
class QWSMyKbPrivate : public QObject

{

Q_OBJECT

public:

QWSMyKbPrivate(QWSMyKeyboardHandler *handler, const QString &device);

~QWSMyKbPrivate();

bool isOpen() { return buttonFD > 0; }




private Q_SLOTS:

void readKeyboardData();




private:

QWSMyKeyboardHandler *m_handler;

QString terminalName;

int buttonFD;

int kbdIdx;

int kbdBufferLen;

unsigned char *kbdBuffer;

QSocketNotifier *notifier;

};


QWSMyKeyboardHandler::QWSMyKeyboardHandler(const QString &device)

: QWSKeyboardHandler(device)

{

d = new QWSMyKbPrivate(this, device);

}


QWSMyKeyboardHandler::~QWSMyKeyboardHandler()

{

delete d;

}


QWSMyKbPrivate::QWSMyKbPrivate(QWSMyKeyboardHandler *h, const QString &device)

: m_handler(h)

{

terminalName = device.isEmpty()?"/dev/ttyS1":device.toLatin1();

buttonFD = -1;

notifier = 0;

if ((buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR|O_NOCTTY|O_NDELAY)) < 0) //O_RDONLY| O_NDELAY

{

qWarning("Cannot open %s\n", terminalName.toLatin1());

}

qWarning("open /dev/ttyS1 OK!buttonFD=%d\n",buttonFD);


if ( buttonFD >= 0 )

{
UART_Init(buttonFD,9600,0,8,1,'N');

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

connect( notifier, SIGNAL(activated(int)),this,SLOT(readKeyboardData()) );

}

kbdBufferLen = 80;

kbdBuffer = new unsigned char [kbdBufferLen];

kbdIdx = 0;

}




QWSMyKbPrivate::~ QWSMyKbPrivate()

{

if ( buttonFD > 0 )

{

::close( buttonFD );

buttonFD = -1;

}

delete notifier;

notifier = 0;

delete [] kbdBuffer;;

}




void QWSMyKbPrivate::readKeyboardData()

{

int n = 0;

int idx = 0;

n = read(buttonFD, kbdBuffer+kbdIdx, 2);

unsigned char *next = kbdBuffer + idx;

int *code = (int *)next;

int keycode = Qt::Key_unknown;

int unicode = 0;

qDebug("Receive num= %d\n", n);
qDebug("Receive key code %d-%d\n", *next ,*(next+1));
if(*next+(*(next+1))!=0xff)
{
    qDebug("key check error!\n");
    return;
}

switch ( (*code) & 0xff )

{

case 0x30:
    keycode = Qt::Key_0;
    unicode='0';
    break;
case 0x31:
    keycode = Qt::Key_1;
    unicode='1';
    break;
case 0x32:
    keycode = Qt::Key_2;
    unicode='2';
    break;
case 0x33:
    keycode = Qt::Key_3;
    unicode='3';
    break;
case 0x34:
    keycode = Qt::Key_4;
    unicode='4';
    break;
case 0x35:
    keycode = Qt::Key_5;
    unicode='5';
    break;
case 0x36:
    keycode = Qt::Key_6;
    unicode='6';
    break;
case 0x37:
    keycode = Qt::Key_7;
    unicode='7';
    break;
case 0x38:
    keycode = Qt::Key_8;
    unicode='8';
    break;
case 0x39:
    keycode = Qt::Key_9;
    unicode='9';
    break;
    
case 0x0d:
    keycode = Qt::Key_Enter;
    break;
case 0x1b:
    keycode = Qt::Key_Escape;
    break;
case 0x09:
    keycode = Qt::Key_Tab;
    break;
case 0x08:
    keycode = Qt::Key_Backspace;
    break;
case 0x27:
    keycode = Qt::Key_Right;
    break;
case 0x25:
    keycode = Qt::Key_Left;
    break;
case 0x26:
    keycode = Qt::Key_Up;
    break;
case 0x28:
    keycode = Qt::Key_Down;
    break;

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

}

m_handler->processKeyEvent( unicode, keycode, 0, TRUE, FALSE );

m_handler->processKeyEvent( unicode, keycode, 0, FALSE, FALSE);


}


qkbdtty_qws.h源码:

#include "qkbdtty_qws.moc"

#endif // QT_NO_QWS_KEYBOARD || QT_NO_QWS_KBD_TTY


#ifndef QKBDTTY_QWS_H

#define QKBDTTY_QWS_H

#include <QtGui/qkbd_qws.h>

#ifndef QT_NO_QWS_KEYBOARD

#ifndef QT_NO_QWS_KBD_TTY




class QWSMyKbPrivate;




class QWSMyKeyboardHandler : public QWSKeyboardHandler

{

public:

QWSMyKeyboardHandler(const QString &);

virtual ~QWSMyKeyboardHandler();




private:




QWSMyKbPrivate *d;

};




#endif // QT_NO_QWS_KBD_TTY




#endif // QT_NO_QWS_KEYBOARD




#endif // QKBDTTY_QWS_H