Chinaunix首页 | 论坛 | 博客
  • 博客访问: 95312
  • 博文数量: 38
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 384
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-06 16:52
文章分类

全部博文(38)

文章存档

2014年(38)

我的朋友

分类: 嵌入式

2014-05-05 19:51:29

1.查看OK6410的原理图,看到GPN0-GPN5分别对应中断XEINT0-XEINT5


2.简单的按键中断驱动程序button_irq.c代码如下所示

点击(此处)折叠或打开

  1. //moudle.h 包含了大量加载模块需要的函数和符号的定义
  2. #include <linux/module.h>
  3. //kernel.h以便使用printk()等函数
  4. #include <linux/kernel.h>
  5. //fs.h包含常用的数据结构,如struct file等
  6. #include <linux/fs.h>
  7. //uaccess.h 包含copy_to_user(),copy_from_user()等函数
  8. #include <linux/uaccess.h>
  9. //io.h 包含inl(),outl(),readl(),writel()等IO口操作函数
  10. #include <linux/io.h>
  11. #include <linux/miscdevice.h>
  12. #include <linux/pci.h>
  13. //init.h来指定你的初始化和清理函数,例如:module_init(init_function)、module_exit(cleanup_function)
  14. #include <linux/init.h>
  15. #include <linux/delay.h>
  16. #include <linux/device.h>
  17. #include <linux/cdev.h>
  18. #include <linux/gpio.h>
  19. #include <linux/irq.h>
  20. #include <linux/sched.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/poll.h>
  23. //irq.h中断与并发请求事件
  24. #include <asm/irq.h>
  25. //下面这些头文件是IO口在内核的虚拟映射地址,涉及IO口的操作所必须包含
  26. //#include <mach/gpio.h>
  27. #include <mach/regs-gpio.h>
  28. #include <plat/gpio-cfg.h>
  29. #include <mach/hardware.h>
  30. #include <mach/map.h>


  31. static struct class *button_irq_class;
  32. static int major;


  33. /*中断服务函数*/
  34. static irqreturn_t button_irq(int irq, void *dev_id)
  35. {
  36.     printk("irq = %d\n",irq );//打印中断号
  37.     return IRQ_HANDLED;
  38. }

  39. static int button_irq_open(struct inode *inode, struct file *file)
  40. {    
  41.     int ret;
  42.     
  43.     /*request_irq注册中断
  44.     *第一个参数是中断号,也是中断处理函数button_irq的第一个参数
  45.     *第二个参数是中断处理函数
  46.     *第三个参数是中断触发方式
  47.     *第四个参数是设备名称
  48.     *第五个参数是设备ID,也是中断处理函数button_irq的第二个参数
  49.      */
  50.     ret = request_irq(IRQ_EINT(0), button_irq, IRQ_TYPE_EDGE_BOTH, "k1", 1);
  51.     if (ret){
  52.         printk("request IRQ_EINT(0) error!\n");
  53.         free_irq(IRQ_EINT(0), 1);
  54.     }    
  55.     ret = request_irq(IRQ_EINT(1), button_irq, IRQ_TYPE_EDGE_BOTH, "k2", 1);
  56.     if (ret){
  57.         printk("request IRQ_EINT(1) error!\n");
  58.         free_irq(IRQ_EINT(1), 1);
  59.     }
  60.         
  61.     ret = request_irq(IRQ_EINT(2), button_irq, IRQ_TYPE_EDGE_BOTH, "k3", 1);
  62.     if (ret){
  63.         printk("request IRQ_EINT(2) error!\n");
  64.         free_irq(IRQ_EINT(2), 1);
  65.     }
  66.         
  67.     ret = request_irq(IRQ_EINT(3), button_irq, IRQ_TYPE_EDGE_BOTH, "k4", 1);
  68.     if (ret){
  69.         printk("request IRQ_EINT(3) error!\n");
  70.         free_irq(IRQ_EINT(3), 1);
  71.     }
  72.         
  73.     ret = request_irq(IRQ_EINT(4), button_irq, IRQ_TYPE_EDGE_BOTH, "k5", 1);
  74.     if (ret){
  75.         printk("request IRQ_EINT(4) error!\n");
  76.         free_irq(IRQ_EINT(4), 1);
  77.     }
  78.         
  79.     ret = request_irq(IRQ_EINT(5), button_irq, IRQ_TYPE_EDGE_BOTH, "k6", 1);
  80.     if (ret){
  81.         printk("request IRQ_EINT(5) error!\n");
  82.         free_irq(IRQ_EINT(5), 1);
  83.     }
  84.     return 0;
  85. }

  86. static ssize_t button_irq_read(struct file *file, char __user *buf, size_t size, loff_t * ppos)
  87. {   
  88.     return 0;
  89. }

  90. static ssize_t button_irq_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
  91. {
  92.     return 0;
  93. }

  94. static int button_irq_release(struct inode *inode, struct file *file)

  95. {
  96.     free_irq(IRQ_EINT(0), 1);    
  97.     free_irq(IRQ_EINT(1), 1);
  98.     free_irq(IRQ_EINT(2), 1);
  99.     free_irq(IRQ_EINT(3), 1);
  100.     free_irq(IRQ_EINT(4), 1);
  101.     free_irq(IRQ_EINT(5), 1);

  102.     return 0;
  103. }

  104. static struct file_operations button_irq_fops = {
  105.     .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
  106.     .open = button_irq_open,
  107.     .read = button_irq_read,
  108.     .write = button_irq_write,
  109.     .release = button_irq_release,
  110. };

  111. static int button_irq_init(void)
  112. {
  113.     major = register_chrdev(0, "button_irq_dev", &button_irq_fops);//注册,告诉内核
  114.     button_irq_class = class_create(THIS_MODULE, "button_irq_cls");
  115.     device_create(button_irq_class, NULL, MKDEV(major, 0), NULL, "button_irq");/* /dev/button_irq */
  116.     
  117.     return 0;
  118. }

  119. static void button_irq_exit(void)
  120. {
  121.     unregister_chrdev(major, "button_irq_cls");
  122.     device_destroy(button_irq_class, MKDEV(major, 0));
  123.     class_destroy(button_irq_class);
  124. }

  125. module_init(button_irq_init);
  126. module_exit(button_irq_exit);

  127. MODULE_LICENSE("GPL");
3.把编译出的button_irq.ko拷贝到开发板,分别执行以下命令
    insmod button_irq.ko         加载驱动
    exec 5/dev/button_irq读入到fd5中
    ps                                    查看-/bin/sh的进程号,这里为963
    ls -l /proc/963/fd               看到fd5指向/dev/button_irq
    cat /proc/interrupts            看到k1-k5,中断已经注册成功了
    按下按键就能打印出中断号了
    exec 5<&-                        关闭fb5
    rmmod
button_irq             卸载驱动
    
阅读(879) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~