MT7620_看门狗(Watchdog)驱动

一、硬件平台: MT7620(A9内核)

二、软件平台:

       1、Ubuntu 12.04 

       2、MT7620 SDK软件开发包(MediaTek_ApSoC_SDK_4320_20150414.tar.bz2)

三、功能简介

       对于看门狗以及其他的一些驱动,本人建议编译成模块,采用.ko 文件挂载,如此方便移植和维护。而且与内核分离开,可以节省编译时间,提高效率。

四、修改内容

       对于MT7620 软件SDK 开发包,已经含有看门狗驱动。但是,内核看门狗驱动源码,默认没有设置看门狗超时时间的接口,故需要修改代码,增加相应的接口。

五、看门狗程序

       1、看门狗头文件

       本程序与为SDK开发包源码一致,原始的SDK代码为   " ..\RT288x_SDK\source\linux-2.6.36.x\drivers\watchdog\ralink_wdt.h "

       头文件名称 watchdog_driver.h

#include <asm/rt2880/rt_mmap.h>

#ifndef _RALINK_WDT_WANTED
#define _RALINK_WDT_WANTED

#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr)
#define sysRegRead(phys) (*(volatile unsigned int *)PHYS_TO_K1(phys))
#define sysRegWrite(phys, val)  ((*(volatile unsigned int *)PHYS_TO_K1(phys)) = (val))

#define SYSCFG      RALINK_SYSCTL_BASE + 0x10  /* System Configuration Register */
#define SYSCFG1     RALINK_SYSCTL_BASE + 0x14  /* System Configuration Register1 */
#define GPIOMODE    RALINK_SYSCTL_BASE + 0x60  
#define CLKCFG      RALINK_SYSCTL_BASE + 0x30  /* Clock Configuration Register */
#define TMRSTAT     (RALINK_TIMER_BASE)  /* Timer Status Register */

#if defined (CONFIG_RALINK_RT6855A)
#define TMR1CTL     (TMRSTAT + 0x0)  /* WDG Timer Control */
#define TMR1LOAD    (TMRSTAT + 0x2C) /* WDG Timer Load Value Register */
#define TMR1VAL     (TMRSTAT + 0x30) /* WDG Timer Current Value Register */
#define RLDWDOG     (TMRSTAT + 0x38) /* Reload Watchdog */
#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) 
#define TMR0CTL     (TMRSTAT + 0x10)  /* Timer0 Control */
#define TMR0LOAD    (TMRSTAT + 0x14)  /* Timer0 Load Value */
#define TMR0VAL     (TMRSTAT + 0x18)  /* Timer0 Counter Value */
#define TMR1CTL     (TMRSTAT + 0x20)  /* WDG Timer Control */
#define TMR1LOAD    (TMRSTAT + 0x24)  /* WDG Timer Load Value */
#define TMR1VAL     (TMRSTAT + 0x28)  /* WDG Timer Counter Value */
#define TMR2CTL     (TMRSTAT + 0x30)  /* Timer1 Control */
#define TMR2LOAD    (TMRSTAT + 0x34)  /* Timer1 Load Value */
#define TMR2VAL     (TMRSTAT + 0x38)  /* Timer1 Counter Value */
#else
#define TMR1CTL     (TMRSTAT + 0x28)  /* Timer1 Control */
#define TMR1LOAD    (TMRSTAT + 0x20)  /* Timer1 Load Value */
#define TMR1VAL     (TMRSTAT + 0x24)  /* Timer1 Counter Value */
#endif

#define INTENA      (RALINK_INTCL_BASE + 0x34)  /* Interrupt Enable */

enum timer_mode {
    FREE_RUNNING,
    PERIODIC,
    TIMEOUT,
    WATCHDOG
};

