首页 > 代码库 > 输入子系统

输入子系统

本篇文章通过按键驱动为例讲解输入子系统的开发流程。

输入子系统由驱动层、输入子系统核心、事件处理层三部分组成。一个输入事件,如鼠标移动、键盘按下等通过Driver->Inputcore->Event handler->userspace的顺序到达用户控件的应用程序。

用于报告EV_KEY,EV_REL,EV_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)

以上函数调用input_event函数上报事件。

set_bit告诉input输入子系统支持哪些事件,哪些按键。

事件类型包括EV_RST,EV_REL,EV_MSC,EV_KEY,EV_ABS,EV_REP等。

变量定义及初始化
struct pin_desc{     int irq;     char *name;     unsigned int pin;     unsigned int key_val;};struct pin_desc pins_desc[4] = {     {IRQ_EINT0,  "S2", S3C2410_GPF0,   KEY_L},     {IRQ_EINT2,  "S3", S3C2410_GPF2,   KEY_S},     {IRQ_EINT11, "S4", S3C2410_GPG3,   KEY_ENTER},     {IRQ_EINT19, "S5",  S3C2410_GPG11, KEY_LEFTSHIFT},};static struct input_dev *buttons_dev;static struct pin_desc *irq_pd;static struct timer_list buttons_timer;

1.分配input_dev结构体

buttons_dev = input_allocate_device();

2.设置

2.1设置能产生哪类事件
set_bit(EV_KEY, buttons_dev->evbit);//按键类事件set_bit(EV_REP, buttons_dev->evbit);//重复类事件
2.2设置能产生这类操作里的哪些事件
set_bit(KEY_L, buttons_dev->keybit);set_bit(KEY_S, buttons_dev->keybit);set_bit(KEY_ENTER, buttons_dev->keybit);set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);
3.注册
input_register_device(buttons_dev);
4.初始化定时器,用于消除按键的抖动
init_timer(&buttosn_timer);buttons_timer.function = buttons_timer_function;add_timer(&buttons_timer);
5.申请按键中断
for (i=0;i<4;i++) {      request_irq(pins_desc[i].irq, buttons_irq, IRQT_BOTHEDGE, pins_desc[i].name, &pins_desc[i]);}

6.中断处理函数,在中断中保存当前按下按键的信息,并打开定时器

static irqreturn_t buttons_irq(int irq, void *dev_id){     irq_pd = (struct pin_desc*)dev_id;     mod_timer(&buttons_timer, jiffies + HZ/100);     return IRQ_RETVAL(IRQ_HANDLed);}
7.定时器中断,用于消除按键抖动,上报事件
static void buttons_timer_function(unsigned long data){     struct pin_desc *pindesc = irq_pd;     unsigned int pinval;      if (!pindesc) {          return;     }     pinval = s3c2410_gpio_getpin(pindesc->pin);     if (pinval) {          /* 松开 */          input_event(buttons_dev, EV_KEY, pindesc->key_val, 0);//上报事件          input_sync(buttons_dev);                //同步用于告诉input core子系统报告结束     } else {          /* 按下 */          input_event(buttons_dev, EV_KEY, pindesc->key, 1);          input_sync(buttons_dev);     }}