免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1329 | 回复: 1
打印 上一主题 下一主题

[C] 实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-11 15:37 |只看该作者 |倒序浏览
实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢
一个很简单的 按键驱动, 搞了三天也insmod不上去....    电脑上输入insmod **.ko 后,  直接就死机了......  
系统:Redhat 2.6.18
代码如下:


  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/mm.h>
  5. #include <linux/errno.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <linux/interrupt.h>

  10. #include <asm/io.h>
  11. #include <asm/system.h>
  12. #include <asm/uaccess.h>
  13. #include <asm-arm/irq.h>
  14. #include <asm-arm/arch-s3c2410/irqs.h>
  15. #include <asm-arm/arch-s3c2410/regs-gpio.h>
  16. #include <asm-arm/arch-s3c2410/hardware.h>

  17. #define DEVICE_NAME        "mini_buttons"
  18. #define BUTTONS_NUM        6
  19. #define MAX_BUTTONS_BUF        16
  20. #define BUTTONS_MAJOR        252

  21. #define BUTTONSTATUS_DOWNX        0
  22. #define BUTTONSTATUS_DOWN        1
  23. #define BUTTONSTATUS_UP                2

  24. #define BUTTONS_TIMER_DELAY        (HZ/50)
  25. #define BUTTONS_TIMER_DELAY1        (HZ/10)

  26. static int buttons_major = BUTTONS_MAJOR;


  27. struct buttons_dev
  28. {
  29.         struct cdev cdev;
  30.         unsigned int buttonStatus[BUTTONS_NUM];
  31.         unsigned char buf[MAX_BUTTONS_BUF];
  32.         unsigned int head,tail;
  33.         wait_queue_head_t wq;
  34. };

  35. static struct buttons_dev *buttons_devp;

  36. static struct buttons_info
  37. {
  38.         unsigned int irq_no;
  39.         unsigned int gpio_port;
  40.         unsigned int buttons_no;
  41. }buttons_info_tab[BUTTONS_NUM] =
  42. {
  43.         {IRQ_EINT8,S3C2410_GPG0,1},
  44.         {IRQ_EINT11,S3C2410_GPG3,2},
  45.         {IRQ_EINT13,S3C2410_GPG5,3},
  46.         {IRQ_EINT14,S3C2410_GPG6,4},
  47.         {IRQ_EINT15,S3C2410_GPG7,5},
  48.         {IRQ_EINT19,S3C2410_GPG11,6},
  49. };

  50. static struct timer_list buttons_timer[BUTTONS_NUM];


  51. void __iomem * virt_GPGCON;
  52. void __iomem * virt_GPGDAT;
  53. void __iomem * virt_SRCPND;
  54. void __iomem * virt_INTMSK;
  55. void __iomem * virt_INTPND;
  56. void __iomem * virt_EINTPEND;
  57. void __iomem * virt_EINTMASK;
  58. void __iomem * virt_EXTINT1;
  59. void __iomem * virt_EXTINT2;

  60. static int buttons_open(struct inode *inode,struct file *filp);
  61. static int buttons_release(struct inode *inode,struct file *filp);
  62. static ssize_t buttons_read(struct file *filp,char __user *buf,
  63.                                 size_t size,loff_t *ppos);

  64. static struct file_operations buttons_fops =
  65. {
  66.         .owner = THIS_MODULE,
  67.         .open = buttons_open,
  68.         .release = buttons_release,
  69.         .read = buttons_read,
  70. //        .write = buttons_write,
  71. };

  72. static void buttons_ioremap(void)
  73. {
  74.    virt_INTPND=ioremap(0x4a000010,4);
  75.    virt_EINTPEND=ioremap(0x560000a8,4);
  76.    virt_SRCPND=ioremap(0x4a000000,4);
  77. //   virt_EXTINT0=ioremap(0x56000088,4);
  78.    virt_EXTINT1=ioremap(0x5600008c,4);
  79.    virt_EXTINT2=ioremap(0x56000090,4);
  80.    virt_GPGDAT=ioremap(0x56000064,4);
  81.    virt_EINTMASK=ioremap(0x560000a4,4);
  82.    virt_INTMSK=ioremap(0x4a000008,4);
  83.    virt_GPGCON=ioremap(0x56000060,4);
  84. }

  85. static void buttons_iounmap(void)
  86. {
  87.         iounmap(&virt_INTPND);
  88.         iounmap(&virt_EINTPEND);
  89.         iounmap(&virt_SRCPND);
  90. //        iounmap(&virt_EXTINT0);
  91.         iounmap(&virt_EXTINT1);
  92.         iounmap(&virt_EXTINT2);
  93.         iounmap(&virt_GPGDAT);
  94.         iounmap(&virt_EINTMASK);
  95.         iounmap(&virt_INTMSK);
  96.         iounmap(&virt_GPGCON);
  97. }

  98. static void buttons_enable_irq(void)
  99. {
  100.         unsigned int value;
  101.         iowrite32((1<<5),virt_SRCPND);
  102.         iowrite32((1<<5),virt_INTPND);
  103.         value = ioread32(virt_INTMSK);
  104.         value &= ~(1<<5);
  105.         iowrite32(value,virt_INTMSK);       

  106.         value = 0;
  107.         value |= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);
  108.         iowrite32(value,virt_EINTPEND);

  109.         value = ioread32(virt_EINTMASK);
  110.         value &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));
  111.         iowrite32(value,virt_EINTMASK);

  112. }

  113. static void buttons_enable_irq_again(void)
  114. {
  115.         unsigned int value;
  116.         value = 0;
  117.         value = ioread32(virt_INTPND);
  118.         if(value = (1<<5))
  119.         {
  120.                 iowrite32((1<<5),virt_SRCPND);
  121.                 iowrite32((1<<5),virt_INTPND);
  122.                 value = ioread32(virt_EINTPEND);
  123.                 if(value = (1<<8))
  124.                 {
  125.                         iowrite32(value,virt_EINTPEND);
  126.                 }else if(value = (1<<11))
  127.                 {
  128.                         iowrite32(value,virt_EINTPEND);
  129.                 }else if(value = (1<<13))
  130.                 {
  131.                         iowrite32(value,virt_EINTPEND);
  132.                 }else if(value = (1<<14))
  133.                 {
  134.                         iowrite32(value,virt_EINTPEND);
  135.                 }else if(value = (1<<15))
  136.                 {
  137.                         iowrite32(value,virt_EINTPEND);
  138.                 }else if(value = (1<<19))
  139.                 {
  140.                         iowrite32(value,virt_EINTPEND);
  141.                 }
  142.         }
  143. }

  144. static void buttons_lowlevel(void)
  145. {
  146.         unsigned int value;
  147.         value = 0;

  148.         value &= ~((7<<0)|(7<<12)|(7<<20)|(7<<24)|(7<<28));
  149.         iowrite32(value,virt_EXTINT1);

  150.         value &= ~(7<<12);
  151.         iowrite32(value,virt_EXTINT2);
  152. }

  153. static int buttons_open(struct inode *inode,struct file *filp)
  154. {
  155.         filp->private_data = buttons_devp;
  156.         buttons_devp->head = buttons_devp->tail =0;
  157.         return 0;
  158. }

  159. static int buttons_release(struct inode *inode,struct file *filp)
  160. {
  161.         return 0;
  162. }

  163. static ssize_t buttons_read(struct file *filp,char __user *buf,
  164.                                 size_t size,loff_t *ppos)
  165. {
  166.         int ret;
  167.         retry:if(buttons_devp->head != buttons_devp->tail)
  168.         {
  169. //                buf = buttons_devp->buf[buttons_devp->tail];
  170.                 ret = copy_to_user(buf,(void *)buttons_devp->buf[buttons_devp->tail],sizeof(unsigned char));
  171.                 (buttons_devp->tail)++;
  172.                 if(buttons_devp->tail == MAX_BUTTONS_BUF)
  173.                 {
  174.                         buttons_devp->tail = 0;
  175.                 }
  176.         }else{
  177.                 __set_current_state(TASK_INTERRUPTIBLE);
  178.                 if(filp->f_flags & O_NONBLOCK)
  179.                 {
  180.                         return -EAGAIN;
  181.                 }
  182.                 schedule();
  183.                 if(signal_pending(current))
  184.                 {
  185.                         return -ERESTARTSYS;
  186.                 }
  187.                 goto retry;
  188.         }
  189.         return ret;
  190. }
  191.                
  192. static int is_buttons_down(unsigned long data)
  193. {
  194.         int key = data;
  195.         unsigned long ret;
  196.         void __iomem * base = S3C24XX_GPIO_BASE(buttons_info_tab[key].gpio_port);
  197.         unsigned long offs = S3C2410_GPIO_OFFSET(buttons_info_tab[key].gpio_port);
  198.         ret = __raw_readl(base + 0x04) & (1 << offs);
  199.         if(ret == 0)
  200.                 return 1;
  201.         else
  202.                 return 0;
  203. }

  204. static void buttons_event(int data)
  205. {
  206.         int key = data;
  207.         buttons_devp->buf[buttons_devp->head] = buttons_info_tab[key].buttons_no;
  208.         (buttons_devp->head)++;
  209.         if(buttons_devp->head == MAX_BUTTONS_BUF)
  210.                 buttons_devp->head = 0;
  211.         wake_up_interruptible(&buttons_devp->wq);
  212. }

  213. static void buttons_timer_func(unsigned long data)
  214. {
  215.         int key = data;
  216.         if(is_buttons_down(key))
  217.         {
  218.                 if(buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWNX)
  219.                 {
  220.                         buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWN;
  221.                         buttons_event(key);
  222.                         buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
  223.                         add_timer(&buttons_timer[key]);
  224.                 }else{
  225.                         buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
  226.                         add_timer(&buttons_timer[key]);
  227.                 }
  228.         }else{
  229.                 buttons_devp->buttonStatus[key] == BUTTONSTATUS_UP;
  230.                 enable_irq(buttons_info_tab[key].irq_no);
  231.         }
  232. }

  233. static irqreturn_t buttons_eint_func(int irq,void *dev_id,struct pt_regs *regs)
  234. {
  235.         int key = dev_id;
  236.         disable_irq(buttons_info_tab[key].irq_no);
  237.         buttons_enable_irq_again();
  238.         buttons_devp->buttonStatus[key] = BUTTONSTATUS_DOWNX;
  239.         buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY;
  240.         add_timer(&buttons_timer[key]);
  241. }

  242. static int request_irqs(void)
  243. {
  244.         int i,ret;
  245.         buttons_lowlevel();
  246.         for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[1]);i++)
  247.         {
  248.                 set_irq_type(buttons_info_tab[i].irq_no,IRQT_LOW);
  249.                 ret = request_irq(buttons_info_tab[i].irq_no,buttons_eint_func,        SA_INTERRUPT,DEVICE_NAME,i);
  250.                 if(ret)
  251.                         return - EINVAL;
  252.         }
  253.         return 0;
  254. }

  255. static int buttons_setup_cdev(struct buttons_dev *dev,int index)
  256. {
  257.         int err,devno = MKDEV(buttons_major,index);
  258.         cdev_init(&dev->cdev,&buttons_fops);
  259.         dev->cdev.owner = THIS_MODULE;
  260.         dev->cdev.ops = &buttons_fops;
  261.         err = cdev_add(&dev->cdev,devno,1);
  262.         if(err)
  263.                 printk(KERN_NOTICE "Error %d adding",err);
  264.         buttons_enable_irq();
  265.         request_irqs();
  266.         /*****  IOREMAP  *****/
  267.         buttons_ioremap();
  268.         return 0;
  269. }

  270. static int __init buttons_init(void)
  271. {
  272.         int i,result;
  273.         dev_t devno = MKDEV(buttons_major,0);
  274.         if(buttons_major)
  275.                 result = register_chrdev_region(devno,1,DEVICE_NAME);
  276.         else{
  277.                 result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);
  278.                 buttons_major = MAJOR(devno);
  279.         }
  280.         if(result)
  281.                 return result;
  282.         buttons_devp->head = buttons_devp->tail = 0;
  283.         for(i = 0;i < BUTTONS_NUM;i++)
  284.                 buttons_devp->buttonStatus[i] = BUTTONSTATUS_UP;
  285.         for(i = 0;i < BUTTONS_NUM;i++)
  286.                 setup_timer(&buttons_timer[i],buttons_timer_func,i);
  287.         init_waitqueue_head(&(buttons_devp->wq));
  288.         buttons_setup_cdev(buttons_devp,0);
  289.         return 0;
  290. }
  291. module_init(buttons_init);

  292. static void __exit buttons_exit(void)
  293. {
  294.         int i;
  295. //        for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[i]);i++)
  296.                 buttons_iounmap();
  297.         for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[i]);i++)
  298.                 free_irq(buttons_info_tab[i].irq_no,i);
  299.         cdev_del(&buttons_devp->cdev);
  300.         for(i = 0;i < BUTTONS_NUM;i++)
  301.                 del_timer(&buttons_timer[i]);
  302.         unregister_chrdev_region(MKDEV(buttons_major,0),1);
  303. }
  304. module_exit(buttons_exit);
  305. MODULE_LICENSE("Dual BSD/GPL");
  306. MODULE_AUTHOR("bejoey_pro");


复制代码

[ 本帖最后由 bejoey_pro 于 2009-4-11 16:17 编辑 ]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2009-04-11 15:43 |只看该作者
发代码的时候请用code包起来
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP