3120|3

82

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢 [复制链接]

实在没辙了,按键驱动,麻烦大家,请指点一下,附代码~~ 谢谢
一个很简单的 按键驱动, 搞了三天也insmod不上去....    电脑上输入insmod **.ko 后,  直接就死机了......  
系统:Redhat 2.6.18
代码如下:
没分了,见谅~~~~~~

最新回复

你好啊,我刚开始看驱动,也看到这里了,但是连这个最简单的按键驱动我也还没写过,呵呵,看书当中,看书也只能看懂个大概,呵呵呵,想在接下去的几天当中把按键驱动写出来,希望你早日解决你的问题,到时候教我哦,呵呵呵,能交个朋友吗?我QQ546303302  详情 回复 发表于 2009-4-11 16:21
点赞 关注

回复
举报

78

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
#define DEVICE_NAME        "mini_buttons"
#define BUTTONS_NUM        6
#define MAX_BUTTONS_BUF        16
#define BUTTONS_MAJOR        252

#define BUTTONSTATUS_DOWNX        0
#define BUTTONSTATUS_DOWN        1
#define BUTTONSTATUS_UP                2

#define BUTTONS_TIMER_DELAY        (HZ/50)
#define BUTTONS_TIMER_DELAY1        (HZ/10)

static int buttons_major = BUTTONS_MAJOR;


struct buttons_dev
{
        struct cdev cdev;
        unsigned int buttonStatus[BUTTONS_NUM];
        unsigned char buf[MAX_BUTTONS_BUF];
        unsigned int head,tail;
        wait_queue_head_t wq;
};

static struct buttons_dev *buttons_devp;

static struct buttons_info
{
        unsigned int irq_no;
        unsigned int gpio_port;
        unsigned int buttons_no;
}buttons_info_tab[BUTTONS_NUM] =
{
        {IRQ_EINT8,S3C2410_GPG0,1},
        {IRQ_EINT11,S3C2410_GPG3,2},
        {IRQ_EINT13,S3C2410_GPG5,3},
        {IRQ_EINT14,S3C2410_GPG6,4},
        {IRQ_EINT15,S3C2410_GPG7,5},
        {IRQ_EINT19,S3C2410_GPG11,6},
};

static struct timer_list buttons_timer[BUTTONS_NUM];


void __iomem * virt_GPGCON;
void __iomem * virt_GPGDAT;
void __iomem * virt_SRCPND;
void __iomem * virt_INTMSK;
void __iomem * virt_INTPND;
void __iomem * virt_EINTPEND;
void __iomem * virt_EINTMASK;
void __iomem * virt_EXTINT1;
void __iomem * virt_EXTINT2;

static int buttons_open(struct inode *inode,struct file *filp);
static int buttons_release(struct inode *inode,struct file *filp);
static ssize_t buttons_read(struct file *filp,char __user *buf,
                                size_t size,loff_t *ppos);

static struct file_operations buttons_fops =
{
        .owner = THIS_MODULE,
        .open = buttons_open,
        .release = buttons_release,
        .read = buttons_read,
//        .write = buttons_write,
};

static void buttons_ioremap(void)
{
   virt_INTPND=ioremap(0x4a000010,4);
   virt_EINTPEND=ioremap(0x560000a8,4);
   virt_SRCPND=ioremap(0x4a000000,4);
//   virt_EXTINT0=ioremap(0x56000088,4);
   virt_EXTINT1=ioremap(0x5600008c,4);
   virt_EXTINT2=ioremap(0x56000090,4);
   virt_GPGDAT=ioremap(0x56000064,4);
   virt_EINTMASK=ioremap(0x560000a4,4);
   virt_INTMSK=ioremap(0x4a000008,4);
   virt_GPGCON=ioremap(0x56000060,4);
}

