查看: 1612|回复: 0

tq2440 按键驱动 中断方式(转)

[复制链接]
  • TA的每日心情
    奋斗
    2018-3-5 10:57
  • 签到天数: 112 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2016-1-18 16:22:48 | 显示全部楼层 |阅读模式
    分享到:
      硬件平台: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("<1>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),count));
      //已经读取了数据,重设事件标志
      key_event = 0;
      //返回拷贝到的数据长度
      return err ? -EFAULT : min(sizeof(key_value),count) ;
      };
      static int key_open(struct inode *inode,struct file *filp)
      {
      int err;
      //GPIO的 基址 虚拟地址
      //对 GPIO的所有操作 都以此地址 作为 参考 地址
      const unsigned int gpio_base = (unsigned int )S3C24XX_VA_GPIO;
      //获取 GPFCON的 地址
      const unsigned int gpfcon = gpio_base + 16 * 5;
      //获取 GPFDAT的 地址
      unsigned int gpfup = gpfcon + 2*4;
      //注册irq函数
      err = request_irq(IRQ_EINT0,keys_irq,IRQ_TYPE_EDGE_BOTH,
      "key0",key_devid);
      if(err)
      return -EBUSY;
      //设置事件标志
      key_event = 1;
      //配置 GPF0 端口 为EINT0
      (*(unsigned int *)gpfcon) &= ~(0x03);
      (*(unsigned int *)gpfcon) |= 0x02;
      //禁止 内部 上拉 电阻
      (*(unsigned int *)gpfup) |= 0x01;
      return 0;
      }
      static int key_release(struct inode *inode,struct file *filp)
      {
      //禁止中断
      disable_irq(IRQ_EINT0);
      //释放中断
      free_irq(IRQ_EINT0,key_devid);
      return 0;
      }
      static struct file_operations key_fops =
      {
      .owner= THIS_MODULE,
      .open = key_open,
      .read = key_read,
      .release = key_release,
      };
      static struct miscdevice key_misc=
      {
      .minor = MISC_DYNAMIC_MINOR,
      .name = DEVICE_NAME,
      .fops = &key_fops,
      };
      static int key_init_module(void)
      {
      int ret ;
      //注册 杂项 设备
      ret = misc_register(&key_misc);
      printk("<1>Module key init,major:10,minor:%dn",key_misc.minor );
      return 0;
      }
      static void key_exit_module(void)
      {
      //注销 杂项设备
      misc_deregister(&key_misc);
      printk("<1>Module key exitn" );
      }
      module_init(key_init_module);
      module_exit(key_exit_module);

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2025-1-12 07:57 , Processed in 0.107265 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.