博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
键盘驱动的原理
阅读量:6112 次
发布时间:2019-06-21

本文共 2102 字,大约阅读时间需要 7 分钟。

 

键盘驱动的设置

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)

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

 

转载于:https://www.cnblogs.com/yuzaipiaofei/archive/2011/07/08/4124675.html

你可能感兴趣的文章
Installed .NET Framework 4.5 Ajax POST IIS hang
查看>>
cocos2d-x make: *** [clean-box2d_static-armeabi] Error 1
查看>>
VS2010无法修改资源文件
查看>>
邮箱工具(尚未完成)的几个组件类
查看>>
inkscape - 百度百科
查看>>
使用 Python 进行稳定可靠的文件操作
查看>>
数据结构之后缀数组
查看>>
.Net 中DataSet和DataTable的 区别与联系
查看>>
Windows 管理
查看>>
HDU 1619 Unidirectional TSP(单向TSP + 路径打印)
查看>>
微软BI 之SSIS 系列 - 使用 Multicast Task 将数据同时写入多个目标表,以及写入Audit 与增量处理信息...
查看>>
使用avalon 实现一个订座系统
查看>>
Ubuntu 如何downgrade降级系统
查看>>
MySQL执行外部sql脚本
查看>>
固态硬盘和机械硬盘的比较和SQLSERVER在两种硬盘上的性能差异
查看>>
java 结束程序进程 代码
查看>>
『摄影欣赏』20幅精美的秋天落叶风景欣赏【组图】
查看>>
基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)
查看>>
Java I/O 文件加锁,压缩
查看>>
网页实战开发笔记之——最全面的HTML的头部信息介绍
查看>>