嵌入式爱好者

查看: 5494|回复: 1

[Linux] ok6410驱动中段注册失败

[复制链接]

2

主题

3

帖子

8

积分

扫一扫,手机访问本帖
发表于 2017-12-14 22:19:30 | 显示全部楼层 |阅读模式
老师:
我想用中断注册的方式实现按键扫描,但是中断注册总是出错,报错值是-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

帖子

3884

积分

发表于 2017-12-15 11:38:43 | 显示全部楼层
技术支持电话:0312-3119192
技术支持邮箱:Android@forlinx.com
点评回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 13:32

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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