enum timer_clock_freq {
    SYS_CLK,          /* System clock     */
    SYS_CLK_DIV4,     /* System clock /4  */
    SYS_CLK_DIV8,     /* System clock /8  */
    SYS_CLK_DIV16,    /* System clock /16 */
    SYS_CLK_DIV32,    /* System clock /32 */
    SYS_CLK_DIV64,    /* System clock /64 */
    SYS_CLK_DIV128,   /* System clock /128 */
    SYS_CLK_DIV256,   /* System clock /256 */
    SYS_CLK_DIV512,   /* System clock /512 */
    SYS_CLK_DIV1024,  /* System clock /1024 */
    SYS_CLK_DIV2048,  /* System clock /2048 */
    SYS_CLK_DIV4096,  /* System clock /4096 */
    SYS_CLK_DIV8192,  /* System clock /8192 */
    SYS_CLK_DIV16384, /* System clock /16384 */
    SYS_CLK_DIV32768, /* System clock /32768 */
    SYS_CLK_DIV65536  /* System clock /65536 */
};

#endif

        2、看门狗程序,参考SDK开发包中的 “ ..\RT288x_SDK\source\linux-2.6.36.x\drivers\watchdog\ralink_wdt.c ” 文件

        文件名称为 watchdog_driver.c

        

// 本程序参考SDK开发包文件
// ..\RT288x_SDK\source\linux-2.6.36.x\drivers\watchdog\ralink_wdt.c

#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/sgi/mc.h>
#include "watchdog_driver.h"

static int RaWdgAlive;
static int WdgLoadValue;
extern u32 get_surfboard_sysclk(void);

// modify :sky.houfei
#define WATCHDOG_TIMEOUT 90		/* 90 sec default timeout */
static int s_timeout = WATCHDOG_TIMEOUT;

#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
#endif

void SetWdgTimerEbl(unsigned int timer, unsigned int ebl)
{
    unsigned int result;

    result=sysRegRead(timer);

    if(ebl==1){
#if defined (CONFIG_RALINK_RT6855A)
        result |= (1<<25) | (1<<5);
#else
        result |= (1<<7);
#endif
    }else {
#if defined (CONFIG_RALINK_RT6855A)
        result &= ~((1<<25)|(1<<5));
#else
        result &= ~(1<<7);
#endif
    }

    sysRegWrite(timer,result);

  //timer1 used for watchdog timer
#if defined (CONFIG_RALINK_TIMER_WDG_RESET_OUTPUT)

#if defined (CONFIG_RALINK_RT2880)
    if(timer==TMR1CTL) {
        result=sysRegRead(CLKCFG);

        if(ebl==1){
            result |= (1<<9); /* SRAM_CS_N is used as wdg reset */
        }else {
            result &= ~(1<<9); /* SRAM_CS_N is used as normal func */
        }

        sysRegWrite(CLKCFG,result);
    }
#elif defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT2883)
    if(timer==TMR1CTL) {
        //the last 4bits in SYSCFG are write only
        result=sysRegRead(SYSCFG);

        if(ebl==1){
            result |= (1<<2); /* SRAM_CS_MODE is used as wdg reset */
        }else {
            result &= ~(1<<2); /* SRAM_CS_MODE is used as wdg reset */
        }

        sysRegWrite(SYSCFG,result);
    }
#elif defined (CONFIG_RALINK_RT3883)
    if(timer==TMR1CTL) {
        result=sysRegRead(SYSCFG1);

        if(ebl==1){
            result |= (1<<2); /* GPIO2 as watch dog reset */
        }else {
            result &= ~(1<<2);
        }

        sysRegWrite(SYSCFG1,result);
    }
#elif defined (CONFIG_RALINK_RT3352)
    if(timer==TMR1CTL) {
	//GPIOMODE[22:21]
	//2'b00:SPI_CS1
	//2'b01:WDG reset output
	//2'b10:GPIO mode
        result=sysRegRead(GPIOMODE); //GPIOMODE[22:21]
	result &= ~(0x3<<21);

        if(ebl==1){
            result |= (0x1<<21); /* SPI_CS1 as watch dog reset */
        }else {
            //result |= (0x0<<21); //SPI_CS1
            result |= (0x2<<21); //GPIO_mode
        }

        sysRegWrite(GPIOMODE,result);
    }
#elif defined (CONFIG_RALINK_RT5350)
    if(timer==TMR1CTL) {
	/*
	 * GPIOMODE[22:21]
	 * 2'b00:SPI_CS1
	 * 2'b01:WDG reset output
	 * 2'b10:GPIO mode
	 */
        result=sysRegRead(GPIOMODE); 
	result &= ~(0x3<<21);

        if(ebl==1){
            result |= (0x1<<21);
        }else {
	    //result |= (0x0<<21); //SPI_CS1
	    result |= (0x2<<21); //GPIO mode
	} 
        
	sysRegWrite(GPIOMODE,result);

    }
#elif defined (CONFIG_RALINK_MT7620)

    if(timer==TMR1CTL) {
        result=sysRegRead(GPIOMODE);
	/*
	 * GPIOMODE[22:21] WDT_GPIO_MODE
	 * 2'b00:Normal
	 * 2'b01:REFCLK0
	 * 2'b10:GPIO Mode
	 */
	result &= ~(0x3<<21);

        if(ebl==1){
            result |= (0x0<<21);
        }else {
	    result |= (0x2<<21); //GPIO
	    //result |= (0x1<<21); //REFCLK0
        }
        sysRegWrite(GPIOMODE,result);
    }
#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) 

    if(timer==TMR1CTL) {
        result=sysRegRead(GPIOMODE);
	/*
	 * GPIOMODE[22:21] WDT_GPIO_MODE
	 * 2'b00:Normal
	 * 2'b01:REFCLK0
	 * 2'b10:GPIO Mode
	 */
	result &= ~(0x3<<21);

        if(ebl==1){
            result |= (0x0<<21);
        }else {
	    result |= (0x2<<21); //GPIO
	    //result |= (0x1<<21); //REFCLK0
        }
        sysRegWrite(GPIOMODE,result);
    }
#endif
#endif
}

