简单按键驱动问题的请教
//头文件#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/poll.h>
#include <linux/signal.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/sysdev.h>
#include <asm/hardware/vic.h>
#include <plat/regs-irqtype.h>
#include <mach/map.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>
#include <mach/irqs.h>
#include <mach/gpio-bank.h>
#include <linux/delay.h>
#include <asm/delay.h>
#include <asm/param.h>
#include <linux/io.h>
#include <linux/sysdev.h>
#include <mach/map.h>
#define DEVICE_NAME "menu_test"
//#define IRQ_NO (IRQ_EINT(16))
struct menu_dev {
struct cdev cdev;
};
struct menu_dev *menu_devp;//设备结构体指针
int IRQ_NO;//定义中断号
//函数声明
static intmenu_major = 250;
static void menu_setup_cdev(struct menu_dev * , int );
static int menu_init(void);
static int menu_open(struct inode * , struct file *);
static int menu_release(struct inode * ,struct file *);
static void init_gpio(void);
//中断处理函数
irqreturn_t menu_interrupt(int irq, void *dev_id)
{
printk("menu_interrupt start.....!\n");
disable_irq_nosync(irq);//关中断
udelay(5);//延迟5ms,消除毛刺信号
printk("i am interrup handler\n");
init_gpio();
enable_irq(irq);//开中断
printk("menu_interruptover.......!\n");
return IRQ_HANDLED;
}
//初始化配置函数
static void init_gpio(void)
{
int error;
printk("init_gpio start....\n");
error = gpio_request(S5PV210_GPH2(0),"gpio_keys");//检查gpio管脚是否被使用
if (error < 0)
printk("gpio-keys: failed to request GPIO %d \n", S5PV210_GPH2(0));
else
printk("gpio %d success!\n",S5PV210_GPH2(0));
s3c_gpio_cfgpin(S5PV210_GPH2(0),0xf); //将管脚配置为中断模式
IRQ_NO = gpio_to_irq(S5PV210_GPH2(0));//获取中断号,其实这个我也不太清楚,看别人的。
if (error < 0)
printk("gpio_to_irq: failed%d \n", S5PV210_GPH2(0));
else
printk("gpio_to_irq %d success!\n",S5PV210_GPH2(0));
//配置为输出 且为低电平
s3c_gpio_cfgpin(S5PV210_GPH3(0),S3C_GPIO_OUTPUT);//配置为输出,低电平 EINT24号管脚 参照原理图上的。
s3c_gpio_setpin(S5PV210_GPH3(0),1);
s3c_gpio_cfgpin(S5PV210_GPH3(1),S3C_GPIO_OUTPUT);//配置为输出,低电平 EINT25号管脚
s3c_gpio_setpin(S5PV210_GPH3(1),1);
//设置下降沿触发
set_irq_type(IRQ_NO,IRQ_TYPE_EDGE_FALLING);
printk("init_gpio successed!\n");
}
static int menu_open(struct inode *inode , struct file *filp)
{
int ret;
init_gpio();//对相关端口初始化
ret = request_irq(IRQ_NO, menu_interrupt,IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DEVICE_NAME, NULL);
if(ret < 0){
printk("request_irqfailer\n");
return -EFAULT;
}
else
printk("request_irq success !\n");
return ret;
}
static int menu_release(struct inode *inode ,struct file *filp)
{
printk("this is release\n");
free_irq(IRQ_NO,NULL);
return 0;
}
static struct file_operations menu_fops = {
.owner = THIS_MODULE,
.open = menu_open,
.release = menu_release,
};
static void menu_setup_cdev(struct menu_dev *dev, int minor)
{
int err;
int devno = MKDEV(menu_major,minor);
cdev_init(&dev->cdev,&menu_fops);
dev -> cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev, devno, 1);
if(err){
printk("error%d adding menu %d \n",err,minor);
}
printk("menu_setup_cdevover!\n");
}
static int menu_init(void)
{
int ret = 0;
dev_t dev = MKDEV(menu_major , 0);
if(menu_major)
ret = register_chrdev_region(dev, 1, DEVICE_NAME);
else{
ret = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
menu_major = MAJOR(dev);
}
if(ret < 0){
printk("unable to get major %d \n",menu_major);
return ret;
}
menu_devp = kmalloc(sizeof(struct menu_dev),GFP_KERNEL);
if(!menu_devp)
{
ret = -ENOMEM;
}
memset(menu_devp,0,sizeof(struct menu_dev));
menu_setup_cdev(menu_devp, 0 );
printk("menu driver initialized\n");
return 0;
}
//驱动卸载
void menu_exit(void)
{
cdev_del(&menu_devp->cdev);
unregister_chrdev_region(MKDEV(menu_major,0),1);
printk("menu driver unistalled \n");
}
module_init(menu_init);
module_exit(menu_exit);
MODULE_LICENSE("Dual BSD/GPL");
这是我写得一个简单的按键驱动,只是想实现,如果按键就会产生中断,进入中断处理函数,打印信息。 我搞了几天,要不就是中断申请失败,要不就是中断申请成功,可是按键没有反应。想请高手帮我看看,**问题。
这是我的部分原理图,我想通过按下menu或者home键,能产生一个中断
这个图是上面代码执行结果。 本帖最后由 jackyard 于 2012-08-20 17:08 编辑
你的这个不是共享中断吧,request_irq函数的每三个参数把IRQF_SHARED,先取掉。gpio_to_irq是获取对应书脚上的中断号,你的原理图上已经给你指出来了。还有你的这个按键原理图是矩阵按键。获取中断,还要作一些处理。EINT24不能配置成低电平,前面有一个4148的.好像你的这个4148是不是接反了。 你好,
1.这个IRQF_SHARED是我乱试的,去掉肯定没问题。
2.你说的矩阵键盘,获取中断还要做些处理,能说的具体点吗
3. EINT24,为啥不能低电平,但是,EINT24,25,同时设置高电平,我也试过了。也是不行。
jackyard 发表于 2012-08-20 16:51 static/image/common/back.gif
你的这个不是共享中断吧,request_irq函数的每三个参数把IRQF_SHARED,先取掉。gpio_to_irq是获取对应书脚上 ... 前面有一个4148的.好像你的这个4148是不是接反了。??
还有这句话,我没看懂,4148,是什么?
jackyard 发表于 2012-08-20 16:51 static/image/common/back.gif
你的这个不是共享中断吧,request_irq函数的每三个参数把IRQF_SHARED,先取掉。gpio_to_irq是获取对应书脚上 ...
页:
[1]