在linux中学看门狗驱动,说实话就是坑爹的,因为一般上看门狗只有一个,只能留给最需要的哪一个,很少有设备用到,不过既然提到了,那就刚好看看,在操作系统中时怎么用写看门狗的,有点坑爹的。就注册一个中断,不想写了,坑爹.......
想了想还是写一点,可以复习一下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
MODULE_LICENSE("GPL");
struct up_wtd{
unsigned long virt_wtd,virt_led;
unsigned long *gpmcon,*gpmdat,*wtcon,*wtcnt,*wtdat,*wtclrint;
char *name;
unsigned int flag;
void (*wtd_init)(struct up_wtd *this);
void (*wtd_exit)(struct up_wtd *this);
void (*wtd_on)(struct up_wtd *this);
void (*wtd_off)(struct up_wtd *this);
void (*wtd_clr)(struct up_wtd *this);
void (*led_on)(struct up_wtd *this);
void (*led_off)(struct up_wtd *this);
irqreturn_t (*do_irq)(int irq,struct up_wtd *this);
};
unsigned long virt_wtd,virt_led;
unsigned long *gpmcon,*gpmdat,*wtcon,*wtcnt,*wtdat,*wtclrint;
char *name;
unsigned int flag;
void (*wtd_init)(struct up_wtd *this);
void (*wtd_exit)(struct up_wtd *this);
void (*wtd_on)(struct up_wtd *this);
void (*wtd_off)(struct up_wtd *this);
void (*wtd_clr)(struct up_wtd *this);
void (*led_on)(struct up_wtd *this);
void (*led_off)(struct up_wtd *this);
irqreturn_t (*do_irq)(int irq,struct up_wtd *this);
};
void my_wtd_init(struct up_wtd *this);
void my_wtd_exit(struct up_wtd *this);
void my_wtd_on(struct up_wtd *this);
void my_wtd_off(struct up_wtd *this);
void my_wtd_clr(struct up_wtd *this);
void my_led_on(struct up_wtd *this);
void my_led_off(struct up_wtd *this);
irqreturn_t my_do_irq(int irq,struct up_wtd *this);
void my_wtd_exit(struct up_wtd *this);
void my_wtd_on(struct up_wtd *this);
void my_wtd_off(struct up_wtd *this);
void my_wtd_clr(struct up_wtd *this);
void my_led_on(struct up_wtd *this);
void my_led_off(struct up_wtd *this);
irqreturn_t my_do_irq(int irq,struct up_wtd *this);
struct up_wtd wtd;
int up_init(void)
{
wtd.wtd_init = my_wtd_init;
wtd.wtd_exit = my_wtd_exit;
wtd.wtd_init(&wtd);
return 0;
}
{
wtd.wtd_init = my_wtd_init;
wtd.wtd_exit = my_wtd_exit;
wtd.wtd_init(&wtd);
return 0;
}
void up_exit(void)
{
wtd.wtd_exit(&wtd);
}
{
wtd.wtd_exit(&wtd);
}
module_init(up_init);
module_exit(up_exit);
module_exit(up_exit);
void my_wtd_init(struct up_wtd *this)
{
this->virt_wtd = ioremap(0x7e004000,SZ_4K);
this->virt_led = ioremap(0x7f008000,SZ_4K);
this->gpmcon = this->virt_led + 0x820;
this->gpmdat = this->virt_led + 0x824;
this->wtcon = this->virt_wtd + 0x00;
this->wtdat = this->virt_wtd + 0x04;
this->wtcnt = this->virt_wtd + 0x08;
this->wtclrint = this->virt_wtd + 0x0c;
this->name = "s3c6410-wdt";
this->flag = 1;
this->wtd_on = my_wtd_on;
this->wtd_off = my_wtd_off;
this->wtd_clr = my_wtd_clr;
this->led_on = my_led_on;
this->led_off = my_led_off;
this->do_irq = my_do_irq;
{
this->virt_wtd = ioremap(0x7e004000,SZ_4K);
this->virt_led = ioremap(0x7f008000,SZ_4K);
this->gpmcon = this->virt_led + 0x820;
this->gpmdat = this->virt_led + 0x824;
this->wtcon = this->virt_wtd + 0x00;
this->wtdat = this->virt_wtd + 0x04;
this->wtcnt = this->virt_wtd + 0x08;
this->wtclrint = this->virt_wtd + 0x0c;
this->name = "s3c6410-wdt";
this->flag = 1;
this->wtd_on = my_wtd_on;
this->wtd_off = my_wtd_off;
this->wtd_clr = my_wtd_clr;
this->led_on = my_led_on;
this->led_off = my_led_off;
this->do_irq = my_do_irq;
int ret = request_irq(IRQ_WDT,this->do_irq,IRQF_SHARED,this->name,this);
if(ret < 0){
printk("wdt request error\n");
return 1;
}
if(ret < 0){
printk("wdt request error\n");
return 1;
}
this->wtd_on(this);
}
}
void my_wtd_exit(struct up_wtd *this)
{
free_irq(IRQ_WDT,this);
this->led_off(this);
this->wtd_off(this);
iounmap(this->virt_wtd);
iounmap(this->virt_led);
}
{
free_irq(IRQ_WDT,this);
this->led_off(this);
this->wtd_off(this);
iounmap(this->virt_wtd);
iounmap(this->virt_led);
}
void my_wtd_on(struct up_wtd *this)
{
*this->wtcon = (1 << 2) | (3 << 3) | (1 << 5) | (15 << 8);
*this->wtdat = 0x8000;
*this->wtcnt = 0x8000;
}
{
*this->wtcon = (1 << 2) | (3 << 3) | (1 << 5) | (15 << 8);
*this->wtdat = 0x8000;
*this->wtcnt = 0x8000;
}
void my_wtd_off(struct up_wtd *this)
{
*this->wtcon = 0;
}
{
*this->wtcon = 0;
}
void my_wtd_clr(struct up_wtd *this)
{
*this->wtclrint = 0;
}
{
*this->wtclrint = 0;
}
void my_led_on(struct up_wtd *this)
{
*this->gpmcon &= ~0xf;
*this->gpmcon |= 1;
*this->gpmdat &= ~1;
}
{
*this->gpmcon &= ~0xf;
*this->gpmcon |= 1;
*this->gpmdat &= ~1;
}
void my_led_off(struct up_wtd *this)
{
*this->gpmcon &= ~0xf;
*this->gpmcon |= 1;
*this->gpmdat |= 1;
}
{
*this->gpmcon &= ~0xf;
*this->gpmcon |= 1;
*this->gpmdat |= 1;
}
irqreturn_t my_do_irq(int irq,struct up_wtd *this)
{
if(irq == IRQ_WDT){
this->wtd_clr(this);
if(this->flag)
{
printk("led_on\n");
this->led_on(this);
}
else
{
printk("led_off\n");
this->led_off(this);
}
this->flag ^= 1;
}
return IRQ_HANDLED;
}
{
if(irq == IRQ_WDT){
this->wtd_clr(this);
if(this->flag)
{
printk("led_on\n");
this->led_on(this);
}
else
{
printk("led_off\n");
this->led_off(this);
}
this->flag ^= 1;
}
return IRQ_HANDLED;
}
坑爹了。。。。这些都是模型,可以套用别的驱动,有机会可以讨论