Linux input 子系统应用之按键驱动

硬件平台:s5pv210

软件平台:Linux2.6.35.7

应用程序:inputk2_app.c

#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char** argv)
{
 int fd;
    int count;
    int i = 0;
    int j = 0;

 struct input_event key2;

    //在根文件系统用cat /proc/bus/input/devices查看是event几
 fd = open("/dev/event1", O_RDWR);
   
 if (fd < 0)
    {
  perror("open");
       
  return -1;
 }
 
 while (1)
 {
  lseek(fd, 0, SEEK_SET);
       
  count = read(fd, &key2, sizeof(struct input_event));     
  if(count != sizeof(struct input_event))
        {
   perror("read");
  }
  if(EV_KEY == key2.type)
  {
   printf("\r\ni = %d, type:%d, code:%d, value:%d\r\n", i, key2.type, key2.code, key2.value);
      if (key2.value)
      {
                i++;
                printf("***********the k2 down %d times***********\r\n", i);
      }
            else
            {
                printf("****************the k2 up*****************\r\n");   
            }
  }
       
  if(EV_SYN == key2.type)
  {
   printf("syn event\r\n");
            if (++j == 2)
            {
                j = 0;
                printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\n");
            }
  }
 }

 close(fd);

 return 0;
}

 

驱动程序:inputk2_drv.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <linux/timer.h>


static struct input_dev *button_dev;//定义输入设备

struct timer_list my_timer;//定义定时器结构体timer_list

//定义定时器超时处理函数
void timer_func(unsigned long data)
{
 int key_value = gpio_get_value(S5PV210_GPH2(0));

 //上报事件给input核心层
 input_report_key(button_dev, KEY_A, !key_value);//按下为1

    //告诉input子系统上报已经完成
 input_sync(button_dev);

    //printk("[%d][%s], data=[%lu]\r\n", __LINE__, __FUNCTION__, data);
}

static irqreturn_t button_interrupt(int irq, void *dev_id)
{
    //the value of timeout is decided by the n of "jiffies + n"
    //timeout = n*(1000/HZ) ms(HZ=256 in this project)
    //the empirical value of timeout ≈ 10~100ms
    mod_timer(&my_timer, jiffies + 5);//timeout≈5*4=20ms
   
 return IRQ_HANDLED;
}

static int __init button_init(void)
{
 int ret;
 ret = gpio_request(S5PV210_GPH2(0), "key2");
 if (ret)
    {
  printk(KERN_ERR "gpio_request Failed to register device\r\n");

        goto error1;
 }
   
    //为新输入设备分配内存并初始化
 button_dev = input_allocate_device();
 if (!button_dev)
    {
  printk(KERN_ERR "can‘t allocate input mem!\r\n");

        goto error2;
 }
   
 button_dev->name = "gec_input";
 button_dev->id.bustype = 0x1;
 button_dev->id.product = 0x2;
 button_dev->id.vendor  = 0x3;
 button_dev->id.version = 0x4;
 button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);//set_bit(EV_KEY,button_dev->evbit[BIT_WORD(EV_KEY)])
 button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);//set_bit(KEY_A, button_dev->keybit[BIT_WORD(KEY_A)])

    //注册一个输入设备
 ret = input_register_device(button_dev);
 if (ret)
    {
  printk(KERN_ERR "Failed to register device\r\n");

        goto error3;
 }

    //申请中断注册中断处理函数
 ret = request_irq(IRQ_EINT(16), button_interrupt,\
   IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING | IRQF_DISABLED, "button", NULL);
 if (ret)
 {
  printk(KERN_ERR "Can‘t request irq %d\r\n", IRQ_EINT(16));

        goto error4;
 }
 
 //定时器
 init_timer(&my_timer);//初始化定时器
 my_timer.function = timer_func;//注册定时器超时处理函数

    return 0;

error4:
    free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存
    input_unregister_device(button_dev);
   
error3:
    input_free_device(button_dev);

error2:
    ret = -ENOMEM;

error1:
    gpio_free(S5PV210_GPH2(0));
   
 return ret;
}

static void __exit button_exit(void)
{
 gpio_free(S5PV210_GPH2(0)); 
 free_irq(IRQ_EINT(16), NULL);
 input_unregister_device(button_dev);
 del_timer(&my_timer);//删除内核定时器
}

module_init(button_init);
module_exit(button_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE("GPL");

 

Makefile:

obj-m += inputk2_drv.o

PWD ?= shell pwd

KDIR := /opt/03.kernel_transplant/android-kernel-samsung-dev
all:
 make -C $(KDIR) M=$(PWD) modules
 cp ./inputk2_drv.ko /mini_rootfs/modules
 cp ./inputk2_app    /mini_rootfs/modules

 rm -rf ./*.o
 rm -rf ./*.order
 rm -rf ./*.symvers
 rm -rf ./*.mod.c
 rm -rf ./.*.cmd
 rm -rf ./.*.tmp*     
 rm -rf ./.tmp_versions
 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。