外部中断驱动问题,能注册成功中断但是无法进入中断,求助
本帖最后由 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);
//代码结束
或者谁给我一份能用的外部中断的驱动代码也好,卡在这里了
页:
[1]