pjj1992 发表于 2015-1-25 11:44:47

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

本帖最后由 pjj1992 于 2015-1-25 11:53 编辑

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

volatile static unsigned long *REG_GPC_CON2;
volatile static unsigned long *REG_GPC_DAT;
volatile static unsigned long *REG_GPC_PULL;
volatile static unsigned long *REG_EINT_CON2;
volatile static unsigned long *REG_EINT_MASK2;
volatile static unsigned long *REG_EINT_PEND2;
volatile static unsigned long *REG_VIC1_INTENABLE;
volatile static unsigned long *REG_VIC1_VECTADDR;
volatile static unsigned long *REG_VIC1_CLEAR;
volatile static unsigned long *REG_VIC1_STATUS;
volatile static unsigned long *REG_VIC1_ADDRESS;
volatile static unsigned long *REG_VIC0_ADDRESS;
volatile static unsigned long *REG_VIC1_SELECT;

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

      return IRQ_HANDLED;
}

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

      REG_GPC_CON2 = (volatile unsigned long *)ioremap(0x7F008040, 4);
      REG_GPC_DAT = (volatile unsigned long *)ioremap(0x7F008044, 4);
      REG_GPC_PULL = (volatile unsigned long *)ioremap(0x7F008048, 4);
      REG_EINT_CON2 = (volatile unsigned long *)ioremap(0x7F008200, 4);
      REG_EINT_MASK2 = (volatile unsigned long *)ioremap(0x7F008240, 4);
      REG_EINT_PEND2 = (volatile unsigned long *)ioremap(0x7F008260, 4);
      REG_VIC1_INTENABLE = (volatile unsigned long *)ioremap(0x71300010, 4);
      REG_VIC1_VECTADDR = (volatile unsigned long *)ioremap(0x71300100, 4);
      REG_VIC1_CLEAR = (volatile unsigned long *)ioremap(0x71300014, 4);
      REG_VIC1_STATUS = (volatile unsigned long *)ioremap(0x71300000, 4);
      REG_VIC1_ADDRESS = (volatile unsigned long *)ioremap(0x71300F00, 4);
      REG_VIC1_SELECT = (volatile unsigned long *)ioremap(0x7130000c, 4);
      REG_VIC0_ADDRESS = (volatile unsigned long *)ioremap(0x71200F00, 4);
      
//      printk("%d \n\n", sizeof(REG_GPC_CON2));
/************引脚配置**********/
      *REG_GPC_CON2 &= ~(0xF << 8);
      *REG_GPC_CON2 |= (0x7 << 8); //外部中断
      *REG_GPC_PULL &= ~(0x3 << 4);
      *REG_GPC_PULL |= (0x1 << 4); //下拉电阻使能
      *REG_EINT_CON2 &= ~(0x7 << 16);
      *REG_EINT_CON2 |= (0x1 << 16); //high level
      *REG_EINT_MASK2 &= ~(0x1 << 18);

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

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

/*********加载中断程序*******/
      REG_VIC1_VECTADDR = (unsigned )EINT_TEST; //中断程序地址

      result = request_irq(53, EINT_TEST, IRQF_DISABLED, "EINT", NULL); //注册中断
      if(result != 0)
      {
                printk("EINT error! -> %d\n", result);
                free_irq(53, NULL);
                return result;
      }
      
      printk("Open Finished!\n");      
      return 0;
}

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

      iounmap(REG_GPC_CON2);
      iounmap(REG_GPC_DAT);
      iounmap(REG_GPC_PULL);
      iounmap(REG_EINT_CON2);
      iounmap(REG_EINT_MASK2);
      iounmap(REG_EINT_PEND2);
      iounmap(REG_VIC1_INTENABLE);
      iounmap(REG_VIC1_VECTADDR);
      iounmap(REG_VIC1_CLEAR);
      iounmap(REG_VIC1_STATUS);
      iounmap(REG_VIC1_ADDRESS);
      iounmap(REG_VIC0_ADDRESS);
      iounmap(REG_VIC1_SELECT);
      free_irq(53, NULL);
      printk("Close Finished!\n");
      return 0;
}

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

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


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

static struct class* pClass;
int major;

static struct file_operations fops =
{
      .owner = THIS_MODULE,
      .open = EINT_open,
      .write = EINT_write,
      .read = EINT_read,
      .release = EINT_close,
};


static int __init EINT_init(void)
{
      major = register_chrdev(0, DEV_NAME, &fops);
      pClass = class_create(THIS_MODULE, DEV_NAME);
      if (pClass == NULL)
      {
                unregister_chrdev(major, DEV_NAME);
                return -1;
      }
      device_create(pClass, NULL, MKDEV(major, 0),NULL, DEV_NAME);
      
/*      REG_GPC_CON2 = (volatile unsigned long *)ioremap(0x7F008040, 4);
      REG_GPC_DAT = (volatile unsigned long *)ioremap(0x7F008044, 4);
      REG_GPC_PULL = (volatile unsigned long *)ioremap(0x7F008048, 4);
      REG_EINT_CON2 = (volatile unsigned long *)ioremap(0x7F008200, 4);
      REG_EINT_MASK2 = (volatile unsigned long *)ioremap(0x7F008240, 4);
      REG_EINT_PEND2 = (volatile unsigned long *)ioremap(0x7F008260, 4);
*/
      printk("Init Finished!\n");

      return 0;
}

static void __exit EINT_exit(void)
{
      unregister_chrdev(major, DEV_NAME);
      if (pClass)
      {
                device_destroy(pClass, MKDEV(major, 0));
                class_destroy(pClass);
      }
      printk("Exit Finished!\n");
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("PuJunji");
module_init(EINT_init);
module_exit(EINT_exit);
//代码结束

pjj1992 发表于 2015-1-25 14:05:16

或者谁给我一份能用的外部中断的驱动代码也好,卡在这里了
页: [1]
查看完整版本: 外部中断驱动问题,能注册成功中断但是无法进入中断,求助