/*------------------------- *先申明下,本人是个菜鸟,刚开始接触驱动程序编写,交代下开发环境(主机系统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