嵌入式爱好者

查看: 9411|回复: 1

[Linux] 外部中断驱动问题,能注册成功中断但是无法进入中断,求助

[复制链接]

1

主题

2

帖子

5

积分

扫一扫,手机访问本帖
发表于 2015-1-25 11:44:47 | 显示全部楼层 |阅读模式
本帖最后由 pjj1992 于 2015-1-25 11:53 编辑

最近用ok6410写外部中断的驱动,用的是第2组外部中断,看芯片手册是53号中断,注册中断没问题,但是怎么也进不了中断函数,我觉得是寄存器配置问题,捣鼓了好几天,参考了好些资料,还是不能进入中断,谁能不能告诉我这个的寄存器配置流程。下面贴我的代码,若能指点一二,不胜感激!!!
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/fs.h>
  4. #include <linux/cdev.h>
  5. #include <linux/device.h>
  6. #include <asm/io.h>
  7. #include <asm/uaccess.h>
  8. #include <linux/interrupt.h>

  9. volatile static unsigned long *REG_GPC_CON2;
  10. volatile static unsigned long *REG_GPC_DAT;
  11. volatile static unsigned long *REG_GPC_PULL;
  12. volatile static unsigned long *REG_EINT_CON2;
  13. volatile static unsigned long *REG_EINT_MASK2;
  14. volatile static unsigned long *REG_EINT_PEND2;
  15. volatile static unsigned long *REG_VIC1_INTENABLE;
  16. volatile static unsigned long *REG_VIC1_VECTADDR;
  17. volatile static unsigned long *REG_VIC1_CLEAR;
  18. volatile static unsigned long *REG_VIC1_STATUS;
  19. volatile static unsigned long *REG_VIC1_ADDRESS;
  20. volatile static unsigned long *REG_VIC0_ADDRESS;
  21. volatile static unsigned long *REG_VIC1_SELECT;

  22. static irqreturn_t EINT_TEST(int irq, void *dev_id)
  23. {
  24.         *REG_EINT_PEND2 |= (0x1 << 18);
  25.         printk("this is interrupt!\n");
  26.         *REG_VIC1_ADDRESS = 0x0;
  27.         *REG_VIC0_ADDRESS = 0x0;

  28.         return IRQ_HANDLED;
  29. }

  30. //用户程序接口部分
  31. static int EINT_open(struct inode* n, struct file* f)
  32. {
  33.         int result;

  34.         REG_GPC_CON2 = (volatile unsigned long *)ioremap(0x7F008040, 4);
  35.         REG_GPC_DAT = (volatile unsigned long *)ioremap(0x7F008044, 4);
  36.         REG_GPC_PULL = (volatile unsigned long *)ioremap(0x7F008048, 4);
  37.         REG_EINT_CON2 = (volatile unsigned long *)ioremap(0x7F008200, 4);
  38.         REG_EINT_MASK2 = (volatile unsigned long *)ioremap(0x7F008240, 4);
  39.         REG_EINT_PEND2 = (volatile unsigned long *)ioremap(0x7F008260, 4);
  40.         REG_VIC1_INTENABLE = (volatile unsigned long *)ioremap(0x71300010, 4);
  41.         REG_VIC1_VECTADDR = (volatile unsigned long *)ioremap(0x71300100, 4);
  42.         REG_VIC1_CLEAR = (volatile unsigned long *)ioremap(0x71300014, 4);
  43.         REG_VIC1_STATUS = (volatile unsigned long *)ioremap(0x71300000, 4);
  44.         REG_VIC1_ADDRESS = (volatile unsigned long *)ioremap(0x71300F00, 4);
  45.         REG_VIC1_SELECT = (volatile unsigned long *)ioremap(0x7130000c, 4);
  46.         REG_VIC0_ADDRESS = (volatile unsigned long *)ioremap(0x71200F00, 4);
  47.         
  48. //        printk("%d \n\n", sizeof(REG_GPC_CON2));
  49. /************引脚配置**********/
  50.         *REG_GPC_CON2 &= ~(0xF << 8);
  51.         *REG_GPC_CON2 |= (0x7 << 8); //外部中断
  52.         *REG_GPC_PULL &= ~(0x3 << 4);
  53.         *REG_GPC_PULL |= (0x1 << 4); //下拉电阻使能
  54.         *REG_EINT_CON2 &= ~(0x7 << 16);
  55.         *REG_EINT_CON2 |= (0x1 << 16); //high level
  56.         *REG_EINT_MASK2 &= ~(0x1 << 18);

  57. /******总中断控制器配置********/
  58.         *REG_VIC1_CLEAR |= (0x1 << 21);
  59.         *REG_VIC1_SELECT &= ~(0x1 << 21);
  60.         *REG_VIC1_ADDRESS = 0x0;
  61.         *REG_VIC0_ADDRESS = 0x0;

  62. /*********中断使能************/
  63.         *REG_VIC1_INTENABLE |= (0x1 << 21); //中断控制器中断使能

  64. /*********加载中断程序*******/
  65.         REG_VIC1_VECTADDR[21] = (unsigned )EINT_TEST; //中断程序地址

  66.         result = request_irq(53, EINT_TEST, IRQF_DISABLED, "EINT", NULL); //注册中断
  67.         if(result != 0)
  68.         {
  69.                 printk("EINT error! -> %d\n", result);
  70.                 free_irq(53, NULL);
  71.                 return result;
  72.         }
  73.         
  74.         printk("Open Finished!\n");      
  75.         return 0;
  76. }

  77. static int EINT_close(struct inode* n, struct file* f)
  78. {        

  79.         iounmap(REG_GPC_CON2);
  80.         iounmap(REG_GPC_DAT);
  81.         iounmap(REG_GPC_PULL);
  82.         iounmap(REG_EINT_CON2);
  83.         iounmap(REG_EINT_MASK2);
  84.         iounmap(REG_EINT_PEND2);
  85.         iounmap(REG_VIC1_INTENABLE);
  86.         iounmap(REG_VIC1_VECTADDR);
  87.         iounmap(REG_VIC1_CLEAR);
  88.         iounmap(REG_VIC1_STATUS);
  89.         iounmap(REG_VIC1_ADDRESS);
  90.         iounmap(REG_VIC0_ADDRESS);
  91.         iounmap(REG_VIC1_SELECT);
  92.         free_irq(53, NULL);
  93.         printk("Close Finished!\n");
  94.         return 0;
  95. }

  96. static ssize_t EINT_write(struct file* f, const char __user* buf, size_t len, loff_t* l)
  97. {
  98.         printk("Write Finished!\n");
  99.         return len;
  100. }

  101. static ssize_t EINT_read(struct file* f, char __user* buf, size_t len, loff_t* l)
  102. {
  103.         printk("Read Finished!\n");
  104.         return 0;
  105. }


  106. //操作系统接口部分
  107. #define DEV_NAME        "EINT"
  108. #define DEV_COUNT        1

  109. static struct class* pClass;
  110. int major;

  111. static struct file_operations fops =
  112. {
  113.         .owner = THIS_MODULE,
  114.         .open = EINT_open,
  115.         .write = EINT_write,
  116.         .read = EINT_read,
  117.         .release = EINT_close,
  118. };


  119. static int __init EINT_init(void)
  120. {
  121.         major = register_chrdev(0, DEV_NAME, &fops);
  122.         pClass = class_create(THIS_MODULE, DEV_NAME);
  123.         if (pClass == NULL)
  124.         {
  125.                 unregister_chrdev(major, DEV_NAME);
  126.                 return -1;
  127.         }
  128.         device_create(pClass, NULL, MKDEV(major, 0),  NULL, DEV_NAME);
  129.         
  130. /*        REG_GPC_CON2 = (volatile unsigned long *)ioremap(0x7F008040, 4);
  131.         REG_GPC_DAT = (volatile unsigned long *)ioremap(0x7F008044, 4);
  132.         REG_GPC_PULL = (volatile unsigned long *)ioremap(0x7F008048, 4);
  133.         REG_EINT_CON2 = (volatile unsigned long *)ioremap(0x7F008200, 4);
  134.         REG_EINT_MASK2 = (volatile unsigned long *)ioremap(0x7F008240, 4);
  135.         REG_EINT_PEND2 = (volatile unsigned long *)ioremap(0x7F008260, 4);
  136. */
  137.         printk("Init Finished!\n");

  138.         return 0;
  139. }

  140. static void __exit EINT_exit(void)
  141. {
  142.         unregister_chrdev(major, DEV_NAME);
  143.         if (pClass)
  144.         {
  145.                 device_destroy(pClass, MKDEV(major, 0));
  146.                 class_destroy(pClass);
  147.         }
  148.         printk("Exit Finished!\n");
  149. }

  150. MODULE_LICENSE("GPL");
  151. MODULE_AUTHOR("PuJunji");
  152. module_init(EINT_init);
  153. module_exit(EINT_exit);
  154. //代码结束

复制代码
回复

使用道具 举报

1

主题

2

帖子

5

积分

 楼主| 发表于 2015-1-25 14:05:16 | 显示全部楼层
或者谁给我一份能用的外部中断的驱动代码也好,卡在这里了
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-6-2 23:14

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表