您的位置:首页 > 运维架构 > Linux

基于linux构建无人值守系统(看门狗)

2012-11-15 19:02 375 查看
菜鸟心得,高手路过。。。





在各种嵌入式设备soc中基本都提供了看门狗,在很长一段时间里我对看门狗的理解就是“关掉它,不然它会找麻烦”。但是当某种需求存在的时候,它又是必不可少的,比如你的产品是一个类似路由器的服务设备,可能在阳台的某刻角落一丢就是好几年,虽然孤独听起来让人伤感,可是如果在孤独中死去,那就会给客户带来更大的烦恼。所以我们应该去了解它

讲解中使用的环境主要基于linux系统,设备是arm s3c6410





#include <linux/io.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/clk.h>

static int wdt_probe(struct platform_device * dev);
static int wdt_remove(struct platform_device * dev);

struct wdt_driver
{
	struct platform_driver pdrv;
	unsigned long phys_regs;
	unsigned long phys_regs_len;

	struct timer_list timer;
	int irq;
	void * regs;
	
};

static struct wdt_driver wdtdrv =
{
	.pdrv = 
	{
		.probe = wdt_probe,
		.remove = wdt_remove,
		.driver = 
		{
			.name = "s3c2410-wdt",
			.owner = THIS_MODULE,
		},
	},
};

irqreturn_t wdt_irq(int irq,void * data)
{	
	struct wdt_driver * wdtdrv = data;
	iowrite32(1,wdtdrv->regs+0xc);
	printk("wdt_irq\n");

	return IRQ_HANDLED;
}

void wdt_timeout(unsigned long data)
{//喂狗
	struct wdt_driver * wdtdrv = (void *)data;
	//printk("wdt_timeout\n");
	iowrite32(3764,wdtdrv->regs+8);
	mod_timer(&wdtdrv->timer,jiffies+HZ/2);
}

//pclk 66500000
static int wdt_init(struct wdt_driver * wdtdrv)
{

	iowrite32(3764,wdtdrv->regs+4);
	iowrite32(3764,wdtdrv->regs+8);

	//狗中断
	//iowrite32(0x80<<8|0x1<<5|0x1<<2|0x3<<3,wdtdrv->regs);
	//狗reset
	iowrite32(0x80<<8|0x1<<5|0x3<<3|1,wdtdrv->regs);
	
	printk("WTCON=%x\n",ioread32(wdtdrv->regs));
	printk("WTDAT=%x\n",ioread32(wdtdrv->regs+4));
	printk("WTCNT=%x\n",ioread32(wdtdrv->regs+8));

	//启动喂狗定时器
	setup_timer(&wdtdrv->timer, wdt_timeout,(unsigned long)wdtdrv);
	mod_timer(&wdtdrv->timer,jiffies+HZ/2);

	//狗超时中断
//	if(!request_irq(wdtdrv->irq,wdt_irq,IRQF_TRIGGER_FALLING,"wdt",wdtdrv))
//		goto err_timer;

	return 0;

}

static int wdt_destroy(struct wdt_driver * wdtdrv)
{
	//狗timer停止运行
	iowrite32(0x80<<8|0<<5|0x3<<3|1,wdtdrv->regs);
	
	//启动喂狗定时器
	del_timer(&wdtdrv->timer);

	//狗超时中断
	//free_irq(wdtdrv->irq,(unsigned long)wdtdrv);
	return 0;
}

static int wdt_probe(struct platform_device * dev)
{	
	struct wdt_driver * wdtdrv;
	struct resource * res;
	
	printk("wdt_probe:%s\n",dev->name);

	wdtdrv = container_of(container_of(dev->dev.driver,struct platform_driver,driver),struct wdt_driver,pdrv);

	
	//获取控制器寄存器地址
	res = platform_get_resource(dev,IORESOURCE_MEM,0);
	if(!res)
		goto err_out;

	wdtdrv->phys_regs = res->start;
	wdtdrv->phys_regs_len = res->end-res->start;

	
	wdtdrv->regs = ioremap(wdtdrv->phys_regs,wdtdrv->phys_regs_len);
	if(!wdtdrv->regs)
		goto err_out;

	if(!request_mem_region(wdtdrv->phys_regs,wdtdrv->phys_regs_len,dev_name(&dev->dev)))
		goto  err_ioremap;
	
	//获取中断
	wdtdrv->irq = platform_get_irq(dev,0);
	if(wdtdrv->irq<0)
		goto err_request_mem;
	printk("irq=%d\n",wdtdrv->irq);
	
	wdt_init(wdtdrv);
	
	return 0;

err_request_mem:
	release_mem_region(wdtdrv->phys_regs,wdtdrv->phys_regs_len);
err_ioremap:
	iounmap(wdtdrv->regs);
err_out:
	return -1;
}

static int wdt_remove(struct platform_device * dev)
{	
	struct wdt_driver * wdtdrv;
	
	printk("wdt_remove:%s\n",dev->name);

	
	wdtdrv = container_of(container_of(dev->dev.driver,struct platform_driver,driver),struct wdt_driver,pdrv);

	wdt_destroy(wdtdrv);
	release_mem_region(wdtdrv->phys_regs,wdtdrv->phys_regs_len);
	iounmap(wdtdrv->regs);	
	
	return 0;	
}

static  int modinit(void)
{
	printk("mod init\n");
	platform_driver_register(&wdtdrv.pdrv);
	return 0;
}

static void modexit(void)
{
	platform_driver_unregister(&wdtdrv.pdrv);
	printk("mod exit\n");
}

module_init(modinit);
module_exit(modexit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("dragon101788");


首先对模块进行初始化

module_init(modinit);

module_exit(modexit);

从平台中通过文件名"s3c2410-wdt"找出设备,回调wdt_probe

当然你的确定arch/arm/mach-s3c64xx/mach-s3c6410的static struct platform_device *smdk6410_devices[] __initdata中找到&s3c_device_wdt,,如果没有,看看arch/arm/plat-samsung/中有没有dev-wdt.c文件搞到里面的platform_device对象,添加到__initdata中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: