微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARMLinux驱动Watch Dog Timer(看门狗)驱动分析

ARMLinux驱动Watch Dog Timer(看门狗)驱动分析

时间:11-19 来源:互联网 点击:
硬件平台:FL2440

内核版本:2.6.28

主机平台:Ubuntu 11,04

内核版本:2.6.39

原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/6595265

1、看门狗驱动的原理

下图是看门狗驱动的原理图


可以看出,PCLK是系统时钟,经过8位的预分频,然后再被分频(16、32、64、128)然后产生计数脉冲,进行计数,当计数器WTCNT加到0或减到0,然后产生中断,或引起系统复位。所以要隔一段时间,重置WTCNT的值,防止WTCNT减到0,称之“喂狗”。

2、驱动分析

下面是自己的驱动分析,如有理解错误,请指正

注,为了尽量是驱动容易理解,这个驱动暂时将有关电源管理的功能删除了,等理解透彻再完善

#include #include #include #include #include #include #include #include #include #include interrupt.h>#include #include #include #include #include #undef S3C_VA_WATCHDOG#define S3C_VA_WATCHDOG (0)#include #define PFX "s3c2410-wdt: "#define CONFIG_S3C2410_WATCHDOG_ATBOOT		(0)#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME	(15)static int nowayout	= WATCHDOG_NOWAYOUT;static int tmr_margin	= CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;static int tmr_atboot	= CONFIG_S3C2410_WATCHDOG_ATBOOT;static int soft_noboot = 1; //设置默认为执行中断static int debug;static int count;//用于计数,控制LED灯的亮灭module_param(tmr_margin,  int, 0);module_param(tmr_atboot,  int, 0);module_param(nowayout,    int, 0);module_param(soft_noboot, int, 0);module_param(debug,	  int, 0);MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default="__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME) ")");MODULE_PARM_DESC(tmr_atboot,"Watchdog is started at boot time if set to 1, default="__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to \reboot (default depends on ONLY_TESTING)");MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)");typedef enum close_state {CLOSE_STATE_NOT,CLOSE_STATE_ALLOW = 0x4021} close_state_t;static unsigned long open_lock;static struct device    *wdt_dev;	/* platform device attached to */static struct resource	*wdt_mem;//用来保存IO端口占用的内存资源static struct resource	*wdt_irq;//保存wdt中断号static struct clk	*wdt_clock;//保存从平台获取的watchdog时钟static void __iomem	*wdt_base;//经过ioremap后的内存基地址static unsigned int	 wdt_count;//保存向WTCNT写的计数值static close_state_t	 allow_close;static DEFINE_SPINLOCK(wdt_lock);//定义一个自旋锁,用于资源的互斥访问/* watchdog control routines */#define DBG(msg...) do { \if (debug) \printk(KERN_INFO msg); \} while (0)/* functions *///喂狗函数,实际上是将wdt_count写入WTCNT寄存器static void s3c2410wdt_keepalive(void){spin_lock(&wdt_lock);//给资源上锁writel(wdt_count, wdt_base + S3C2410_WTCNT);//写WTCNT寄存器spin_unlock(&wdt_lock);//解锁资源,下同}static void __s3c2410wdt_stop(void){unsigned long wtcon;wtcon = readl(wdt_base + S3C2410_WTCON);wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN);writel(wtcon, wdt_base + S3C2410_WTCON);//设备看门狗使能无效、复位功能无效}//停止watchdog计时static void s3c2410wdt_stop(void){spin_lock(&wdt_lock);__s3c2410wdt_stop();spin_unlock(&wdt_lock);}//启动watchdog计时static void s3c2410wdt_start(void){unsigned long wtcon;spin_lock(&wdt_lock);__s3c2410wdt_stop();wtcon = readl(wdt_base + S3C2410_WTCON);wtcon |= S3C2410_WTCON_ENABLE | S3C2410_WTCON_div128;//看门狗定时器使能、时钟除数因子128if (soft_noboot) //使用参数soft_noboot来选择看门狗到时是重启还是执行中断函数{wtcon |            

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top