#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)
void SetWdgTimerClock(int prescale)
{
    unsigned int result;

    result=sysRegRead(TMR1CTL);
    result &= 0x0000FFFF;
    result |= (prescale << 16); //unit = 1u
    sysRegWrite(TMR1CTL, result);
}
void SetTimerMode(unsigned int timer, enum timer_mode mode)
{
}
#else
void SetTimerMode(unsigned int timer, enum timer_mode mode)
{
    unsigned int result;

    result=sysRegRead(timer);
    result &= ~(0x3<<4); //watchdog mode
    result=result | (mode << 4);
    sysRegWrite(timer,result);
}

void SetWdgTimerClock(unsigned int timer, enum timer_clock_freq prescale)
{
    unsigned int result;

    result=sysRegRead(timer);
    result &= ~0xF;
    result=result | (prescale&0xF);
    sysRegWrite(timer,result);
}
#endif

static void RaWdgStart(void)
{
#if defined (CONFIG_RALINK_RT6855A)
    int HwConf;
#endif

    printk(KERN_INFO "Started WatchDog Timer.\n");

    SetTimerMode(TMR1CTL,WATCHDOG);
#if defined (CONFIG_RALINK_RT2880) || defined (CONFIG_RALINK_RT2883) || \
    defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3883)
    /*
     * For user easy configuration, We assume the unit of watch dog timer is 1s,
     * so we need to calculate the TMR1LOAD value.
     *
     * Unit= 1/(SysClk/65536), 1 Sec = (SysClk)/65536
     *
     */
    SetWdgTimerClock(TMR1CTL,SYS_CLK_DIV65536);
    WdgLoadValue = s_timeout * (get_surfboard_sysclk()/65536);
#elif defined (CONFIG_RALINK_RT6855A)
    HwConf = sysRegRead(RALINK_SYSCTL_BASE + 0x8c);
    if(((HwConf >> 24) & 0x3) == 0) { //SDR
            WdgLoadValue =  s_timeout * (140 * 1000 * 1000 / 2);
    }else {
            if(((HwConf >> 26) & 0x1) == 0) {
                     WdgLoadValue =  s_timeout * (233 * 1000 * 1000 / 2);
            }else {
                     WdgLoadValue =  s_timeout * (175 * 1000 * 1000 / 2);
            }
    }
    sysRegWrite(TMR1LOAD,  WdgLoadValue);
