实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢
实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢
一个很简单的 按键驱动, 搞了三天也insmod不上去.... 电脑上输入insmod **.ko 后, 直接就死机了......
系统:Redhat 2.6.18
代码如下:
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/fs.h>
- #include <linux/mm.h>
- #include <linux/errno.h>
- #include <linux/sched.h>
- #include <linux/init.h>
- #include <linux/cdev.h>
- #include <linux/interrupt.h>
- #include <asm/io.h>
- #include <asm/system.h>
- #include <asm/uaccess.h>
- #include <asm-arm/irq.h>
- #include <asm-arm/arch-s3c2410/irqs.h>
- #include <asm-arm/arch-s3c2410/regs-gpio.h>
- #include <asm-arm/arch-s3c2410/hardware.h>
- #define DEVICE_NAME "mini_buttons"
- #define BUTTONS_NUM 6
- #define MAX_BUTTONS_BUF 16
- #define BUTTONS_MAJOR 252
- #define BUTTONSTATUS_DOWNX 0
- #define BUTTONSTATUS_DOWN 1
- #define BUTTONSTATUS_UP 2
- #define BUTTONS_TIMER_DELAY (HZ/50)
- #define BUTTONS_TIMER_DELAY1 (HZ/10)
- static int buttons_major = BUTTONS_MAJOR;
- struct buttons_dev
- {
- struct cdev cdev;
- unsigned int buttonStatus[BUTTONS_NUM];
- unsigned char buf[MAX_BUTTONS_BUF];
- unsigned int head,tail;
- wait_queue_head_t wq;
- };
- static struct buttons_dev *buttons_devp;
- static struct buttons_info
- {
- unsigned int irq_no;
- unsigned int gpio_port;
- unsigned int buttons_no;
- }buttons_info_tab[BUTTONS_NUM] =
- {
- {IRQ_EINT8,S3C2410_GPG0,1},
- {IRQ_EINT11,S3C2410_GPG3,2},
- {IRQ_EINT13,S3C2410_GPG5,3},
- {IRQ_EINT14,S3C2410_GPG6,4},
- {IRQ_EINT15,S3C2410_GPG7,5},
- {IRQ_EINT19,S3C2410_GPG11,6},
- };
- static struct timer_list buttons_timer[BUTTONS_NUM];
- void __iomem * virt_GPGCON;
- void __iomem * virt_GPGDAT;
- void __iomem * virt_SRCPND;
- void __iomem * virt_INTMSK;
- void __iomem * virt_INTPND;
- void __iomem * virt_EINTPEND;
- void __iomem * virt_EINTMASK;
- void __iomem * virt_EXTINT1;
- void __iomem * virt_EXTINT2;
- static int buttons_open(struct inode *inode,struct file *filp);
- static int buttons_release(struct inode *inode,struct file *filp);
- static ssize_t buttons_read(struct file *filp,char __user *buf,
- size_t size,loff_t *ppos);
- static struct file_operations buttons_fops =
- {
- .owner = THIS_MODULE,
- .open = buttons_open,
- .release = buttons_release,
- .read = buttons_read,
- // .write = buttons_write,
- };
- static void buttons_ioremap(void)
- {
- virt_INTPND=ioremap(0x4a000010,4);
- virt_EINTPEND=ioremap(0x560000a8,4);
- virt_SRCPND=ioremap(0x4a000000,4);
- // virt_EXTINT0=ioremap(0x56000088,4);
- virt_EXTINT1=ioremap(0x5600008c,4);
- virt_EXTINT2=ioremap(0x56000090,4);
- virt_GPGDAT=ioremap(0x56000064,4);
- virt_EINTMASK=ioremap(0x560000a4,4);
- virt_INTMSK=ioremap(0x4a000008,4);
- virt_GPGCON=ioremap(0x56000060,4);
- }
- static void buttons_iounmap(void)
- {
- iounmap(&virt_INTPND);
- iounmap(&virt_EINTPEND);
- iounmap(&virt_SRCPND);
- // iounmap(&virt_EXTINT0);
- iounmap(&virt_EXTINT1);
- iounmap(&virt_EXTINT2);
- iounmap(&virt_GPGDAT);
- iounmap(&virt_EINTMASK);
- iounmap(&virt_INTMSK);
- iounmap(&virt_GPGCON);
- }
- static void buttons_enable_irq(void)
- {
- unsigned int value;
- iowrite32((1<<5),virt_SRCPND);
- iowrite32((1<<5),virt_INTPND);
- value = ioread32(virt_INTMSK);
- value &= ~(1<<5);
- iowrite32(value,virt_INTMSK);
- value = 0;
- value |= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);
- iowrite32(value,virt_EINTPEND);
- value = ioread32(virt_EINTMASK);
- value &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));
- iowrite32(value,virt_EINTMASK);
- }
- static void buttons_enable_irq_again(void)
- {
- unsigned int value;
- value = 0;
- value = ioread32(virt_INTPND);
- if(value = (1<<5))
- {
- iowrite32((1<<5),virt_SRCPND);
- iowrite32((1<<5),virt_INTPND);
- value = ioread32(virt_EINTPEND);
- if(value = (1<<8))
- {
- iowrite32(value,virt_EINTPEND);
- }else if(value = (1<<11))
- {
- iowrite32(value,virt_EINTPEND);
- }else if(value = (1<<13))
- {
- iowrite32(value,virt_EINTPEND);
- }else if(value = (1<<14))
- {
- iowrite32(value,virt_EINTPEND);
- }else if(value = (1<<15))
- {
- iowrite32(value,virt_EINTPEND);
- }else if(value = (1<<19))
- {
- iowrite32(value,virt_EINTPEND);
- }
- }
- }
- static void buttons_lowlevel(void)
- {
- unsigned int value;
- value = 0;
- value &= ~((7<<0)|(7<<12)|(7<<20)|(7<<24)|(7<<28));
- iowrite32(value,virt_EXTINT1);
- value &= ~(7<<12);
- iowrite32(value,virt_EXTINT2);
- }
- static int buttons_open(struct inode *inode,struct file *filp)
- {
- filp->private_data = buttons_devp;
- buttons_devp->head = buttons_devp->tail =0;
- return 0;
- }
- static int buttons_release(struct inode *inode,struct file *filp)
- {
- return 0;
- }
- static ssize_t buttons_read(struct file *filp,char __user *buf,
- size_t size,loff_t *ppos)
- {
- int ret;
- retry:if(buttons_devp->head != buttons_devp->tail)
- {
- // buf = buttons_devp->buf[buttons_devp->tail];
- ret = copy_to_user(buf,(void *)buttons_devp->buf[buttons_devp->tail],sizeof(unsigned char));
- (buttons_devp->tail)++;
- if(buttons_devp->tail == MAX_BUTTONS_BUF)
- {
- buttons_devp->tail = 0;
- }
- }else{
- __set_current_state(TASK_INTERRUPTIBLE);
- if(filp->f_flags & O_NONBLOCK)
- {
- return -EAGAIN;
- }
- schedule();
- if(signal_pending(current))
- {
- return -ERESTARTSYS;
- }
- goto retry;
- }
- return ret;
- }
- static int is_buttons_down(unsigned long data)
- {
- int key = data;
- unsigned long ret;
- void __iomem * base = S3C24XX_GPIO_BASE(buttons_info_tab[key].gpio_port);
- unsigned long offs = S3C2410_GPIO_OFFSET(buttons_info_tab[key].gpio_port);
- ret = __raw_readl(base + 0x04) & (1 << offs);
- if(ret == 0)
- return 1;
- else
- return 0;
- }
- static void buttons_event(int data)
- {
- int key = data;
- buttons_devp->buf[buttons_devp->head] = buttons_info_tab[key].buttons_no;
- (buttons_devp->head)++;
- if(buttons_devp->head == MAX_BUTTONS_BUF)
- buttons_devp->head = 0;
- wake_up_interruptible(&buttons_devp->wq);
- }
- static void buttons_timer_func(unsigned long data)
- {
- int key = data;
- if(is_buttons_down(key))
- {
- if(buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWNX)
- {
- buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWN;
- buttons_event(key);
- buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
- add_timer(&buttons_timer[key]);
- }else{
- buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
- add_timer(&buttons_timer[key]);
- }
- }else{
- buttons_devp->buttonStatus[key] == BUTTONSTATUS_UP;
- enable_irq(buttons_info_tab[key].irq_no);
- }
- }
- static irqreturn_t buttons_eint_func(int irq,void *dev_id,struct pt_regs *regs)
- {
- int key = dev_id;
- disable_irq(buttons_info_tab[key].irq_no);
- buttons_enable_irq_again();
- buttons_devp->buttonStatus[key] = BUTTONSTATUS_DOWNX;
- buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY;
- add_timer(&buttons_timer[key]);
- }
- static int request_irqs(void)
- {
- int i,ret;
- buttons_lowlevel();
- for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[1]);i++)
- {
- set_irq_type(buttons_info_tab[i].irq_no,IRQT_LOW);
- ret = request_irq(buttons_info_tab[i].irq_no,buttons_eint_func, SA_INTERRUPT,DEVICE_NAME,i);
- if(ret)
- return - EINVAL;
- }
- return 0;
- }
- static int buttons_setup_cdev(struct buttons_dev *dev,int index)
- {
- int err,devno = MKDEV(buttons_major,index);
- cdev_init(&dev->cdev,&buttons_fops);
- dev->cdev.owner = THIS_MODULE;
- dev->cdev.ops = &buttons_fops;
- err = cdev_add(&dev->cdev,devno,1);
- if(err)
- printk(KERN_NOTICE "Error %d adding",err);
- buttons_enable_irq();
- request_irqs();
- /***** IOREMAP *****/
- buttons_ioremap();
- return 0;
- }
- static int __init buttons_init(void)
- {
- int i,result;
- dev_t devno = MKDEV(buttons_major,0);
- if(buttons_major)
- result = register_chrdev_region(devno,1,DEVICE_NAME);
- else{
- result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);
- buttons_major = MAJOR(devno);
- }
- if(result)
- return result;
- buttons_devp->head = buttons_devp->tail = 0;
- for(i = 0;i < BUTTONS_NUM;i++)
- buttons_devp->buttonStatus[i] = BUTTONSTATUS_UP;
- for(i = 0;i < BUTTONS_NUM;i++)
- setup_timer(&buttons_timer[i],buttons_timer_func,i);
- init_waitqueue_head(&(buttons_devp->wq));
- buttons_setup_cdev(buttons_devp,0);
- return 0;
- }
- module_init(buttons_init);
- static void __exit buttons_exit(void)
- {
- int i;
- // for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[i]);i++)
- buttons_iounmap();
- for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[i]);i++)
- free_irq(buttons_info_tab[i].irq_no,i);
- cdev_del(&buttons_devp->cdev);
- for(i = 0;i < BUTTONS_NUM;i++)
- del_timer(&buttons_timer[i]);
- unregister_chrdev_region(MKDEV(buttons_major,0),1);
- }
- module_exit(buttons_exit);
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("bejoey_pro");
复制代码
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
设置一堆printk(KERN_INFO "point x\n");
这样的~ 看看加载到第几步死机吧~
而且最好用个虚拟机来试试~ 这样死机也不用重启~
他的平台应该是s3c24×× 不是pc把。所以系统:Redhat 2.6.18 没有用。
最好是增加printk。 检查中断是否一直在中断。(set_irq_type(buttons_info_tab.irq_no,IRQT_LOW);)
这句话有问题吧,buttons_devp->head = buttons_devp->tail = 0;
buttons_devp申请空间了么?