我申请中断,打印的信息显示申请成功,也能看到DM644X_GPIO_BUTTON的变化
但是却在 cat /proc/interrupt中看不到响应的中断号
也无法进入中断例程;请各位指教下~~~
程序如下,打印信息如图所示。
/* drivers/char/davinci_dm644x_button.c*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <asm/arch/hardware.h>
#include <asm/arch/clock.h>
#include <asm/arch/clock.h>
#include <asm/arch/psc.h>
#include <linux/delay.h>
#include <asm/arch/gpio.h>
#include <asm/delay.h>
#include <linux/errno.h>
#include <asm/arch/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h> //define for irq number
#include <asm-arm/arch-davinci/irqs.h>
#include <asm-arm/arch-davinci/clock.h>
#include <asm/arch-davinci/gpio.h>
//#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define DM6446_GPIO_BASE 0x01C67000
//#define BINTEN (DM6446_GPIO_BASE + 0x8) //GPIO Interrupt Per Bank Enable
#define GPIO_REG(reg) (*(int *__iomem) IO_ADDRESS(reg))
#define IRQ1 0x01C4800C // Interrupt Request Status Register
#define EINT1 0x01C4801C // Interrupt Enable Register
#define INTPRI6 0x01C48048 // Interrupt Proirty
#define EABASE 0x01C48024 // Interrupt Entry Table Base Address
#define IRQENTRY 0x01C48047 // Entry Address for Valid IRQ
#define DEVICE_NAME "buttontest" /*定义设备驱动的名字,或设备节点名称*/
#define BUTTON_MAJOR 200 /*使用 cat /proc/devices查看不要和存在的char节点重复*/
/*my app gpio define*/
#define DM644X_GPIO_BUTTON 3 /*GPIO3*/
//#define DM644X_GPIO_INIT IRQ_GPIO3
#define DM644X_GPIO_INIT 51
/* 等待队列:
* 当没有按键被按下时,如果有进程调用buttons_read函数,
* 它将休眠
*/
//static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
/* 中断事件标志, 中断服务程序将它置1,buttons_read将它清0 */
//static int ev_press = 0;
static int value=1; //按键的电平值,按下为0
static irqreturn_t buttons_interrupt(int irq, void *dev_id,struct pt_regs *regs)
{
value = gpio_get_value(DM644X_GPIO_BUTTON);
printk(KERN_INFO "key is pressed!\n");
//ev_press = 1;
//wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */
printk("test, value = %d\n", value);
return IRQ_HANDLED;
}
static int buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
//unsigned long err;
//int value_test;
//wait: wait_event_interruptible(button_waitq, ev_press);
//value_test = value;
//mdelay(15);
value = gpio_get_value(DM644X_GPIO_BUTTON);
//if(value_test != value)
//{
// ev_press = 0;
// goto wait;
//}
printk("In kernel key_read()!\n"); //打印调试信息
/* 将按键状态复制给用户 */
//err = copy_to_user(buff, &ev_press, sizeof(ev_press));
copy_to_user(buff, (void *)&value, sizeof(value));
// ev_press = 0;
printk("this is at kernel, value = %d\n", value);
//wait_event_interruptible(button_waitq, ev_press);
//mdelay(15);
/* 将按键状态复制给用户 */
//err = copy_to_user(buff, (void *)&ev_press, sizeof(ev_press));
//err = copy_to_user(buff, &value, sizeof(value));
// printk(KERN_INFO "this is at kernel, ev_press = %d/n", ev_press);
//ev_press = 0;
return 0;
}
//static int buttons_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
//{
// int value = gpio_get_value(DM644X_GPIO_BUTTON);
// printk(KERN_INFO "this is kernel, value = %d\n", value);
//
// return value;
//}
static int buttons_open(struct inode *inode, struct file *file)
{
int result;
//int irq_number;
int value;
gpio_direction_input(DM644X_GPIO_BUTTON);
set_irq_type(DM644X_GPIO_INIT, IRQ_TYPE_EDGE_RISING); //RISING or Edge Falling type
disable_irq(DM644X_GPIO_INIT);
enable_irq(DM644X_GPIO_INIT);
//set_irq_type(irq_number, IRQ_TYPE_EDGE_FALLING);
//int test;
//printk("open gpio,here is driver\n");
//if(gpio_is_valid(DM644X_GPIO_BUTTON) < 0)
//{
// printk("gpio is invalid\n");
// return -EINVAL;
//}
//printk("gpio is valid\n");
// test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");
// if(test < 0 )
// {
// printk("failed to request gpio\n");
// return -EINVAL;
//}
// printk("request gpio ok!\n");
//irq_number = gpio_to_irq(DM644X_GPIO_BUTTON);
//printk(KERN_INFO "irq_number = %d\n", irq_number);
// gpio_direction_input(DM644X_GPIO_BUTTON);
// set_irq_type(IRQ_GPIO4, IRQF_TRIGGER_HIGH); //RISING or Edge Falling type
//set_irq_type(irq_number, IRQ_TYPE_EDGE_FALLING);
//disable_irq(IRQ_GPIO4);
//enable_irq(IRQ_GPIO4);
//gpio_direction_input(DM644X_GPIO_BUTTON);
//result = request_irq((gpio_to_irq(DM644X_GPIO_BUTTON)), buttons_interrupt, 0, "button", "key");
//result = request_irq((gpio_to_irq(DM644X_GPIO_BUTTON)), buttons_interrupt, SA_INTERRUPT, DEVICE_NAME, NULL);
//result = request_irq(DM644X_GPIO_INIT,buttons_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL);
result = request_irq(DM644X_GPIO_INIT,buttons_interrupt,SA_INTERRUPT,"buttontest","key");
if (result < 0)
{
printk(KERN_INFO "Cannot initialize IRQ \n");
return result;
}
printk(KERN_INFO "initialize IRQ successful, result = %d\n", result);
value = gpio_get_value(DM644X_GPIO_BUTTON);
disable_irq(DM644X_GPIO_INIT);
enable_irq(DM644X_GPIO_INIT);
printk(KERN_INFO "value = %d\n", value);
return 0;/*该函数可以什么都不做,也可以加入类似初始化的设置*/
}
static int buttons_close(struct inode *inode,struct file *filp)
{
//free_irq(DM644X_GPIO_INIT, NULL); //it will emit error if do not add "key"
free_irq(DM644X_GPIO_INIT, "key");
disable_irq(DM644X_GPIO_INIT);
gpio_free(DM644X_GPIO_BUTTON);
return 0;
}
/*定义驱动设备文件API,在linux系统当中,任何设备都可以当做文件的方式操作,这一点和单片机和MCU有很大差别*/
static const struct file_operations davinci_dm644x_gpio_fileops = {
.owner = THIS_MODULE,
.open = buttons_open,
.release = buttons_close,
.read = buttons_read,
//.ioctl = buttons_ioctl,
};
static int __init davinci_dm644x_button_open(void) /*内核初始化会调用该函数*/
{
int ret;
int test;
unsigned long pmux0;
unsigned long pmux1;
//board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO,1);
davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);
//davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN,DAVINCI_LPSC_GPIO,1);
pmux0 = davinci_readl(PINMUX0);
printk(KERN_INFO "test pmux0 = %lx\n",pmux0);
pmux1 = davinci_readl(PINMUX1);
printk(KERN_INFO "test pmux1 = %lx\n",pmux1);
pmux0 &= ~(0x00000001 << 25);
//pmux1 &= ~(0x00000007 << 4);
davinci_writel(pmux0, PINMUX0);
pmux0 = davinci_readl(PINMUX0);
printk(KERN_INFO "pmux0 = %ld;hex = %lx\n",pmux0,pmux0);
/*ARM INTERRUPT CONTROLLER REGISTER*/
int io_add = IO_ADDRESS(0x01c48000);
//GPIO_REG(IRQ1)=0x00800000; //GPIO3 INTERRUPT NUMBER = 51 BIT # 17
//GPIO_REG(IRQ1)=0x00800000; //GPIO0 INTERRUPT NUMBER = 48 BIT # 17
//GPIO_REG(EINT1)=0x00800000; //INTERRUPT ENABLE
//GPIO_REG(INTPRI6) = (GPIO_REG(INTPRI6) & 0xFFFFFFFF ) | ( 0x00000003 ); //INTERRUPT PIRIORITY
//ASP_REG(INTCTL);
/*set GPIO3 interrupt enable*/
//int binen = inl(io_addr + 0x08)|0x01;
//outl(binen,io_addr+0x08);
//printk("fiq value is %x\n",inl(io_add + 0x00));
int irq = inl(io_add + 0x0c)|0x00800000;
outl(irq,io_add + 0x0c);
printk("irq value is %x\n",inl(io_add + 0x0c));
int eint = inl(io_add + 0x1c)|0x00800000;
outl(eint,io_add + 0x1c);
printk("eint value is %x\n",inl(io_add + 0x1c));
int intpr6 = inl(io_add + 0x48)|0x00000003;
outl(intpr6,io_add + 0x48);
printk("intpr6 value is %x\n",inl(io_add + 0x48));
/**/
int io_addr = IO_ADDRESS(0x01c67000);
/*set GPIO3 interrupt enable*/
int binen = inl(io_addr + 0x08)|0x01;
outl(binen,io_addr+0x08);
printk("binen value is %x\n",inl(io_addr + 0x08));
/*set GPIO3 in*/
//int dir = inl(io_addr + 0x10)|0x08;
//outl(dir,io_addr+0x10);
//printk("dir value is %x\n",inl(io_addr + 0x10));
/*set GPIO3 rasing*/
int ris = inl(io_addr + 0x24)|0x08;
outl(ris,io_addr+0x24);
printk("ris value is %x\n",inl(io_addr + 0x24));
/*set GPIO3 status*/
//int insta = inl(io_addr + 0x34)|0x08;
//outl(insta,io_addr+0x34);
printk("insta value is %x\n",inl(io_addr + 0x34));
//
//printk("<1>GPIO_SET_INT: %x\n", GPIO_REG(BINTEN));
//
//davinci_writel(pmux1, PINMUX1)
gpio_direction_input(DM644X_GPIO_BUTTON);
//
if(gpio_is_valid(DM644X_GPIO_BUTTON) < 0)
{
printk("gpio is invalid\n");
return -EINVAL;
}
printk("gpio is valid\n");
test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");
if(test < 0 )
{
printk("failed to request gpio\n");
return -EINVAL;
}
printk("request gpio ok!\n");
//irq_number = gpio_to_irq(DM644X_GPIO_BUTTON);
//printk(KERN_INFO "irq_number = %d\n", irq_number);
//
ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &davinci_dm644x_gpio_fileops);
if(ret < 0)
{
printk(KERN_INFO "dm644x_button register falid!\n");
return ret;
}
printk (KERN_INFO "dm644x_button initialized\n");
return ret;
}
static void __exit davinci_dm644x_button_exit(void)
{
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(KERN_INFO "dm644x_button:exit\n");
}
module_init(davinci_dm644x_button_open);
module_exit(davinci_dm644x_button_exit);
MODULE_AUTHOR("azhgul");
MODULE_LICENSE("Dual BSD/GPL");
Feng Dong:
request中断号不对吧,另外保证gpio module的状态是对的
Feng Dong:
另外通常的逻辑应该是request_gpio,并且设置为input,然后才requet irq
fei wang:
回复 Feng Dong:
你好,谢谢你的回复。我已经申请GPIO资源了,代码已经标注,并且设置input,打印信息显示都可以,而且可以读取相应的GPIO管脚的输入状态,比如,按下按键,可以读取状态值为1等,中断号是查相应技术手册,应该也没有问题的。能不能加你联系方式,向您请教,谢谢,我QQ:364620379,
test = gpio_request(DM644X_GPIO_BUTTON, "buttons_interrupt");
if(test < 0 )
{
printk("failed to request gpio\n");
return -EINVAL;
}
printk("request gpio ok!\n");