嵌入式爱好者

查看: 11195|回复: 3

[Linux] OK6410外部中断注册问题

[复制链接]

2

主题

3

帖子

8

积分

扫一扫,手机访问本帖
发表于 2017-12-14 22:27:42 | 显示全部楼层 |阅读模式
老师:
我想用中断注册的方式实现按键扫描,但是中断注册总是出错,报错值是-22,请指点下下面代码到底哪有问题,困扰了好几天了,非常感谢。


int ret = 0;

ret = request_irq(IRQ_EINT0_3, ButtonsIRQ, IRQ_TYPE_EDGE_FALLING, "ButtonsG1", NULL);
if(ret != 0)
    printk("register IRQ_EINT0_3 fail, ret = %d\n", ret);

ret = 0;
ret = request_irq(IRQ_EINT4_11, ButtonsIRQ, IRQ_TYPE_EDGE_FALLING, "ButtonsG2", NULL);
if(ret != 0)
    printk("register IRQ_EINT4_11 fail, ret = %d\n", ret);这种方式注册失败,返回值-22.

#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/interrupt.h>

#include <asm/io.h>
#include <asm/irq.h>


#include <asm/types.h>      // for variable types

//Key1-6   GPN0~N5
volatile unsigned long *gpncon;
volatile unsigned long *gpndat;
volatile unsigned long *gpnpud;

static volatile unsigned int ReadFlag = 0;
static DECLARE_WAIT_QUEUE_HEAD(Buttons_WaitQ);

unsigned char KeyVal = 0;

static irqreturn_t ButtonsIRQ(int irq, void *dev_id)
{
    printk("irq = %d\n", irq);

    unsigned long RegVal = *gpndat;

    if(irq == IRQ_EINT0_3)
    {
        if(RegVal == 0x7e)
            KeyVal = 0;
        else if(RegVal == 0x7d)
            KeyVal = 1;
        else if(RegVal == 0x7b)
            KeyVal = 2;
        else if(RegVal == 0x77)
            KeyVal = 3;
        else if(RegVal == 0x6F)
            KeyVal = 4;
    }
    else
{
        if(RegVal == 0x5F)
            KeyVal = 5;
    }

    //wake up to read
    ReadFlag = 1;
    wake_up_interruptible(&Buttons_WaitQ);

    return IRQ_HANDLED;
}

int KeyIntrOpen(const char *pathname, int flags)
{
    printk("Key Intr open\n");

    return 0;
}

int KeyIntrRead(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
    printk("Key intr read\n");

    if(size != 1)
    {
        printk("You just need to read 1 data\n");
        return -1;
    }

    //sleep
    wait_event_interruptible(Buttons_WaitQ, ReadFlag);
    printk("There's key event\n");
    copy_to_user(buf, &KeyVal, 1);
    ReadFlag = 0;

    return 0;
}


static struct file_operations KeyIntrFiles =
{
    .owner = THIS_MODULE,
    .open = KeyIntrOpen,
    .read = KeyIntrRead,
};

int major;
static struct class *KeyIntrClass;
static struct class_device *KeyIntrClassDev;

static struct irqaction Button0_IRQ = {
        .name     = "S3C6410 Intr0-3",
        .flags    = IRQ_TYPE_EDGE_BOTH | IRQF_SHARED,
        .handler   = ButtonsIRQ,
};

static struct irqaction Button1_IRQ = {
        .name     = "S3C6410 Intr4-11",
        .flags    = IRQ_TYPE_EDGE_BOTH | IRQF_SHARED,
        .handler   = ButtonsIRQ,
};

static int KeyIntrInit()
{
    printk("Key intr Init\n");
    major = register_chrdev(0, "KeyIntr", &KeyIntrFiles);
    //Auto create the node
    KeyIntrClass = class_create(THIS_MODULE, "KeyIntr");
    if(IS_ERR(KeyIntrClass))
    {
        return PTR_ERR(KeyIntrClass);
    }

    KeyIntrClassDev = device_create(KeyIntrClass, NULL, MKDEV(major, 0), NULL, "%s","KeyIntr");

    gpncon = (volatile unsigned long *)ioremap(0x7F008830, 16);
    gpndat = gpncon + 1;
    gpnpud = gpncon + 2;

#if 0

    int ret = 0;

    ret = request_irq(IRQ_EINT0_3, ButtonsIRQ, IRQ_TYPE_EDGE_FALLING, "ButtonsG1", NULL);
    if(ret != 0)
        printk("register IRQ_EINT0_3 fail, ret = %d\n", ret);

    ret = 0;
    ret = request_irq(IRQ_EINT4_11, ButtonsIRQ, IRQ_TYPE_EDGE_FALLING, "ButtonsG2", NULL);
    if(ret != 0)
        printk("register IRQ_EINT4_11 fail, ret = %d\n", ret);
#endif

    int ret = setup_irq(IRQ_EINT0_3, &Button0_IRQ);
    if(ret != 0)
        printk("setup irq EINT0-3 fail, ret = %d\n", ret);
    else
printk("setup irq EINT0-3 successful, ret = %d\n", ret);

    ret = 0;
    ret = setup_irq(IRQ_EINT4_11, &Button1_IRQ);
    if(ret != 0)
        printk("setup irq EINT4-11 fail, ret = %d\n", ret);
    else
printk("setup irq EINT4-11 successful, ret = %d\n", ret);

    return 0;
}

static void KeyIntrExit()
{
    device_destroy(KeyIntrClass, MKDEV(major, 0));
    class_destroy(KeyIntrClass);
    unregister_chrdev(major, "ScanKey");
    iounmap(gpncon);

    free_irq(IRQ_EINT0_3, NULL);
    free_irq(IRQ_EINT4_11, NULL);
   
    printk("Scan Key exit\n");
}

module_init(KeyIntrInit);
module_exit(KeyIntrExit);

MODULE_LICENSE("GPL");

这可以注册成功,但是不能触发中断。

谢谢!


回复

使用道具 举报

1

主题

3669

帖子

3925

积分

发表于 2017-12-15 11:37:56 | 显示全部楼层
您好:
    不好意思,您这要求已经超出我们的技术支持范畴了,不过可以给您一些建议,我们外接模块有4X4的矩阵键盘,您可以参考一下矩阵键盘的中断注册
技术支持电话:0312-3119192
技术支持邮箱:Android@forlinx.com
回复 支持 反对

使用道具 举报

2

主题

3

帖子

8

积分

 楼主| 发表于 2017-12-15 18:20:13 | 显示全部楼层
好的,非常感谢,我看下
回复 支持 反对

使用道具 举报

2

主题

4

帖子

27

积分

AM335x通行证i.MX6Q通行证FCU1201通行证

发表于 2018-8-28 16:37:42 | 显示全部楼层
请问这个IRQ_EINT0_3是在哪个文件中定义的?
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-24 15:32

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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