博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 2.6 输入子系统 键盘驱动的实现
阅读量:4047 次
发布时间:2019-05-25

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

好久没来了!写点东西.关于linux 2.6下面的键盘驱动的实现.

    2.6内核采用"input sub system" 的概念.将输入驱动分成三块: driver,input core和Event handler. "一个输入事件,如鼠标移动,键盘按键按下,joystick的移动等等通过 Driver -> InputCore -> Eventhandler -> userspace 的顺序到达用户空间传给应用程序。"
    关于输入子系统详细的文章有一个老兄写了一篇:
   
    在这里我肤浅得讲一下如何实现一个驱动.todo
正文
2.6输入子系统使得用户空间可以通过字符设备接口毫无遗漏的获得原始的输入消息。比如说有些智能鼠标,除了坐标滚球,三键,滚轮之外还有其他的输入装置,,比如控制系统音量的按钮.
如何注册设备

      
/*
       *Input interface, not finished yet
       */
       int key,code;
       button_dev = input_allocate_device(); /*static struct input_dev *button_dev defined outside*/
       init_input_dev(button_dev);
      
       set_bit(EV_KEY,button_dev->evbit);
       //@set_bit(EV_REP,button_dev->evbit);       //repeat
       for(key=0;key<16;key++)
              set_bit(keypad_keycode[key],button_dev->keybit);
       button_dev->name = PCA9554_DRV_NAME;
       button_dev->id.bustype = BUS_HOST;
      
       input_register_device(button_dev);
                     
如上述代码所示,首先分配一个输入设备,之后对其进行初始化,然后配置参数. “set_bit(EV_KEY,button_dev->evbit);”将该输入设备定义为键盘输入,这样input core在分发消息的时候会将其发送到keyboard event handler.
接着就是初始化键盘定义,这里keybit是由若干个long型变量组成的数组,我所用的kernel直至最大按键数目为0x1ff.
       for(key=0;key<16;key++)
              set_bit(keypad_keycode[key],button_dev->keybit);
我的开发板上有16个按键,因为项目是播放器,所以我对其作了定义:
int keypad_keycode[] = {
              KEY_UP,  KEY_DOWN,     KEY_A,   KEY_B,              // 1 - 4
              KEY_LEFT, KEY_RIGHT,    KEY_C,   KEY_D,             // 5 - 8
              KEY_PLAYPAUSE,KEY_PLAY,KEY_NEXTSONG,KEY_VOLUMEUP,   // 9 - 12
              KEY_CANCEL,KEY_OK,KEY_PREVIOUSSONG,KEY_VOLUMEDOWN,  // 13 - 16
              KEY_UNKNOWN,
       };

 

键盘定义示意图

 

input.cinput_event函数中会对keybit进行判断,确定某个按键对应的位是否被打开,否则不予上传键值.

              case EV_KEY:
                     printk("haigang;:%s: code:%d,value=%d/n",__FUNCTION__,code,value);
                     if (code > KEY_MAX || !test_bit(code, dev->keybit) || !!test_bit(code, dev->key) == value){
                            printk("haigang:%s: code too big/n",__FUNCTION__,code);
                            return;
                     }
                     if (value == 2)
                            break;
                     change_bit(code, dev->key);
                     if (test_bit(EV_REP, dev->evbit) && dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] && dev->timer.data && value) {
                            dev->repeat_key = code;
                            mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
                     }
                     break;

 

input_event部分代码

 

如何传送输入键值比较简单,只需要使用   函数void input_event即可,该函数定义

void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
include/linux/input.h中对该函数作了封装
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{
       input_event(dev, EV_KEY, code, !!value);
}
这里code是键值,value应该是键盘状态,按下或者释放(仅是猜测,有待考证)
我的驱动中的建值传输代码,当键值是0x16时候,表示松开键盘事件
       unsigned char key;
       static unsigned char oldKey=0x16;
       key = pca9554_readKey();
       //@printk("KEY:%d/n",key);
      
       if(key!=0x16){
              input_report_key(button_dev,keypad_keycode[key],1);
              input_sync(button_dev);
       }else{
              input_report_key(button_dev,keypad_keycode[oldKey],0);
              input_sync(button_dev);
       }
       set_irq_type(IRQ_KEYPAD,IRQT_FALLING);
       s3c_gpio_cfgpin(S3C_GPF4,S3C_GPF4_EINT4);/*reconfigure the GPF4 as EINT4*/
       oldKey=key;

转载地址:http://askci.baihongyu.com/

你可能感兴趣的文章
struct msghdr与struct iovec
查看>>
编译和解释的区别是什么?
查看>>
unpv1 Makefile 文件 简略分析
查看>>
linux网络编程 UDP聊天程序 包括群聊和私聊
查看>>
linux 网络编程 Tcp文件服务器
查看>>
有关send() / recv()函数的理解
查看>>
ping在类unix下的实现
查看>>
python下操作数据库
查看>>
python下对数据库的操作(2) 图片的存取
查看>>
常用排序算法总结(一) 比较算法总结
查看>>
剖析 Linux hypervisor
查看>>
常用排序算法总结(二)
查看>>
基于redhat的发行版本的linux系统 下 扩展Swap分区
查看>>
Fedora下安装Fcitx
查看>>
SSH原理与运用
查看>>
libvirt LXC driver --pass-fds
查看>>
Python ::OS模块 提供的接口介绍
查看>>
Python调用shell命令的几种方法(在新进程中执行shell命令)
查看>>
shell快捷键大全
查看>>
linux 4.15.7内核fedora(Ubuntu)下编译安装
查看>>