#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)
    SetWdgTimerClock(1000); // 1 msec
    WdgLoadValue = s_timeout * 1000;
    sysRegWrite(TMR1LOAD,  WdgLoadValue);
#else
    SetWdgTimerClock(TMR1CTL,SYS_CLK_DIV65536);
    WdgLoadValue = s_timeout * (40000000/65536); //fixed at 40Mhz
#endif
    
    sysRegWrite(TMR1LOAD, WdgLoadValue);
    SetWdgTimerEbl(TMR1CTL,1);
}

static void RaWdgStop(void)
{
	SetWdgTimerEbl(TMR1CTL,0);

	printk(KERN_INFO "Stopped WatchDog Timer.\n");
}

static void RaWdgReload(void)
{
#if defined (CONFIG_RALINK_RT6855A)
	 sysRegWrite(RLDWDOG, 1);
#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)
	 sysRegWrite(TMRSTAT, (1 << 9)); //WDTRST
#else
	 sysRegWrite(TMR1LOAD, WdgLoadValue);
#endif
}

// add by sky.houfei
// 设置WatchDog周期timeout
static int RaWdgSetHeartbeat(int timeout)
{
#if defined (CONFIG_RALINK_RT6855A)
    int HwConf;
#endif

	if (timeout > 107)
	{
		printk("Warn! The timeout value is > 107 second, the max value is 107.Set failed\n");
	}
    SetTimerMode(TMR1CTL,WATCHDOG);
	s_timeout = timeout;
#if defined (CONFIG_RALINK_RT2880) || defined (CONFIG_RALINK_RT2883) || \
    defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3883)
    /*
     * For user easy configuration, We assume the unit of watch dog timer is 1s,
     * so we need to calculate the TMR1LOAD value.
     *
     * Unit= 1/(SysClk/65536), 1 Sec = (SysClk)/65536
     *
     */
    SetWdgTimerClock(TMR1CTL,SYS_CLK_DIV65536);
    WdgLoadValue = s_timeout * (get_surfboard_sysclk()/65536);
#elif defined (CONFIG_RALINK_RT6855A)
    HwConf = sysRegRead(RALINK_SYSCTL_BASE + 0x8c);
    if(((HwConf >> 24) & 0x3) == 0) { //SDR
            WdgLoadValue =  s_timeout * (140 * 1000 * 1000 / 2);
    }else {
            if(((HwConf >> 26) & 0x1) == 0) {
                     WdgLoadValue =  s_timeout * (233 * 1000 * 1000 / 2);
            }else {
                     WdgLoadValue =  s_timeout * (175 * 1000 * 1000 / 2);
            }
    }
    sysRegWrite(TMR1LOAD,  WdgLoadValue);
#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)
    SetWdgTimerClock(1000); // 1 msec
    WdgLoadValue = s_timeout * 1000;
    sysRegWrite(TMR1LOAD,  WdgLoadValue);
#else
    SetWdgTimerClock(TMR1CTL,SYS_CLK_DIV65536);
    WdgLoadValue = s_timeout * (40000000/65536); //fixed at 40Mhz
#endif
    
    sysRegWrite(TMR1LOAD, WdgLoadValue);
    SetWdgTimerEbl(TMR1CTL,1);

	return 0;
}

/*
 *	Allow only one person to hold it open
 */
static int ralink_open(struct inode *inode, struct file *file)
{
	if (RaWdgAlive)
		return -EBUSY;

#ifdef CONFIG_WATCHDOG_NOWAYOUT
	if (nowayout)
		__module_get(THIS_MODULE);
#endif

	/* Activate timer */
	RaWdgStart();
	RaWdgAlive = 1;

	return nonseekable_open(inode, file);
}

static int ralink_release(struct inode *inode, struct file *file)
{
	/* Shut off the timer.
	 * Lock it in if it's a module and we defined ...NOWAYOUT */
#ifdef CONFIG_WATCHDOG_NOWAYOUT
	if (!nowayout)
		RaWdgStop();		/* Turn the WDT off */
#endif

	RaWdgAlive = 0;

	return 0;
}

