主题 : 菜鸟请教下mini2440的问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 117775
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
综合积分: 4 分
注册时间: 2015-07-28
最后登录: 2015-08-05
楼主  发表于: 2015-07-30 09:01

 菜鸟请教下mini2440的问题

我按照韦东山老师的视频做实验,做到按键中断方式实验时,在read函数中加入了使进程进入等待状态的函数,以便降低CPU占有率。但是结果只进中断,却无法唤醒测试程序,大侠们帮我看看这是为啥啊,刚开始学linux不知道从哪里写手了,下面是测试代码和驱动程序。
注: printk("irq = %d\n",irq);       驱动中这个打印函数在6个按键按下时,可以正确打印对应的中断号,说明进中断了。
         但是测试程序中的printf函数一个都没打印,这个是我根据视频中查询式的方法修改的。
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;
}

级别: 新手上路
UID: 117775
精华: 0
发帖: 2
金钱: 10 两
威望: 2 点
综合积分: 4 分
注册时间: 2015-07-28
最后登录: 2015-08-05
1楼  发表于: 2015-08-03 10:53

 回 楼主(lele411) 的帖子

没有人指导下吗