当前位置:首页>Linux>防止系统死机:嵌入式Linux看门狗(Watchdog)应用编程实战

防止系统死机:嵌入式Linux看门狗(Watchdog)应用编程实战

  • 2026-09-02 20:22:11
防止系统死机:嵌入式Linux看门狗(Watchdog)应用编程实战

IMX6ULL上的看门狗

ls /dev/watchdog*/dev/watchdog  /dev/watchdog0

<linux/watchdog.h> : watch的ioctl命令

#define    WATCHDOG_IOCTL_BASE    'W'#define    WDIOC_GETSUPPORT    _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)#define    WDIOC_GETSTATUS        _IOR(WATCHDOG_IOCTL_BASE, 1, int)#define    WDIOC_GETBOOTSTATUS    _IOR(WATCHDOG_IOCTL_BASE, 2, int)#define    WDIOC_GETTEMP        _IOR(WATCHDOG_IOCTL_BASE, 3, int)#define    WDIOC_SETOPTIONS    _IOR(WATCHDOG_IOCTL_BASE, 4, int)#define    WDIOC_KEEPALIVE        _IOR(WATCHDOG_IOCTL_BASE, 5, int)#define    WDIOC_SETTIMEOUT        _IOWR(WATCHDOG_IOCTL_BASE, 6, int)#define    WDIOC_GETTIMEOUT        _IOR(WATCHDOG_IOCTL_BASE, 7, int)#define    WDIOC_SETPRETIMEOUT    _IOWR(WATCHDOG_IOCTL_BASE, 8, int)#define    WDIOC_GETPRETIMEOUT    _IOR(WATCHDOG_IOCTL_BASE, 9, int)#define    WDIOC_GETTIMELEFT    _IOR(WATCHDOG_IOCTL_BASE, 10, int)#define    WDIOS_DISABLECARD    0x0001    /* Turn off the watchdog timer */#define    WDIOS_ENABLECARD    0x0002    /* Turn on the watchdog timer */#define    WDIOS_TEMPPANIC        0x0004    /* Kernel panic on temperature trip */

常用指令:

ioctl指令
WDIOC_GETSUPPORT
获取看门狗支持哪些功能
WDIOC_SETOPTIONS
用于开启或关闭看门狗
WDIOC_KEEPALIVE
喂狗操作
WDIOC_SETTIMEOUT
设置看门狗超时时间
WDIOC_GETTIMEOUT
获取看门狗超时时间

WDIOC_GETSUPPORT 通过struct watchdog_info获取看够支持的功能。

structwatchdog_info {    __u32 options;        /* Options the card/driver supports */    __u32 firmware_version;    /* Firmware version of the card */    __u8  identity[32];    /* Identity of the board */};
  • options,记录看够支持的功能或选项
  • firmware_version,设备版本号
  • identity,描述性的字符串

options字段主要是以下值的位或:

#define    WDIOF_UNKNOWN        -1    /* Unknown flag error */#define    WDIOS_UNKNOWN        -1    /* Unknown status error */#define    WDIOF_OVERHEAT        0x0001    /* Reset due to CPU overheat */#define    WDIOF_FANFAULT        0x0002    /* Fan failed */#define    WDIOF_EXTERN1        0x0004    /* External relay 1 */#define    WDIOF_EXTERN2        0x0008    /* External relay 2 */#define    WDIOF_POWERUNDER    0x0010    /* Power bad/power fault */#define    WDIOF_CARDRESET        0x0020    /* Card previously reset the CPU */#define    WDIOF_POWEROVER        0x0040    /* Power over voltage */#define    WDIOF_SETTIMEOUT    0x0080  /* Set timeout (in seconds) */#define    WDIOF_MAGICCLOSE    0x0100    /* Supports magic close char */#define    WDIOF_PRETIMEOUT    0x0200  /* Pretimeout (in seconds), get/set */#define    WDIOF_ALARMONLY        0x0400    /* Watchdog triggers a management or                       other external alarm not a reboot */#define    WDIOF_KEEPALIVEPING    0x8000    /* Keep alive ping reply */

