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 |
ARMLinux驱动WatchDogTime 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)