static void buttons_iounmap(void)
{
        iounmap(&virt_INTPND);
        iounmap(&virt_EINTPEND);
        iounmap(&virt_SRCPND);
//        iounmap(&virt_EXTINT0);
        iounmap(&virt_EXTINT1);
        iounmap(&virt_EXTINT2);
        iounmap(&virt_GPGDAT);
        iounmap(&virt_EINTMASK);
        iounmap(&virt_INTMSK);
        iounmap(&virt_GPGCON);
}

static void buttons_enable_irq(void)
{
        unsigned int value;
        iowrite32((1<<5),virt_SRCPND);
        iowrite32((1<<5),virt_INTPND);
        value = ioread32(virt_INTMSK);
        value &= ~(1<<5);
        iowrite32(value,virt_INTMSK);       

        value = 0;
        value |= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);
        iowrite32(value,virt_EINTPEND);

        value = ioread32(virt_EINTMASK);
        value &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));
        iowrite32(value,virt_EINTMASK);

}

static void buttons_enable_irq_again(void)
{
        unsigned int value;
        value = 0;
        value = ioread32(virt_INTPND);
        if(value = (1<<5))
        {
                iowrite32((1<<5),virt_SRCPND);
                iowrite32((1<<5),virt_INTPND);
                value = ioread32(virt_EINTPEND);
                if(value = (1<<8))
                {
                        iowrite32(value,virt_EINTPEND);
                }else if(value = (1<<11))
                {
                        iowrite32(value,virt_EINTPEND);
                }else if(value = (1<<13))
                {
                        iowrite32(value,virt_EINTPEND);
                }else if(value = (1<<14))
                {
                        iowrite32(value,virt_EINTPEND);
                }else if(value = (1<<15))
                {
                        iowrite32(value,virt_EINTPEND);
                }else if(value = (1<<19))
                {
                        iowrite32(value,virt_EINTPEND);
                }
        }
}

static void buttons_lowlevel(void)
{
        unsigned int value;
        value = 0;

        value &= ~((7<<0)|(7<<12)|(7<<20)|(7<<24)|(7<<28));
        iowrite32(value,virt_EXTINT1);

        value &= ~(7<<12);
        iowrite32(value,virt_EXTINT2);
}
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
static int buttons_open(struct inode *inode,struct file *filp)
{
        filp->private_data = buttons_devp;
        buttons_devp->head = buttons_devp->tail =0;
        return 0;
}

static int buttons_release(struct inode *inode,struct file *filp)
{
        return 0;
}

static ssize_t buttons_read(struct file *filp,char __user *buf,
                                size_t size,loff_t *ppos)
{
        int ret;
        retry:if(buttons_devp->head != buttons_devp->tail)
        {
//                buf = buttons_devp->buf[buttons_devp->tail];
                ret = copy_to_user(buf,(void *)buttons_devp->buf[buttons_devp->tail],sizeof(unsigned char));
                (buttons_devp->tail)++;
                if(buttons_devp->tail == MAX_BUTTONS_BUF)
                {
                        buttons_devp->tail = 0;
                }
        }else{
                __set_current_state(TASK_INTERRUPTIBLE);
                if(filp->f_flags & O_NONBLOCK)
                {
                        return -EAGAIN;
                }
                schedule();
                if(signal_pending(current))
                {
                        return -ERESTARTSYS;
                }
                goto retry;
        }
        return ret;
}
               
static int is_buttons_down(unsigned long data)
{
        int key = data;
        unsigned long ret;
        void __iomem * base = S3C24XX_GPIO_BASE(buttons_info_tab[key].gpio_port);
        unsigned long offs = S3C2410_GPIO_OFFSET(buttons_info_tab[key].gpio_port);
        ret = __raw_readl(base + 0x04) & (1 << offs);
        if(ret == 0)
                return 1;
        else
                return 0;
}

static void buttons_event(int data)
{
        int key = data;
        buttons_devp->buf[buttons_devp->head] = buttons_info_tab[key].buttons_no;
        (buttons_devp->head)++;
        if(buttons_devp->head == MAX_BUTTONS_BUF)
                buttons_devp->head = 0;
        wake_up_interruptible(&buttons_devp->wq);
}

static void buttons_timer_func(unsigned long data)
{
        int key = data;
        if(is_buttons_down(key))
        {
                if(buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWNX)
                {
                        buttons_devp->buttonStatus[key] == BUTTONSTATUS_DOWN;
                        buttons_event(key);
                        buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
                        add_timer(&buttons_timer[key]);
                }else{
                        buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY1;
                        add_timer(&buttons_timer[key]);
                }
        }else{
                buttons_devp->buttonStatus[key] == BUTTONSTATUS_UP;
                enable_irq(buttons_info_tab[key].irq_no);
        }
}

static irqreturn_t buttons_eint_func(int irq,void *dev_id,struct pt_regs *regs)
{
        int key = dev_id;
        disable_irq(buttons_info_tab[key].irq_no);
        buttons_enable_irq_again();
        buttons_devp->buttonStatus[key] = BUTTONSTATUS_DOWNX;
        buttons_timer[key].expires = jiffies + BUTTONS_TIMER_DELAY;
        add_timer(&buttons_timer[key]);
}

static int request_irqs(void)
{
        int i,ret;
        buttons_lowlevel();
        for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab[1]);i++)
        {
                set_irq_type(buttons_info_tab.irq_no,IRQT_LOW);
                ret = request_irq(buttons_info_tab.irq_no,buttons_eint_func,        SA_INTERRUPT,DEVICE_NAME,i);
                if(ret)
                        return - EINVAL;
        }
        return 0;
}

static int buttons_setup_cdev(struct buttons_dev *dev,int index)
{
        int err,devno = MKDEV(buttons_major,index);
        cdev_init(&dev->cdev,&buttons_fops);
        dev->cdev.owner = THIS_MODULE;
        dev->cdev.ops = &buttons_fops;
        err = cdev_add(&dev->cdev,devno,1);
        if(err)
                printk(KERN_NOTICE "Error %d adding",err);
        buttons_enable_irq();
        request_irqs();
        /*****  IOREMAP  *****/
        buttons_ioremap();
        return 0;
}

static int __init buttons_init(void)
{
        int i,result;
        dev_t devno = MKDEV(buttons_major,0);
        if(buttons_major)
                result = register_chrdev_region(devno,1,DEVICE_NAME);
        else{
                result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME);
                buttons_major = MAJOR(devno);
        }
        if(result)
                return result;
        buttons_devp->head = buttons_devp->tail = 0;
        for(i = 0;i < BUTTONS_NUM;i++)
                buttons_devp->buttonStatus = BUTTONSTATUS_UP;
        for(i = 0;i < BUTTONS_NUM;i++)
                setup_timer(&buttons_timer,buttons_timer_func,i);
        init_waitqueue_head(&(buttons_devp->wq));
        buttons_setup_cdev(buttons_devp,0);
        return 0;
}
module_init(buttons_init);

static void __exit buttons_exit(void)
{
        int i;
//        for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab);i++)
                buttons_iounmap();
        for(i = 0;i < sizeof(buttons_info_tab)/sizeof(buttons_info_tab);i++)
                free_irq(buttons_info_tab.irq_no,i);
        cdev_del(&buttons_devp->cdev);
        for(i = 0;i < BUTTONS_NUM;i++)
                del_timer(&buttons_timer);
        unregister_chrdev_region(MKDEV(buttons_major,0),1);
}
module_exit(buttons_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("bejoey_pro");
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

4
 
你好啊,我刚开始看驱动,也看到这里了,但是连这个最简单的按键驱动我也还没写过,呵呵,看书当中,看书也只能看懂个大概,呵呵呵,想在接下去的几天当中把按键驱动写出来,希望你早日解决你的问题,到时候教我哦,呵呵呵,能交个朋友吗?我QQ546303302
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表