mini2440的按键驱动
来源:互联网 发布:php pack("h*") 编辑:程序博客网 时间:2024/05/17 21:36
#include <linux/types.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/cdev.h>#include <asm/io.h>#include <asm/system.h>#include <asm/uaccess.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/miscdevice.h>#include <linux/poll.h>#include <linux/delay.h>// 混杂设备的次设备号#define DEV_MINOR 1000#define DEV_NAME "button"#define GPGCON 0x56000060#define GPGDATA 0x56000064DECLARE_WAIT_QUEUE_HEAD(dev_queue);unsigned int * dev_con = NULL;unsigned int * dev_data = NULL;// 按键的状态,默认的时候是没有按键按下unsigned char volatile key_flag = 0;// 按键值unsigned char volatile key_value = 0;MODULE_LICENSE("GPL");struct dev_str { int irq; int num; char * name;};static struct dev_str dev[4]= { {IRQ_EINT8,1,"key1",},{IRQ_EINT11,2,"key2",},{IRQ_EINT13,3,"key3",},{IRQ_EINT14,4,"key4",}};static irqreturn_t intterrupt_ser(int irq, void *dev_id){ struct dev_str * button = (struct dev_str *)dev_id; unsigned int ret = 0; mdelay(3); //udelay(3); // 读取按键值 ret = ioread32(dev_data); if ((ret & 0x01) && !key_flag) { key_flag = 1; key_value = button->num; wake_up_interruptible(&dev_queue); } if ((ret & 0x08) && !key_flag) { key_flag = 1; key_value = button->num; wake_up_interruptible(&dev_queue); } if ((ret & 0x20) && !key_flag) { key_flag = 1; key_value = button->num; wake_up_interruptible(&dev_queue); } if ((ret & 0x40) && !key_flag) { key_flag = 1; key_value = button->num; wake_up_interruptible(&dev_queue); } return IRQ_RETVAL(IRQ_HANDLED); }int dev_open (struct inode * dev_inode, struct file * dev_file){ int err = -1;int i = 0 ; printk ("pi"); dev_con = ioremap (GPGCON, 4); dev_data = ioremap (GPGDATA, 4); // 端口为中断方式 *dev_con &= ~( (0x03<<0) | (0x03<<6) | (0x03<<10) | (0x03<<12) );*dev_con |= ( (0x02<<0) | (0x02<<6) | (0x02<<10) | (0x02<<12) ); // 注册中断,上升沿中断for(i = 0;i < 4;i++){ err = request_irq (dev[i].irq, intterrupt_ser, IRQ_TYPE_EDGE_RISING, dev[i].name, (void *)&dev[i]); if (err) { disable_irq (dev[i].irq); free_irq (dev[i].irq, (void *)&dev[i]); return -EBUSY; }key_flag = 0;} //key_flag = 0; return 0;}int dev_close (struct inode * dev_inode, struct file * dev_file){int i = 0;for(i = 0;i < 4; i++){ disable_irq (dev[i].irq); free_irq (dev[i].irq, (void *)&dev[i]);} return 0;}ssize_t dev_read (struct file * dev_file, char __user * buff, size_t dev_size, loff_t * dev_loff){ int ret = -1; if (!key_flag) { if (dev_file->f_flags & O_NONBLOCK) return -EAGAIN; else wait_event_interruptible(dev_queue,key_flag); } key_flag= 0; printk("key %d press!\n", key_value); ret = copy_to_user (buff, (const void *)&key_value, sizeof (char)); key_value = 0; return ret ? -EFAULT : sizeof (char); }unsigned int dev_poll (struct file * dev_file, struct poll_table_struct * dev_table){//int i = 0; unsigned int mask = 0; poll_wait (dev_file, &dev_queue, dev_table); if (key_flag) mask |= (POLLIN | POLLRDNORM); return mask;}struct file_operations dev_ops = { .owner = THIS_MODULE, .open = dev_open, .release = dev_close, .read = dev_read, .poll = dev_poll,};struct miscdevice dev_misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEV_NAME, .fops = &dev_ops,};static int __init dev_init (void){ int ret = -1; ret = misc_register(&dev_misc); printk (DEV_NAME "init!\n"); return ret; }static void __exit dev_exit (void){ // 注销混杂设备 misc_deregister (&dev_misc);}MODULE_AUTHOR("LiangPeng");module_init(dev_init);module_exit(dev_exit);
测试程序
#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>#include <sys/select.h>#define DEV_NAME "/dev/button"int main (){ fd_set rset; int fd = 0; int ret = 0; int read_count = 0; unsigned char key_value = 0; fd = open(DEV_NAME ,O_RDWR); if (fd < 0) { printf("Open Dev Error!\n"); return -1; } FD_ZERO (&rset); FD_SET (fd, &rset); for (;;) { ret = select(fd + 1, &rset, NULL, NULL, NULL); if (FD_ISSET (fd, &rset)) { read_count = read (fd, &key_value, 1); printf ("the key is :%d\n", key_value); key_value = 0; } } close (fd); return 0; }
在测试的过程中发现连续按k1或者k2或者其他的按键 终端上偶尔会出现错误的键值,出现0的情况
后来在调试的时候 把udelay改成了mdelay之后 发现问题没有了
应该是延时的问题
- mini2440的按键驱动
- mini2440的按键驱动
- mini2440 基于中断的按键驱动
- 输入子系统实现的mini2440按键驱动
- 基于mini2440外部中断的按键驱动
- mini2440按键驱动分析
- mini2440按键驱动分析
- mini2440 按键驱动
- mini2440按键驱动
- mini2440 按键控制LED 驱动
- 转:一个相当详细的MINI2440按键驱动详解
- 一个相当详细的MINI2440按键驱动详解
- 基于mini2440的按键驱动分析与总结
- 一个相当详细的MINI2440按键驱动详解
- 转:一个相当详细的MINI2440按键驱动详解
- 一个相当详细的MINI2440按键驱动详解
- 基于中断的linux按键驱动(mini2440)
- 基于linux的mini2440按键驱动及应用程序
- 高频机和低频机捕鱼机的优缺点
- ASP.NET MVC 入门10 使用AJAX
- C++中string的常用函数
- 序列化和反序列化
- 2013 多校第七场 hdu 4669 Mutiples on a circle(DP,环)
- mini2440的按键驱动
- Linq基本查询
- codeforces---#196 337A
- Unity3d--metaio
- uvc摄像头代码解析2
- 【树形DP】 codeforces 337D Book of Evil
- (step 4.3.5)hdu 1035(Robot Motion——DFS)
- python random模块
- oracle 存储过程