文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>第一个驱动-按键点亮LED(基于linux-2.6.22)

第一个驱动-按键点亮LED(基于linux-2.6.22)

时间:2009-04-29  来源:gpephone

闲来无事,清明节的时候便想着自己动手做一个简单的驱动
做什么呢,LED最简单,就整这个了.可还要在用户空间测试,好麻烦,不如直接用按键来控制了
于是便参照着资料,开始coding...

//#include <linux/config.h>

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>

#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include <asm/hardware.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/irqs.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "button"
#define MAX_KEY_BUF 16
#define KEY_NUM 4

static int button_major = 232;
typedef struct
{
    unsigned int key_status[KEY_NUM];
    //unsigned char buf[MAX_KEY_BUF];
    //unsigned int head, tail;
    //wait_queue_head_t wq;
    struct cdev cdev;  
}button_dev;

static button_dev *button_p;

static struct led_info
{
    unsigned long gpio;
    unsigned long gpio_status;
}led_table[4] =
{
    {S3C2410_GPB7,S3C2410_GPB7_OUTP},
    {S3C2410_GPB8,S3C2410_GPB8_OUTP},
    {S3C2410_GPB9,S3C2410_GPB9_OUTP},
    {S3C2410_GPB10,S3C2410_GPB10_OUTP},
};

static struct key_info
{
    int irq_no;
    unsigned int gpio_port;
    int key_no;
}key_info_table[4] =
{
{    IRQ_EINT1, S3C2410_GPF1, 1},
{    IRQ_EINT2, S3C2410_GPF2, 2},
{    IRQ_EINT3, S3C2410_GPF3, 3},
{    IRQ_EINT7, S3C2410_GPF7, 4},   
};

static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)
{
    struct key_info *k;
    int i,j = (int)dev_id;
    printk("int %d received\n", j);
    unsigned int value;
    int found = 0;
    for (i = 0; i < sizeof key_info_table / sizeof key_info_table[1]; i++)
    {
       k = key_info_table + i;
       if (k->irq_no == irq)
        {
            found = 1;
            break;
        }
    }
    if (!found)
    {
       printk("bad irq %d in button\n", irq);
       return;
    }
printk("interrupt %d received!\n", i);
value = s3c2410_gpio_getpin(led_table[i].gpio);
    if(value)
        s3c2410_gpio_setpin(led_table[i].gpio,0);
    else
        s3c2410_gpio_setpin(led_table[i].gpio,1);
}

static int request_irqs(void)
{
struct key_info *k;
int i;
for (i = 0; i < sizeof key_info_table / sizeof key_info_table[1]; i++)
    {
     k = key_info_table + i;
     //set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
        set_irq_type(k->irq_no, IRQT_BOTHEDGE);
     if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME,
                i))
        {
        return -1;
     }
}
    printk("irq request successfully!\n");
return 0;
}

static void free_irqs(void)
{
    struct key_info *k;
    int i;
    for (i = 0; i < sizeof key_info_table / sizeof key_info_table[1]; i++)
    {
    k = key_info_table + i;
    free_irq(k->irq_no, buttons_irq);
    }
}

static void button_setup(button_dev *dev, int index)
{
    int err, devno = MKDEV(button_major, index);
    dev->cdev.owner = THIS_MODULE;
    err = cdev_add(&dev->cdev, devno, 1);
    if(err)
    {
        printk(KERN_NOTICE"Error %d adding button", err);
    }
}

static int button_init(void)
{
    int ret,i;
    dev_t devno = MKDEV(button_major,0);
    ret = register_chrdev_region(devno, 1, "button");
    if(ret)
        return ret;
    button_p = kmalloc(sizeof(button_dev), GFP_KERNEL);
    if(!button_p)
    {
        ret = -ENOMEM;
        goto fail;
    }
memset(button_p, 0, sizeof(button_dev));
button_setup(button_p, 0);
    for(i=0;i<4;i++)
    {
        s3c2410_gpio_cfgpin(led_table[i].gpio, led_table[i].gpio_status);
        s3c2410_gpio_setpin(led_table[i].gpio, 1);
        printk("led%d initialized!\n",i+1);
    }
ret = request_irqs();
    if(ret)
    {
        printk(DEVICE_NAME " can't request irqs\n");
        goto fail;
    }
    printk("int request ok!\n");
    return 0;
fail:
    unregister_chrdev_region(devno, 1);
    return ret;
}

static void button_exit(void)
{
    cdev_del(&button_p->cdev);
    kfree(button_p);
    unregister_chrdev_region(MKDEV(button_major,0), 1);   
    free_irqs();
}

MODULE_AUTHOR("jimmy");
MODULE_LICENSE("Daul BSD/GPL");

module_param(button_major, int, S_IRUGO);
module_init(button_init);
module_exit(button_exit);
呵呵,按一下就亮,松开就灭(双边触发)
相关阅读 更多 +
排行榜 更多 +
摧毁大厦游戏

摧毁大厦游戏

飞行射击 下载
合并动物城手游版

合并动物城手游版

休闲益智 下载
哈士奇大冒险

哈士奇大冒险

休闲益智 下载