static ssize_t ralink_write(struct file *file, const char *data, size_t len, loff_t *ppos)
{
	/* Refresh the timer. */
	if (len) {
		RaWdgReload();
	}
	return len;
}

static struct watchdog_info ident = {
    .options		= WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
    .identity		= "Ralink Hardware WatchDog",
};

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
long ralink_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
#else
static int ralink_ioctl(struct inode *inode, struct file *file,
	unsigned int cmd, unsigned long arg)
#endif
{
	int options, retval = -EINVAL;
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_margin;

	switch (cmd) {
		default:
			return -ENOTTY;
		case WDIOC_GETSUPPORT:
			if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
				return -EFAULT;
			return 0;
		case WDIOC_GETSTATUS:
		case WDIOC_GETBOOTSTATUS:
			return put_user(0,(int *)arg);
		case WDIOC_KEEPALIVE:
			RaWdgReload();
			return 0;
		case WDIOC_GETTIMEOUT:
			return put_user(s_timeout,(int *)arg);
			
        // add by sky.houfei
        // 增加设置超时时间功能
		case WDIOC_SETTIMEOUT:
			if (get_user(new_margin, p))
			{
				return -EFAULT;
			}
			if (RaWdgSetHeartbeat(new_margin))
			{
				return -EINVAL;
			}
			RaWdgReload();
			return put_user(s_timeout, p);
		case WDIOC_SETOPTIONS:
		{
			if (get_user(options, (int *)arg))
				return -EFAULT;

			if (options & WDIOS_DISABLECARD) {
				RaWdgStop();
				retval = 0;
			}

			if (options & WDIOS_ENABLECARD) {
				RaWdgStart();
				retval = 0;
			}

			return retval;
		}
	}
}

static int ralink_notify_sys(struct notifier_block *this, unsigned long code, void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		RaWdgStop();		/* Turn the WDT off */

	return NOTIFY_DONE;
}

static const struct file_operations ralink_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= ralink_write,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
	.unlocked_ioctl = ralink_ioctl,
#else
	.ioctl		= ralink_ioctl,
#endif
	.open		= ralink_open,
	.release	= ralink_release,
};

static struct miscdevice ralink_miscdev = {
	.minor		= WATCHDOG_MINOR,
	.name		= "watchdog",
	.fops		= &ralink_fops,
};

static struct notifier_block ralink_notifier = {
	.notifier_call = ralink_notify_sys,
};

static char banner[] __initdata =
	KERN_INFO "Ralink APSoC Hardware Watchdog Timer\n";

static int __init watchdog_init(void)
{
	int ret;

	ret = register_reboot_notifier(&ralink_notifier);
	if (ret) {
		printk(KERN_ERR "cannot register reboot notifier (err=%d)\n",
			ret);
		return ret;
	}

	ret = misc_register(&ralink_miscdev);
	if (ret) {
		printk(KERN_ERR "cannot register miscdev on minor=%d (err=%d)\n",
			WATCHDOG_MINOR, ret);
		unregister_reboot_notifier(&ralink_notifier);
		return ret;
	}

	printk(banner);

	return 0;
}

static void __exit watchdog_exit(void)
{
	RaWdgStop();
	misc_deregister(&ralink_miscdev);
	unregister_reboot_notifier(&ralink_notifier);
}

module_init(watchdog_init);
module_exit(watchdog_exit);

MODULE_AUTHOR("sky.houfei");
MODULE_DESCRIPTION("Ralink APSoC Hardware Watchdog Timer");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

        3、驱动 makefile

        文件名:MakeFile

        make 命令,其中 “ /home/sky/RT288x_SDK/source/linux-2.6.36.x/  ”为内核包的路径。

make MIPSLINUXDIR=/home/sky/RT288x_SDK/source/linux-2.6.36.x/
       make clean 命令,其中 “ /home/sky/RT288x_SDK/source/linux-2.6.36.x/  ”为内核包的路径。

make MIPSLINUXDIR=/home/sky/RT288x_SDK/source/linux-2.6.36.x/ clean

       MakeFile 内容如下:

obj-m = watchdog_driver.o

