Watchdog使用参考

Version1.0


1. 概述

Watchdog 采用标准的linux 框架,提供硬件的watchdog,上层应用可以设定time out时间,自己来keep alive。

Watchdog默认是关闭的,可自行决定是否开启。开启建议在主线程中操作,如果在其他线程中操作,watchdog会随着线程的关闭而关闭。


2. Kernel配置


3. WATCHDOG控制


3.1. 打开WATCHDOG

打开/dev/watchdog设备,watchdog将被启动。

参考代码如下:

int wdt_fd = -1;
wdt_fd = open("/dev/watchdog", O_WRONLY);
if (wdt_fd == -1)
{
    // fail to open watchdog device
}

3.2. 关闭WATCHDOG

参考代码如下:

int option = WDIOS_DISABLECARD;
        ioctl(wdt_fd, WDIOC_SETOPTIONS, &option);
if (wdt_fd != -1)
    {
        close(wdt_fd);
        wdt_fd = -1;
    }

3.3. 设定TIMEOUT

通过标准的IOCTL命令WDIOC_SETTIMEOUT,来设定timeout,单位是second,timeout的时间建议大于5s,参考代码如下:

int timeout = 20;

ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);

3.4. KEEP ALIVE

通过标准的IOCTL命令WDIOC_KEEPALIVE来喂狗,喂狗时间按照设定的timeout来决定,喂狗时间应该比timeout小,参考代码如下:

ioctl(wdt_fd, WDIOC_KEEPALIVE, 0);

4. 完整demo

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <syslog.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>

int WatchDogInit(int timeout)
{
    printf("[%s %d] init watch dog, timeout:%ds\n", __func__,__LINE__, timeout);
    int wdt_fd = -1;
    wdt_fd = open("/dev/watchdog", O_WRONLY);

    if(wdt_fd == -1)
    {
        printf("[%s %d] open /dev/watchdog failed\n", __func__,__LINE__);
        return -1;
    }
    if(-EINVAL == ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout))
    {
        printf("[%s %d] ioctl return -EINVAL\n", __func__, __LINE__);
    }

    return wdt_fd;
}

int WatchDogDeinit(int wdt_fd)
{
    if(wdt_fd <= 0)

    printf("[%s %d] watch dog hasn't been inited\n",__func__,__LINE__);

    int option = WDIOS_DISABLECARD;
    int ret = ioctl(wdt_fd, WDIOC_SETOPTIONS, &option);
    printf("[%s %s] WDIOC_SETOPTIONS %d WDIOS_DISABLECARD=%d\n", __func__,__LINE__, ret, option);

    if(wdt_fd != -1)
    {
        close(wdt_fd);
        wdt_fd = -1;
    }
    return 0;
}

int WatchDogKeepAlive(int wdt_fd)
{
    if(wdt_fd < 0)
    {
        printf("[%s %d] watch dog hasn't been inited\n",__func__,__LINE__);
        return 0;
    }
    if(-EINVAL == ioctl(wdt_fd, WDIOC_KEEPALIVE, 0))
    {
        printf("[%s %d] ioctl return -EINVAL\n", __func__, __LINE__);
        return -1;
    }
    return 0;
}

int main()
{
    int loop = 0;
    int wdt_fd = -1;
    wdt_fd = WatchDogInit(5);

    loop = 3;
    while(loop--)
    {
        sleep(3);
        WatchDogKeepAlive(wdt_fd);
    }

    printf("Stop to feed dog, let system reboot...\n");

    return 0;
}