Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1300375
  • 博文数量: 548
  • 博客积分: 7597
  • 博客等级: 少将
  • 技术积分: 4224
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 13:21
个人简介

嵌入式软件工程师&&太极拳

文章分类

全部博文(548)

文章存档

2014年(10)

2013年(76)

2012年(175)

2011年(287)

分类: 嵌入式

2011-12-03 13:44:38

 

  1. http://blog.163.com/shaohj_1999@126/blog/static/6340685120103130036928/

 

  1. 经过两天的学习,终于搞定at91的输入中断了,明白后感觉很简单,真的~

  2.        废话少说,开始说下所遇到的麻烦。刚开始,一直没有注意kernel中对at91的中断号定义与管脚定义是重复,中断号的寻找花了不少时间,原来在内核的 kernel/arch/arm/mach-at91/include/mach/gpio.h中 these pin numbers double as IRQ numbers, like AT91xxx_ID_* values这句话提醒了我。找到中断号后,在网上看了别人写好的程序,不过问题还是有的。他只介绍,没具体程序。无赖下只能用写这块程序了,其实也不难,在s3c2440基础上进行了修改便可。不过一定要注意正在使用的IO口是否被使用过。

  3.         驱动程序如下:

  4. #include <linux/miscdevice.h>
  5. #include <asm/irq.h>
  6. #include <mach/gpio.h>
  7. #include <mach/hardware.h>
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/mm.h>
  12. #include <linux/fs.h>
  13. #include <linux/types.h>
  14. #include <linux/slab.h>
  15. #include <linux/errno.h>
  16. #include <linux/ioctl.h>
  17. #include <linux/cdev.h>
  18. #include <linux/string.h>
  19. #include <linux/list.h>
  20. #include <linux/pci.h>
  21. #include <asm/uaccess.h>
  22. #include <asm/atomic.h>
  23. #include <asm/unistd.h>
  24. #include<linux/module.h>
  25. #include<linux/poll.h>
  26. #include<linux/interrupt.h>


  27. #define DEVICE_NAME "Timll-keys"

  28. struct button_irq_desc
  29. {
  30.     int irq;
  31.     int pin;
  32.     int number;
  33.     char *name;
  34. };

  35. static struct button_irq_desc button_irqs[]=
  36. {
  37.     {AT91_PIN_PA27,AT91_PIN_PA27,0,"KEY1"},
  38.     {AT91_PIN_PA28,AT91_PIN_PA28,1,"KEY2"},
  39. };

  40. static volatile char key_values [] = {0,0};

  41. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

  42. static volatile int ev_press = 0;


  43. static irqreturn_t button_interrupt(int irq, void *dev_id)
  44. {
  45.  struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
  46.  int down;

  47.  down = !gpio_get_value(button_irqs->pin);

  48.  if (down != (key_values[button_irqs->number] & 1))
  49.  {
  50.   key_values[button_irqs->number] = down;
  51.   ev_press = 1;
  52.   wake_up_interruptible(&button_waitq);
  53.   printk("down=%d\n",down);
  54. // printk("down key_values[0]=%c , key_values[1]=%c\n",key_values[0],key_values[1]);
  55.  }
  56.  return IRQ_RETVAL(IRQ_HANDLED);
  57. }


  58. static int irq_open(struct inode *inode, struct file *file)
  59. {
  60.     int err, i;
  61.     for(i=0; i<sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
  62.         at91_set_gpio_input(button_irqs[i].pin,1);
  63.         gpio_to_irq(button_irqs[i].pin);
  64.         err=request_irq(button_irqs[i].irq,button_interrupt,NULL,button_irqs[i].name,(void *)&button_irqs[i]);
  65.         if(err) {
  66.             i--;
  67.             for(; i>=0; i--) {
  68.                 disable_irq(button_irqs[i].irq);
  69.                 free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);
  70.             }
  71.             printk("open err");
  72.             return -EBUSY;
  73.         }
  74.     }
  75.     return 0;
  76. }


  77. static int irq_close(struct inode *inode, struct file *file)
  78. {
  79.  int i;
  80.  for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++)
  81.  {
  82.   if (button_irqs[i].irq < 0)
  83.    continue;
  84.   free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
  85.  }
  86.  return 0;
  87. }


  88. static int irq_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
  89. {
  90.  unsigned long err;
  91.  if (!ev_press)
  92.  {
  93.   if (filp->f_flags & O_NONBLOCK)
  94.    return -EAGAIN;
  95.   else
  96.    wait_event_interruptible(button_waitq, ev_press);
  97.  }
  98.  ev_press = 0;
  99.  err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));
  100.  return err ? -EFAULT : min(sizeof(key_values), count);
  101. }


  102. static struct file_operations dev_fops = {
  103.  .owner = THIS_MODULE,
  104.  .open = irq_open,
  105.  .release =irq_close,
  106.  .read = irq_read,
  107. };

  108. static struct miscdevice misc = {
  109.  .minor = MISC_DYNAMIC_MINOR,
  110.  .name = DEVICE_NAME,
  111.  .fops = &dev_fops,
  112. };

  113. static char __initdata dis[]="shaohj_1999@126.com\n";

  114. static int __init dev_init(void)
  115. {
  116.  int ret;
  117.  printk(dis);
  118.  ret = misc_register(&misc);
  119.  printk (DEVICE_NAME" initialized\n");
  120.  return ret;
  121. }

  122. static void __exit dev_exit(void)
  123. {
  124.  misc_deregister(&misc);
  125. }

  126. module_init(dev_init);
  127. module_exit(dev_exit);

  128. MODULE_LICENSE("GPL");


  129. 测试程序网上只要read就行。

  130. 不明白QQ我,或者邮箱。
阅读(895) | 评论(0) | 转发(0) |
0

上一篇:分析DMA

下一篇:UVC驱动测试程序

给主人留下些什么吧!~~