#K_DIR = /home/sky/RT288x_SDK/source/linux-2.6.36.x/

PWD=$(shell pwd)

all:
	make  ARCH=mips CROSS_COMPILE="/opt/buildroot-gcc463/usr/bin"/mipsel-linux-  -C $(MIPSLINUXDIR)  M=$(PWD) modules
	
clean:
	make  ARCH=mips CROSS_COMPILE="/opt/buildroot-gcc463/usr/bin"/mipsel-linux-  -C $(MIPSLINUXDIR)  M=$(PWD) clean
	rm -f watchdog_driver.ko
  
#make command:
#make MIPSLINUXDIR=/home/sky/RT288x_SDK/source/linux-2.6.36.x/
#make MIPSLINUXDIR=/home/sky/RT288x_SDK/source/linux-2.6.36.x/ clean

       4、看门狗应用程序

        程序名称:watchdog_app.c

/*
 * Watchdog Driver Test Program
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/watchdog.h>


#define DEV  "/dev/watchdog"

static int s_watchdogFd;

/*
* @brief 看门狗使能。
*/
static void Watchdog_Start(void)
{
	int i = WDIOS_ENABLECARD;

	ioctl(s_watchdogFd,WDIOC_SETOPTIONS,&i);
}


/*
* @brief 看门狗禁止。
*/
static void Watchdog_Stop(void)
{
	int i = WDIOS_DISABLECARD;

	ioctl(s_watchdogFd, WDIOC_SETOPTIONS, &i);
}


/*
* @brief 喂狗程序。
*/
static void Watchdog_Feed(void)
{
    int dummy;

    ioctl(s_watchdogFd, WDIOC_KEEPALIVE, &dummy);
}

/*
* @brief 设置看门狗复位时间。
* @param[in] time, unsigned int, 复位时间,单位为秒。
*/
static void Watchdog_TimeoutSet(int time)
{
	ioctl(s_watchdogFd, WDIOC_SETTIMEOUT, &time);
}


/*
* @brief 获取看门狗复位时间。
* @return time, int,复位定时时间,单位为秒。
*/
static int Watchdog_TimeoutGet(void)
{
	int time = 0;

	ioctl(s_watchdogFd, WDIOC_GETTIMEOUT, &time);
	return time;
}


int main(int argc, char *argv[])
{
    int flags;  
	int count = 0;
	int i = 0;

    s_watchdogFd = open(DEV, O_RDWR);

    if (s_watchdogFd == -1) 
	{
		fprintf(stderr, "Watchdog device not enabled.\n");
		fprintf(stderr, "Can not find the file /dev/watchdog.\n");
		fflush(stderr);
		exit(-1);
    }

    // 读看门狗溢出时间
    i = Watchdog_TimeoutGet(); 
    printf("watchdog get timer = %d\n", i);	

    // 设置看门狗溢出时间
    i = 5;	// 复位时间5秒
    Watchdog_TimeoutSet(i);
    printf("watchdog set timer = %d\n", i);
	
    // 读看门狗溢出时间
    i = Watchdog_TimeoutGet(); 
    printf("watchdog get timer = %d\n", i);

    // 功能说明:
    // 1、前面10秒喂狗,看门狗不会复位,用于验证喂狗功能是否正常。
    // 2、第11 秒关闭看门狗,用于验证看门狗关闭是否正常(如果不能关闭,则5秒达到看门狗超时后,自动复位)。
    // 3、第30秒 看门狗使能,用于验证看门狗使能是否正常,此时不喂狗,5秒后自动复位。
    //  如果验证看门狗是否正常,直接把 喂狗、开启、关闭看门狗代码注释即可。
    while(1) 
    {
		count++;
		if (count < 10)
		{
			Watchdog_Feed();      // 喂狗程序
		}
		else if (count == 11)
		{
			Watchdog_Stop();   // 停止看门狗功能
		}
		else if (count == 30)
		{
			Watchdog_Start();   // 开启看门狗功能
		}
		sleep(1);
		printf("count = %d\n", count);
    }
}

  

你可能感兴趣的:(linux,linux,kernel,驱动,看门狗)