zoukankan      html  css  js  c++  java
  • 键盘驱动的原理

    http://blog.csdn.net/zhenwenxian/article/details/6064299

     

    键盘驱动的设置

    1,一般要初始化矩阵键盘的行数和列数,设置矩阵的扫描驱动线的开始gpio,设置矩阵的扫描输入线的开始gpio,利用循环分别对每个扫描驱动线的gpio初始化为输出脚,利用循环分别对每个扫描输入线的gpio初始化为输入脚。

    2, 在模块加载函数中注册输入设备。

    注册输入设备的函数为:

    int input_register_device(struct input_dev *dev);

    3,在probe函数

    申请一个输入设备,告知input子系统它可以报告的事件。

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

    set_bit(EV_KEY, button_dev.evbit);

    初始化键盘的映射表,申请键盘中断,打开中断。

    4,实现中断处理函数,中断处理函数是响应中断,读出键盘的按键缓冲区的数据,对每个比特检查,看那个按键按下,将扫描码转换为按键码通过

    input_report_key() 报按键

    后面跟input_sync()用于事件同步,它告知事件的接收者驱动已经发出了一个完整的报告。

    getevent & sendevent
    getevent监控当前的事件,鼠标事件,按键事件,拖动滑动等
    在命令行通过pc键盘输入getevent可以监控当前的事件
    # getevent
    getevent
    add device 1: /dev/input/event0
      name: "qwerty2"
    /dev/input/event0: 0001 001e 00000001
    /dev/input/event0: 0001 001e 00000000

    其中/dev/input/event0是device的名字 0001是type, 001e是键码, 最后一个根据type不同而不同
    比如上面的倒数第二条就是按下a键的keydown,最后一个是按下a的keyup
    具体的type,code,value的定义可以在源码/frameworks/base/core/java/android/view/KeyEvent.java中找到

    sendevent发送时间,格式和上面的一样,需要注意的是在get中code显示的是十六进制,而send中需要用十进制,例如

    # sendevent /dev/input/event0 1 5 1
    这个命令就是发送数字4的keydown消息,所以在屏幕上就会一直打印出很多个4(因为没有发送keyup)

    http://linux-qcm-msm.sourcearchive.com/documentation/2.6.31-800.2/rpc__server__handset_8c-source.html

    static const uint32_t hs_key_map[] = {
     KEY(HS_PWR_K, KEY_POWER),
     KEY(HS_END_K, KEY_END),
     KEY(HS_STEREO_HEADSET_K, SW_HEADPHONE_INSERT),
     KEY(HS_HEADSET_SWITCH_K, KEY_MEDIA),
     0
    };

    static int hs_find_key(uint32_t hscode)
    {
          int i, key;

          key = KEY(hscode, 0);

          for (i = 0; hs_key_map[i] != 0; i++) {
                if ((hs_key_map[i] & 0xff000000) == key)
                      return hs_key_map[i] & 0x00ffffff;
          }
          return -1;
    }

    static void report_hs_key(uint32_t key_code, uint32_t key_parm)
    {
     int key, temp_key_code;

     if (key_code == HS_REL_K)
      key = hs_find_key(key_parm);
     else
      key = hs_find_key(key_code);

     temp_key_code = key_code;

     if (key_parm == HS_REL_K)
      key_code = key_parm;

     switch (key) {
     case KEY_POWER:
     case KEY_END:
     case KEY_MEDIA:
      input_report_key(hs->ipdev, key, (key_code != HS_REL_K));
      break;
     case SW_HEADPHONE_INSERT:
      report_headset_switch(hs->ipdev, key, (key_code != HS_REL_K));
      break;
     case -1:
      printk(KERN_ERR "%s: No mapping for remote handset event %d/n",
         __func__, temp_key_code);
      return;
     }
     input_sync(hs->ipdev);


  • 相关阅读:
    linux网络编程之socket编程(三)
    linux网络编程之socket编程(二)
    字符串转成时间戳
    xls的读写
    统计词语频率保存到xls
    信息时代的学习(对于人类)
    编码格式简介:ASCII码、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM头
    ThinkPHP中:RBAC权限控制的实习步骤
    getField()和select()方法的区别
    按钮美化,变化显示效果
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124675.html
Copyright © 2011-2022 走看看