看门狗编程

编程步骤:

  1. open看门狗设备节点,打开狗看门狗会立即运行
  2. WDIOC_SETOPTIONS,关闭看门狗
  3. WDIOC_SETTIMEOUT ,设置看门狗超时时间
  4. WDIOC_KEEPALIVE,喂狗

wdg.h :

#ifndef __WDG_H__#define __WDG_H__enum {    WDG_OFF = 0,    WDG_ON,};typedefunsignedcharwdg_on_off_t;/* * @brief : 打开看门狗   */intwdg_open(constchar *devname);/* * @brief : 开启or停止看门狗 */intwdg_on_off(int fd, wdg_on_off_t on_off);/* * @brief : 设置看门狗超时时间 * @param : timeout 超时时间,单位s(秒) */intwdg_set_timeout(int fd, int timeout);/* * @brief : 喂狗 */intwdg_feed(int fd);#endif/* __WDG_H__ */

wdg.c :

#include"wdg.h"#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<sys/ioctl.h>#include<errno.h>#include<string.h>#include<linux/watchdog.h>/* * @brief : 打开看门狗   */intwdg_open(constchar *devname){return open(devname, O_RDWR);}/* * @brief : 开启or停止看门狗 */intwdg_on_off(int fd, wdg_on_off_t on_off){int op = WDIOS_ENABLECARD;if (on_off == WDG_OFF)        op = WDIOS_DISABLECARD;    ioctl(fd, WDIOC_SETOPTIONS, &op);}/* * @brief : 设置看门狗超时时间 * @param : timeout 超时时间,单位s(秒) */intwdg_set_timeout(int fd, int timeout){return ioctl(fd, WDIOC_SETTIMEOUT, &timeout);}/* * @brief : 喂狗 */intwdg_feed(int fd){return ioctl(fd, WDIOC_KEEPALIVE, NULL);}

wdg_sample:

#include"stdio.h"#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<stdio.h>#include<string.h>#include<sys/ioctl.h>#include<poll.h>#include<stdint.h>#include<sys/select.h>#include"wdg.h"#define    WDOG_DEV      "/dev/watchdog0"voidsleep_ms(unsignedint ms){structtimevaldelay;    delay.tv_sec = 0;    delay.tv_usec = ms * 1000;     select(0, NULL, NULL, NULL, &delay);}intmain(int argc, char **argv){int fd;    fd = wdg_open(WDOG_DEV);if (fd < 0)     {printf("Open watchdog err\r\n");return-1;    }    wdg_on_off(fd, WDG_OFF);    wdg_set_timeout(fd, 2);    wdg_on_off(fd, WDG_ON);int cnt = 0;while (1)    {printf("--------> %d\r\n", cnt);        wdg_feed(fd);if (++cnt < 20)        {            sleep_ms(500);        }else        {while (1)            {                sleep_ms(5000);            }        }    }return0;}

测试:

debian@npi:~/nfs_root$ sudo ./wdg_sample--------> 0--------> 1--------> 2--------> 3--------> 4--------> 5--------> 6--------> 7--------> 8--------> 9--------> 10--------> 11--------> 12--------> 13--------> 14--------> 15--------> 16--------> 17--------> 18--------> 19U-Boot 2020.10-g4f79a1a2 (Apr 08 2021 - 09:59:52 +0800)CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)CPU:   Industrial temperature grade (-40C to 105C) at 52CReset cause: WDOGModel: Freescale i.MX6 UltraLiteLite 14x14 EVK BoardBoard: MX6ULL 14x14 EVKDRAM:  512 MiBMMC:   FSL_SDHC: 0, FSL_SDHC: 1Loading Environment from MMC... OK

看够uboot信息可以知道系统重启了

最新文章

随机文章