十三、优化按键驱动(用延迟作业消抖)

将key.c修改为:

  1 #include <linux/init.h>
  2 #include <linux/module.h>
  3 #include <linux/miscdevice.h>
  4 #include <linux/fs.h>
  5 #include <linux/interrupt.h>
  6 #include <linux/io.h>
  7 #include <linux/wait.h>
  8 #include <linux/uaccess.h>
  9 #include <linux/workqueue.h>
 10 
 11 #define GPNCON  0x7F008830
 12 
 13 struct my_key_struct {
 14     int irq;
 15     int id;
 16     char name[16];
 17 };
 18 
 19 struct my_key_struct my_key_config[6] = {
 20     {S3C_EINT(0), 0, "key0"},
 21     {S3C_EINT(1), 1, "key1"},
 22     {S3C_EINT(2), 2, "key2"},
 23     {S3C_EINT(3), 3, "key3"},
 24     {S3C_EINT(4), 4, "key4"},
 25     {S3C_EINT(5), 5, "key5"},
 26 };
 27 
 28 static int __g_key_value;
 29 
 30 int volatile condition = 0;
 31 DECLARE_WAIT_QUEUE_HEAD(key_wqh);
 32 
 33 //struct work_struct my_work;
 34 struct delayed_work my_delayed_work;
 35 struct workqueue_struct *p_my_workqueue;
 36 
 37 void my_work_func (struct work_struct *p_work)
 38 {
 39     condition = 1;
 40     wake_up_interruptible(&key_wqh);
 41 }
 42 
 43 irqreturn_t key_irqhandler (int irq, void *p_arg)
 44 {
 45     __g_key_value = *((int *)p_arg);
 46 
 47     printk("irq\n");
 48 
 49     //schedule_work(&my_work);
 50     //schedule_delayed_work(&my_delayed_work, 2);
 51     //queue_work(p_my_workqueue, &my_work);
 52     queue_delayed_work(p_my_workqueue, &my_delayed_work, 20);
 53 
 54     return 0;
 55 }
 56 
 57 static int key_open (struct inode *p_inode, struct file *p_file)
 58 {
 59     int ret, i;
 60     int *p_gpncon;
 61     int temp;
 62     
 63     p_gpncon = ioremap(GPNCON, 4);
 64     temp = readl(p_gpncon);
 65     temp &= ~(0xFFF);
 66     temp |= 0xAAA;
 67     writel(temp, p_gpncon);
 68      
 69     for (i = 0; i < 6; i++) {
 70         ret = request_irq(my_key_config[i].irq, 
 71                           key_irqhandler, 
 72                           IRQF_TRIGGER_FALLING, 
 73                           my_key_config[i].name, 
 74                           (void*)&my_key_config[i].id);
 75 
 76         if (ret != 0) {
 77 
 78             i--;
 79             while (i >= 0) {
 80                 free_irq(my_key_config[i].irq, (void*)&my_key_config[i].id);
 81             }
 82             return -1;
 83         }
 84     }
 85 
 86     p_my_workqueue = create_singlethread_workqueue("my_workqueue");
 87 
 88     //INIT_WORK(&my_work, my_work_func);
 89     INIT_DELAYED_WORK(&my_delayed_work, my_work_func);
 90 
 91     return 0;
 92 }
 93 
 94 static int key_close (struct inode *p_inode, struct file *p_file)
 95 {
 96      int i;
 97 
 98     for (i = 0; i < 6; i++) {
 99         free_irq(my_key_config[i].irq, (void*)&my_key_config[i].id);
100     } 
101 
102     destroy_workqueue(p_my_workqueue);
103 
104     return 0;
105 }
106 
107 static ssize_t key_read (struct file *p_file, char __user *p_dat, size_t size, loff_t *p_loff)
108 {
109     
110     wait_event_interruptible(key_wqh, condition);
111     condition = 0;
112 
113     copy_to_user(p_dat, &__g_key_value, 4);
114 
115     return 4;
116 }
117 
118 
119 static struct file_operations fops = {
120     .owner = THIS_MODULE,
121     .open = key_open,
122     .release = key_close,
123     .read = key_read,
124 };
125 
126 static struct miscdevice key_dev = {
127     .minor = MISC_DYNAMIC_MINOR,
128     .name = "mykey",
129     .fops = &fops,
130 };
131 
132 static int __init key_init (void)
133 {
134     misc_register(&key_dev);
135 
136     return 0;
137 }
138 
139 static void __exit key_exit (void)
140 {
141     misc_deregister(&key_dev);
142 }
143 
144 module_init(key_init);
145 module_exit(key_exit);
146 
147 MODULE_LICENSE("GPL");

第52行的延时时间与按键质量有关系,按键抖动厉害的话就适当增加时间。

 

转载于:https://www.cnblogs.com/Suzkfly/p/10334638.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值