老师:
我想用中断注册的方式实现按键扫描,但是中断注册总是出错,报错值是-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(&quot;irq = %d\n&quot;, 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(&quot;Key Intr open\n&quot;);
return 0;
}
int KeyIntrRead(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
printk(&quot;Key intr read\n&quot;);
if(size != 1)
{
printk(&quot;You just need to read 1 data\n&quot;);
return -1;
}
//sleep
wait_event_interruptible(Buttons_WaitQ, ReadFlag);
printk(&quot;There's key event\n&quot;);
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 = &quot;S3C6410 Intr0-3&quot;,
.flags = IRQ_TYPE_EDGE_BOTH | IRQF_SHARED,
.handler = ButtonsIRQ,
};
static struct irqaction Button1_IRQ = {
.name = &quot;S3C6410 Intr4-11&quot;,
.flags = IRQ_TYPE_EDGE_BOTH | IRQF_SHARED,
.handler = ButtonsIRQ,
};
static int KeyIntrInit()
{
printk(&quot;Key intr Init\n&quot;);
major = register_chrdev(0, &quot;KeyIntr&quot;, &KeyIntrFiles);
//Auto create the node
KeyIntrClass = class_create(THIS_MODULE, &quot;KeyIntr&quot;);
if(IS_ERR(KeyIntrClass))
{
return PTR_ERR(KeyIntrClass);
}
KeyIntrClassDev = device_create(KeyIntrClass, NULL, MKDEV(major, 0), NULL, &quot;%s&quot;,&quot;KeyIntr&quot;);
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, &quot;ButtonsG1&quot;, NULL);
if(ret != 0)
printk(&quot;register IRQ_EINT0_3 fail, ret = %d\n&quot;, ret);
ret = 0;
ret = request_irq(IRQ_EINT4_11, ButtonsIRQ, IRQ_TYPE_EDGE_FALLING, &quot;ButtonsG2&quot;, NULL);
if(ret != 0)
printk(&quot;register IRQ_EINT4_11 fail, ret = %d\n&quot;, ret);
#endif
int ret = setup_irq(IRQ_EINT0_3, &Button0_IRQ);
if(ret != 0)
printk(&quot;setup irq EINT0-3 fail, ret = %d\n&quot;, ret);
else
printk(&quot;setup irq EINT0-3 successful, ret = %d\n&quot;, ret);
ret = 0;
ret = setup_irq(IRQ_EINT4_11, &Button1_IRQ);
if(ret != 0)
printk(&quot;setup irq EINT4-11 fail, ret = %d\n&quot;, ret);
else
printk(&quot;setup irq EINT4-11 successful, ret = %d\n&quot;, ret);
return 0;
}
static void KeyIntrExit()
{
device_destroy(KeyIntrClass, MKDEV(major, 0));
class_destroy(KeyIntrClass);
unregister_chrdev(major, &quot;ScanKey&quot;);
iounmap(gpncon);
free_irq(IRQ_EINT0_3, NULL);
free_irq(IRQ_EINT4_11, NULL);
printk(&quot;Scan Key exit\n&quot;);
}
module_init(KeyIntrInit);
module_exit(KeyIntrExit);
MODULE_LICENSE(&quot;GPL&quot;);
这可以注册成功,但是不能触发中断。
谢谢! |