Chinaunix首页 | 论坛 | 博客
  • 博客访问: 120941
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 296
  • 用 户 组: 普通用户
  • 注册时间: 2015-01-10 21:57
文章分类

全部博文(31)

文章存档

2016年(4)

2015年(27)

我的朋友

分类: LINUX

2015-03-13 10:51:05

按键原理图:


1、驱动代码,建立按键驱动文件 input_key.c
点击(此处)折叠或打开
  1. #include <linux/input.h>
  2. #include <linux/module.h>
  3. #include <linux/init.h>
  4. #include <linux/slab.h>
  5. #include <asm/irq.h>
  6. #include <asm/io.h>
  7. #include <linux/kernel.h>
  8. #include <linux/fs.h>
  9. #include <linux/init.h>
  10. #include <linux/delay.h>
  11. #include <linux/poll.h>
  12. #include <linux/irq.h>
  13. #include <asm/irq.h>
  14. #include <linux/interrupt.h>
  15. #include <asm/uaccess.h>
  16. #include <mach/regs-gpio.h>
  17. #include <mach/hardware.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/cdev.h>
  20. #include <linux/miscdevice.h>
  21. #include <linux/device.h>
  22. #include <linux/gpio.h>
  23. #include <mach/irqs.h>

  24. MODULE_LICENSE("GPL");

  25. struct work_struct *work1;

  26. struct timer_list buttons_timer;

  27. unsigned int *gpio_data;

  28. unsigned int key_num = 0;

  29. wait_queue_head_t key_q;

  30. struct input_dev *button_dev;

  31. void work1_func(struct work_struct *work)
  32. {
  33.     mod_timer(&buttons_timer, jiffies + (HZ /10));     
  34. }

  35. void buttons_timer_function(unsigned long data)
  36. {
  37.     input_report_key(button_dev, KEY_1, !s3c2410_gpio_getpin(S3C2410_GPG(0)));
  38.     input_report_key(button_dev, KEY_2, !s3c2410_gpio_getpin(S3C2410_GPG(3)));
  39.     
  40.     input_sync(button_dev);
  41. }


  42. irqreturn_t key_int(int irq, void *dev_id)
  43. {
  44.     //1. 检测是否发生了按键中断
  45.     
  46.     //2. 清除已经发生的按键中断
  47.     
  48.     //3. 提交下半部
  49.     schedule_work(work1);
  50.     
  51.     return IRQ_HANDLED;
  52. }

  53. void key_hw_init()
  54. {
  55.     s3c2410_gpio_cfgpin(S3C2410_GPG(0), S3C2410_GPG0_EINT8);
  56.     s3c2410_gpio_cfgpin(S3C2410_GPF(3), S3C2410_GPG3_EINT11);
  57. }


  58. static int button_init()
  59. {
  60.     int ret;
  61.     
  62.     /*分配输入型设备结构*/
  63.     button_dev = input_allocate_device();
  64.     
  65.     /*申明所支持的事件类型*/
  66.     set_bit(EV_KEY,button_dev->evbit);
  67.     
  68.     /*申明可能上报的键编号*/
  69.     set_bit(KEY_1,button_dev->keybit);
  70.     set_bit(KEY_2,button_dev->keybit);
  71.     
  72.     /*注册输入型设备*/
  73.     input_register_device(button_dev);
  74.     
  75.     
  76.     //注册中断处理程序
  77.     request_irq(IRQ_EINT8,key_int, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"key",(void *)1);
  78.     request_irq(IRQ_EINT11,key_int, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"key",(void *)2);
  79.     
  80.     //按键初始化
  81.     key_hw_init();
  82.     
  83.     //. 创建工作
  84.     work1 = kmalloc(sizeof(struct work_struct),GFP_KERNEL);
  85.     INIT_WORK(work1, work1_func);
  86.     
  87.     /* 初始化定时器 */
  88.     init_timer(&buttons_timer);
  89.     buttons_timer.function = buttons_timer_function;
  90.     
  91.     /* 向内核注册一个定时器 */
  92.     add_timer(&buttons_timer);
  93.     
  94.     /*初始化等待队列*/
  95.     init_waitqueue_head(&key_q);
  96.  
  97.     return 0;
  98.     
  99. }

  100. static void button_exit()
  101. {
  102.     input_unregister_device(button_dev);    
  103. }


  104. module_init(button_init);
  105. module_exit(button_exit);

2、Makefile

点击(此处)折叠或打开

  1. obj-m := input_key.o
  2. KDIR := /home/win/code3/my2440/linux-2.6.39
  3. all:
  4.     make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
  5. clean:
  6.     rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order

3、测试代码,key_app.c 采用静态编译 
#arm-linux-gcc -static key_app.c -o key_app
点击(此处)折叠或打开
  1. /*
  2.  * Buttons Example for Matrix V
  3.  *
  4.  * Copyright (C) 2004 capbily - friendly-arm
  5.  *    capbily@hotmail.com
  6.  */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <sys/ioctl.h>
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14. #include <sys/select.h>
  15. #include <sys/time.h>
  16. #include <errno.h>
  17. #include <linux/input.h>
  18. int main(void)
  19. {
  20.     int buttons_fd;
  21.     int key_value,i=0,count;

  22.     struct input_event ev_key;
  23.     buttons_fd = open("/dev/input/event1", O_RDWR);
  24.     if (buttons_fd < 0) {
  25.         perror("open device buttons");
  26.         exit(1);
  27.     }

  28.     printf("open device success\n");

  29.     for (;;)
  30.     {
  31.         count = read(buttons_fd,&ev_key,sizeof(struct input_event));
  32.         //printf("count=%d\n",count);
  33.         for(i=0; i<(int)count/sizeof(struct input_event); i++)
  34.         {
  35.             if(EV_KEY==ev_key.type)
  36.                 printf("type:%d,code:%d,value:%d\n", ev_key.type,ev_key.code-1,ev_key.value);
  37.             if(EV_SYN==ev_key.type)
  38.                 printf("syn event\n\n");
  39.         }
  40.     }

  41.     close(buttons_fd);
  42.     return 0;
  43. }
按键输出结果:

4、调试过程中发现,如果上报的事件,按键编码的值没有发生改变,比如input_report_key(button_dev, KEY_1, !s3c2410_gpio_getpin(S3C2410_GPG(0)));改成input_report_key(button_dev, KEY_1, 1);那么测试程序read函数只有第一次按键操作时可以读到数据,后面再操作按键都感觉设备没有数据到达,read发生阻塞。
阅读(1452) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~