Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7687553
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2012-01-17 09:46:25

Linux系统提供了input子系,按键、触摸屏、鼠标等都可以利用input接口函数来实现设备驱动。

设备描述

Linux内核中,input设备用nput_dev结构体描述,使用input子系统实现输入设备驱动的时候,驱动的核心工作是向系统报告按、触摸屏、键盘、鼠标等输入事件event,通过input_event结构体描述),不再需要关心文件操作接口,因为input子系统已经完成了件操作接口。驱动报告的事件经过InputCoreEventhandler最终到达用户空间。

设备注册/注销

v注册输入设备的函数为:

int input_register_device(struct input_dev *dev)

v注销输入设备的函数为:

void input_unregister_device(struct input_dev *dev)

驱动实现-事件支持

设备驱动通过set_bit()告诉input子系统它支持哪些事件,如下所示:

set_bit(EV_KEY, button_dev.evbit)

Struct iput_dev中有两个成员,一个是evbit;一个是keybit。分别用来表示设备所支持的事件类型和按键类型。

事件类型:

EV_RST Reset  EV_KEY 按键

EV_REL 相对坐标 EV_ABS 绝对坐标

EV_MSC 其它 EV_LED LED

EV_SND 声音 EV_REP Repeat

EV_FF 力反馈

驱动实现-报告事件

用于报告EV_KEYEV_RELEV_ABS事件的函数分别为:

void input_report_key(struct input_dev *dev,unsigned int code, int value)

void input_report_rel(struct input_dev *dev,unsigned int code, int value)

void input_report_abs(struct input_dev *dev,unsigned int code, int value)

code

事件的代码。如果事件的类型是EV_KEY,该代码code为设备键盘代码。代码值0~127为键盘上的按键代码,0x110~0x116 为鼠标上按键代码,其中0x110(BTN_LEFT)为鼠标左键,0x111(BTN_RIGHT)为鼠标右键,0x112(BTN_ MIDDLE)为鼠标中键。其它代码含义请参看include/linux/input.h文件

value

事件的值。如果事件的类型是EV_KEY,当按键按下时值为1,松开时值为0

input_sync()用于事件同步,它告知事件的接收者:驱动已经发出了一个完整的报告。例如,在触摸屏设备驱动中,一次坐标及按下状态的整个报告过程如下:

input_report_abs(input_dev, ABS_X, x); //X坐标

input_report_abs(input_dev, ABS_Y, y); //Y坐标

input_report_abs(input_dev, ABS_PRESSURE, pres);//压力

input_sync(input_dev); //同步

 

实例分析

/*在按键中断中报告事件*/

static void button_interrupt(int irq, void *dummy, struct pt_regs *fp)

{

    input_report_key(&button_dev, BTN_0, inb(BUTTON_PORT0));

    input_report_key(&button_dev, BTN_0, inb(BUTTON_PORT1));

    input_sync(&button_dev);

}

static int _ _init button_init(void){

    /*申请中断*/

    if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL))

        return - EBUSY;

    set_bit(EV_KEY, button_dev.evbit)//支持EV_KEY事件

    set_bit(BTN_0, button_dev.keybit); //设备支持两个键

    set_bit(BTN_1, button_dev.keybit);

    input_register_device(&button_dev); //注册input设备

}

 

应用程序

struct input_event

{

    struct timeval time; //按键时间

    __u16 type; //类型,在下面有定义

    __u16 code; //要模拟成什么按键

    __s32 value;//是按下还是释放

}

 

struct input_event ev_mouse[2];

fd = open ("/dev/input/event3",O_RDWR);

 

while(1)

{

    count=read(fd, ev_mouse, sizeof(struct input_event));

    for(i=0;i<(int)count/sizeof(struct input_event);i++)

    {

        if(EV_REL==ev_mouse[i].type)

        {

            printf(“time:%ld.%d”,ev_mouse[i].time.tv_sec,ev_mouse[i].time.tv_usec);

            printf(“ type:%d code:%d value:%d\n",ev_mouse[i].type,ev_mouse[i].code,ev_mouse[i].value);

        }

 

        if(EV_KEY==ev_mouse[i].type)

        {

            printf("time:%ld.%d",ev_mouse[i].time.tv_sec,ev_mouse[i].time.tv_usec);

            printf(" type:%d code:%d value:%d\n",ev_mouse[i].type,ev_mouse[i].code,ev_mouse[i].value);

        }

    }

}

 

源码: Source.rar   

阅读(3459) | 评论(0) | 转发(2) |
0

上一篇:终端控制台体系

下一篇:USB的发展历程

给主人留下些什么吧!~~