嵌入式爱好者

查看: 6306|回复: 2

[Linux] OK6410A中6个userkey按键驱动问题

[复制链接]

1

主题

4

帖子

6

积分

扫一扫,手机访问本帖
发表于 2015-9-14 17:45:10 | 显示全部楼层 |阅读模式
请问,驱动文件夹中是没有没有单独的6个userkey的测试程序,我从网上找了一个中断的方式,但是不起作用,请大神帮忙看一下,谢谢。

驱动程序:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/device.h>//新版内核

#include <linux/gpio.h>
#include <plat/gpio-cfg.h>


static struct class *key_irq_class;
static struct class_device        *key_class_irq;
volatile unsigned long  *gpncon=NULL;
volatile unsigned long  *gpndat=NULL;

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */
static volatile int ev_press = 0;
struct key_desc{
        unsigned int pin;
        unsigned int key_val;
        };
/*键值:按下时,0x01,0x02,0x03,0x04,0x05,0x06*/
/*键值:松开时,0x81,0x82,0x83,0x84,0x85,0x86*/
static unsigned char key_num;
struct key_desc keys_desc[6]={
        {1,0x01},
        {2,0x02},
        {3,0x03},
        {4,0x04},
        {5,0x05},
        {6,0x06},
};

static irqreturn_t key_irq(int irq, void *dev_id)
{
        struct key_desc *pin=(struct key_desc*)dev_id;
        unsigned int pinval;
        pinval=gpio_get_value(S3C64XX_GPN(pin->pin));
        if(pinval)
                {
                        key_num=0x80|pin->key_val;
                }
        else
                {
                        key_num=pin->key_val;
                }
        //printk("*********************");
        //printk("key_num= %x\n",key_num);
        //printk("*********************");
        ev_press=1;/*表示中断发生了*/
        wake_up_interruptible(&button_waitq);/*唤醒休眠的进程*/
        return IRQ_HANDLED;
}

static int key_drv_open(struct inode  * inode, struct file * file)
{
        request_irq(IRQ_EINT(1),key_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"S1",&keys_desc[0]);
        request_irq(IRQ_EINT(2),key_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"S2",&keys_desc[1]);
        request_irq(IRQ_EINT(3),key_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"S3",&keys_desc[2]);
        request_irq(IRQ_EINT(4),key_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"S4",&keys_desc[3]);
        request_irq(IRQ_EINT(5),key_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"S5",&keys_desc[4]);
        request_irq(IRQ_EINT(6),key_irq,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,"S6",&keys_desc[5]);
        return 0;
}
static ssize_t key_drv_write(struct inode * file, const char __user *buf, size_t count, loff_t *ppos)
{

        return 0;
}
ssize_t key_drv_read (struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
        //返回四个引脚的电平
        if(size != 1)
                return -EINVAL;
        /*如果没有按键动作发生就休眠*/
        wait_event_interruptible(button_waitq, ev_press);
        /*如果有按键动作,返回键值*/
        copy_to_user(buf,&key_num,1);
        ev_press=0;
        return 1;
}
int key_drv_release(struct inode * inode, struct file * file)
{
        free_irq(IRQ_EINT(1),&keys_desc[0]);
        free_irq(IRQ_EINT(2),&keys_desc[1]);
        free_irq(IRQ_EINT(3),&keys_desc[2]);
        free_irq(IRQ_EINT(4),&keys_desc[3]);
        free_irq(IRQ_EINT(5),&keys_desc[4]);
        free_irq(IRQ_EINT(6),&keys_desc[5]);
       
        return 0;
}
static struct file_operations key_drv_openration ={
        .owner = THIS_MODULE,
        .open = key_drv_open,
        .write =key_drv_write,
        .read=key_drv_read,
        .release=key_drv_release,
};
int major;
static int key_drv_init(void)
{
        major=register_chrdev(0,"key_irq",&key_drv_openration);
       
        key_irq_class = class_create(THIS_MODULE, "key_irq");
                //自动创建设备节点
        /* 新版的内核不能用class_device_create 要用device_create*/
        key_class_irq = device_create(key_irq_class, NULL, MKDEV(major, 0), NULL, "key"); /* /dev/xyz */
               
        gpncon = (volatile unsigned long*)ioremap(0x7F008830,16);
        gpndat=gpncon+1;//指针的操作是按照指针指向的长度为单位?
                                                /*本例中使用的是unsigned long类型刚好是4个字节*/

        return 0;
}
static void key_drv_exit(void)
{
        unregister_chrdev(major,"key_irq");
        device_unregister(key_class_irq);
        class_destroy(key_irq_class);

        iounmap(gpncon);
        return 0;
}

module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");
这个程序编译成.ko模块,在开发板中用insmod加载模块,测试程序如下
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>

int main(int argc,char **argv)
{
        int fd;
        unsigned char key_val;
        int cnt;
        fd=open("/dev/key",O_RDWR);
        if(fd < 0)
                {
                        printf("can not open!!!\n");
                        return 0;
                }
        while(1)
                {
                        read(fd,&key_val,1);
                        printf("key_val = 0x%x\n", key_val);
                }
        return 0;
}
用arm—linux-gcc编译后与ko文件一起发到开发板中,挂载模块后运行测试程序,没有反应,我在中断函数中加的log没有打印,好像没有触发中断,请帮忙看看这是什么原因,谢谢。




回复

使用道具 举报

1

主题

4

帖子

6

积分

 楼主| 发表于 2015-9-14 17:50:38 | 显示全部楼层
自己顶,坐等大神回复。:lol
点评回复 支持 反对

使用道具 举报

1

主题

4

帖子

6

积分

 楼主| 发表于 2015-9-15 18:46:13 | 显示全部楼层
大神不出现呢???
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-6-2 22:36

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

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