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);
    }
}

  

發佈了44 篇原創文章 · 獲贊 20 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章