首页| 论坛| 消息

标题:tq2440 按键驱动 中断方式(转)
作者:fly0418
日期:2016-01-18 16:21
内容:

  硬件平台:TQ2440
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #define DEVICE_NAME "key-device"
  MODULE_DESCRIPTION("759981398@qq.com");
  MODULE_AUTHOR("traveler");
  MODULE_LICENSE("Dual BSD/GPL");
  //声明一个等待队列
  static DECLARE_WAIT_QUEUE_HEAD(keys_wait_irq) ;
  //事件 用于同步用户与驱动程序之间的数据
  static volatile int key_event = 0;
  //存储按键的值
  static volatile int key_value = 0;
  static void * key_devid = (void *)0;
  //ISR中断服务程序
  static irqreturn_t keys_irq(int irq,void *devid)
  {
  int down ;
  //GPIO的 基址 虚拟地址
  //对 GPIO的所有操作 都以此地址 作为 参考 地址
  const unsigned int gpio_base = (unsigned int )S3C24XX_VA_GPIO;
  //获取 GPFDAT寄存器 的 虚拟地址
  const unsigned int gpfdat = gpio_base + 16 * 5 + 4;
  if(devid!=key_devid)
  {
  printk("DRIVER ERROR !devid=%dn",(int)devid);
  return IRQ_RETVAL(IRQ_NONE);
  }
  //获取按键引脚状态
  down = (*(unsigned int *)gpfdat) ;
  //如果当前值和存储的值不相等 则唤醒等待队列
  // if((down &0x01) != (key_value&0x01))
  {
  key_value = down & 0x01;
  key_event = 1;
  wake_up_interruptible(&keys_wait_irq);
  }
  //返回标志 中断已服务
  return IRQ_RETVAL(IRQ_HANDLED);
  }
  //读取 按键 状态 用户 调用 参数 列表
  static ssize_t key_read(struct file *filp,char __user *buf,
  size_t count,loff_t *loff)
  {
  int err;
  if(!key_event)
  {
  //如果事件未发生并且文件不允许阻塞,那么返回一个错误标识
  if(filp->f_flags & O_NONBLOCK)
  return -EAGAIN ;
  //等待事件
  wait_event_interruptible(keys_wait_irq,key_event);
  }
  //拷贝数据到用户空间
  err = copy_to_user(buf,(void*)(&key_value),min(sizeof(key_value ..

回复 发表
主题 版块