面向对象之编写驱动程序--中断(linux系统、s3c6410开发板)

/*-------------------------
*先申明下,本人是个菜鸟,刚开始接触驱动程序编写,交代下开发环境(主机系统redhat6.3,开发板ARM-s3c6410)
以watchdog (看门狗,俗称狗中断)为例,编写简单的中断(驱动)
-------------------------*/
#include <linux/init.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/irq.h>
#include <linux/interrupt.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("cheng");

typedef struct mydev{
        unsigned long gpio_virt;
        unsigned long wdt_virt;
        unsigned long *gpmcon, *gpmdat;
        unsigned long *wtcon, *wtdat, *wtcnt, *wtclrint;
        void (*init_nydev)(struct mydev *this);
        void (*exit_mydev)(struct mydev *this);
        irqreturn_t (*do_irq)(int irq, struct mydev *this);
        void (*led_on)(struct mydev *this);
        void (*led_off)(struct mydev *this);
        void (*wdt_on)(struct mydev *this);
        void (*wdt_off)(struct mydev *this);
}MYDEV;

void my_init_mydev(struct mydev *this);
void my_exit_mydev(struct mydev *this);
irqreturn_t my_do_irq(int irq, struct mydev *this);
void my_led_on(struct mydev *this);
void my_led_off(struct mydev *this);
void my_wdt_on(struct mydev *this);
void my_wdt_off(struct mydev *this);

MYDEV my ;
static int test_init(void)
{
    printk("hello,in my test_init\n");
    my.init_mydev = my_init_mydev;
    my.exit_mydev = my_exit_mydev;
    my.init_mydev(&my);

    return 0;
}

void test_exit()
{
    my.exit_mydev(&my);
    printk("this is test exit\n");
}

module_init(test_init);
module_exit(test_exit);

void my_init_mydev(struct mydev *this)
{
        this->do_irq   = my_do_irq;
        this->led_on   = my_led_on;
        this->led_off   = my_led_off;
        this->wdt_on  = my_wdt_on;
        this->wdt_off  = my_wdt_off;
        int ret = request_irq(IRQ_WDT, this->do_irq, IRQF_SHARED,"hello", this);
        if(ret < 0){
                printk("request_irq error\n");
                return ;
        }
        this->gpio_virt   =    ioremap(0x7f008000, SZ_4K);
        this->wdt_virt     =    ioremap(0x7e004000, SZ_4K);
        this->gpmcon    =    this->gpio_virt + 0x820;
        this->gpmdat     =    this->gpio_virt + 0x824;
        this->wtcon        =    this->wdt_virt + 0x00;
        this->wtdat         =    this->wdt_virt + 0x04;
        this->wtcnt         =    this->wdt_virt + 0x08;
        this->wtclrint      =    this->wdt_virt + 0x0c;
        this->wdt_on(this);
}

void my_exit_mydev(struct mydev *this)
{
    this->my_wtd_off(this);
    iounmap(this->wdt_virt);
    iounmap(this->gpio_virt);
    free_irq(IRQ_WDT,this);
}

irqreturn_t my_do_irq(int irq, struct mydev *this)
{
    if(irq == IRQ_WDT){
        *this->wtclrint = 0;
        printk("wang wang wang\n");
        static int flag = 1;
        if(flag)
            this->led_on(this);
        else
            this->led_off(this);
       flag ^= 1;
    }
    return IRQ_HANDLED;
}

void my_led_on(struct mydev *this)
{
    *this->gpmcon = 1;
    *this->gpmdat = 0;
}

void my_led_off(struct mydev *this)
{
    *this->gpmcon = 1;
    *this->gpmdat = 1;
}

void my_wdt_on(struct mydev *this)
{
    *this->wtcon = (1 << 2) | (1 << 3) | (1 << 5) | (31 << 8);
    *this->wtdat = 0x4000;
    *this->wtcnt = 0x8000;
}

void my_wdt_off(struct mydev *this)
{
    *this->wtcon = 0;
}

/*
    下面是makefile内容:
*/

all:
        make -C linux-2.6.28_smdk6410 M=`pwd` modules
clean:
        make -C /linux-2.6.28_smdk6410 M=`pwd` clean
        rm -rf modules.order
obj-m += test.o 

 

posted on 2014-03-12 20:34  程良  阅读(375)  评论(0编辑  收藏  举报

导航