搜索
bottom↓
回复: 2

求助mini2440的问题,这个按键驱动不能唤醒测试程序

[复制链接]

出0入0汤圆

发表于 2015-7-28 14:56:05 | 显示全部楼层 |阅读模式
我是刚刚学习linux驱动开发,写了这个按键中断方式的驱动,在按下按键时,唤醒测试程序。这个例子是根据韦东山老师的按键驱动写的,我在中断函数中加入了打印,6个按键都可以正确触发,并打印中断号。但是就是测试程序没反应,啥都没见打印,我查看了进程显示一直在休眠!下面是驱动和测试程序,大侠们帮我这个菜鸟看看!
1:驱动
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/poll.h>
//#include <linux/irqreturn.h>
#include <linux/wait.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
/*定义一个等待队列头*/
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/*中断事件标志,中断服务程序将其置1,read函数将其置0*/
static volatile ev_press = 0;
/*设备号*/
int major;
/*保存按键值*/
static unsigned char key_value;
/*GPG配置寄存器和数值寄存器*/
#define GPGCONADDR 0x56000060  //GPBCON物理地址  
#define GPGDATADDR 0x56000064  
volatile unsigned long *gpgcon;  
volatile unsigned long *gpgdat;

static struct class *thirddrv_class;
static struct device  *thirddrv_class_dev;

static struct pin_desc{
        int pin;
        int key_value;
};
/*
*按键按下时值:0x01,0x02,0x03,....0x06
*按键松开时值:0x81,0x82,0x83,....0x86
*/
struct pin_desc pins_desc[6] = {
        {S3C2410_GPG(0),   1 },       
        {S3C2410_GPG(3),   2 },       
        {S3C2410_GPG(5),   3 },       
        {S3C2410_GPG(6),   4 },
        {S3C2410_GPG(7),   5 },
        {S3C2410_GPG(11), 6 },

};
static irqreturn_t buttons_irq (int irq, void *dev_id)
{
        struct pin_desc *pin_descs= (struct pin_desc *)dev_id;
        unsigned char value;
        value = s3c2410_gpio_getpin(pin_descs->pin);
        if(value == 1)
        {
                key_value = pin_descs->key_value |0x80;               
        }
        else
        {
                key_value = pin_descs->key_value;
        }
        ev_press = 1;

        wake_up_interruptible(&button_waitq);
        printk("irq = %d\n",irq);                                //这个可以打印出中断号,测试正确,说明进中断了
       
        return IRQ_RETVAL(IRQ_HANDLED);
}

static int third_driver_open(struct inode *inode, struct file *file)
{   
        printk("third_driver_open\r\n");
        /*读取键值key1=GPG0,key2=GPG3,key3=GPG5,KEY4=GPG6,KEY5=GPG7,KEY6=GPG11*/
        request_irq(IRQ_EINT8,  buttons_irq,  IRQ_TYPE_EDGE_BOTH, "key1",&pins_desc[0]);
        request_irq(IRQ_EINT11, buttons_irq, IRQ_TYPE_EDGE_BOTH, "key2",&pins_desc[1]);
        request_irq(IRQ_EINT13, buttons_irq, IRQ_TYPE_EDGE_BOTH, "key3",&pins_desc[2]);
        request_irq(IRQ_EINT14, buttons_irq, IRQ_TYPE_EDGE_BOTH, "key4",&pins_desc[3]);
        request_irq(IRQ_EINT15, buttons_irq, IRQ_TYPE_EDGE_BOTH, "key5",&pins_desc[4]);
        request_irq(IRQ_EINT19, buttons_irq, IRQ_TYPE_EDGE_BOTH, "key6",&pins_desc[5]);
        return 0;
}

static int  third_driver_read(struct file *flie, const char __user *buf, size_t count, loff_t *ppos)
{
        if(count != 1)
        {
                printk("length err!");
                return -EINVAL;               
        }
        /*如果没有中断就进入休眠*/
        wait_event_interruptible(button_waitq, ev_press);
        ev_press = 0;
        /*如果有中断就直接返回键值*/
        copy_to_user(buf, &key_value, 1);//copy_to_user实现从用户空间读取参数到内核空间
        return 1;       
}

static int third_driver_close(struct inode *inode, struct file *file)
{
        printk("third_driver_close\r\n");
        free_irq(IRQ_EINT8,   &pins_desc[0]);
        free_irq(IRQ_EINT11, &pins_desc[1]);
        free_irq(IRQ_EINT13, &pins_desc[2]);
        free_irq(IRQ_EINT14, &pins_desc[3]);
        free_irq(IRQ_EINT15, &pins_desc[4]);
        free_irq(IRQ_EINT19, &pins_desc[5]);
        return 0;       
}

static struct file_operations third_driver_fops =
{   
        .owner          =   THIS_MODULE,
        .open           =   third_driver_open,         
        .read           =   third_driver_read,
        .release         =   third_driver_close,
};

int third_driver_init(void)
{

        major = register_chrdev(0, "third_drv", &third_driver_fops);
        thirddrv_class = class_create(THIS_MODULE, "thirddrv");
        if (IS_ERR(thirddrv_class))
                return PTR_ERR(thirddrv_class);
        thirddrv_class_dev = device_create(thirddrv_class, NULL, MKDEV(major, 0),NULL, "buttons");
        if(unlikely(IS_ERR(thirddrv_class_dev)))
                return PTR_ERR(thirddrv_class_dev);       
        gpgcon = (volatile unsigned long *)ioremap(GPGCONADDR,16); //ioremap实现物理地址到虚拟地址的转换  
        gpgdat = gpgcon+1;  
        return 0;
}
static void third_driver_exist(void)
{
        unregister_chrdev(major, "third_drv");
        device_destroy(thirddrv_class,  MKDEV(major, 0));
        class_destroy(thirddrv_class);
        iounmap(gpgcon);
        return;
}
module_init(third_driver_init);
module_exit(third_driver_exist);
MODULE_LICENSE("GPL");      

2:测试程序
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, const char * argv [ ])
{
        int fd;  
        int key_value;
        int resualt;
        unsigned int cnt;
        fd = open("/dev/buttons",O_RDWR);  
        if(fd<0)  
        {  
                printf("can't open file!\n");  
                return 0;  
        }
        while(1)
        {
                resualt = read(fd,&key_value,1,NULL);
                if(resualt==1)
                {
                        printf("%d:key_value = 0x%x",cnt++,key_value);
                }
                else
                {
                        printf("data length error!\n");  
                }
        }
        return 0;
}



阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2015-7-28 17:34:29 | 显示全部楼层
帮顶,不知道LZ解决没有?

出0入0汤圆

 楼主| 发表于 2015-7-29 09:21:28 | 显示全部楼层
licheng0620 发表于 2015-7-28 17:34
帮顶,不知道LZ解决没有?

没有啊,还是不行啊,菜鸟一个,真不知道该从哪里找问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-28 07:34

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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