看门狗应用

目录

1、看门狗介绍

struct watchdog_info

2、imx6u的看门狗 

3、操控看门狗

         打开看门狗设备

开启/关闭看门狗: WDIOC_SETOPTIONS

 获取/设置超时时间:WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT

喂狗: WDIOC_KEEPALIVE

4、看门狗应用编程

验证


1、看门狗介绍

        什么是看门狗?在产品化的嵌入式系统中,为了使系统在异常情况下能自动复位,一般都需要引入看门狗。看门狗其实就是一个可以在一定时间内被复位的计数器。当看门狗启动后,计数器开始自动计数,经过一定时间,如果没有被复位,计数器溢出就会对 CPU 产生一个复位信号使系统重启(俗称“被狗咬”)。系统正常运行时,需要在看门狗允许的时间间隔内对看门狗计数器清零(俗称“喂狗”),不让复位信号产生。如果系统不出问题,程序保证按时“喂狗”,一旦程序跑飞,没有“喂狗”,系统“被咬”复位。
        看门狗其实就是一个可以在一定时间内被复位/重置的计数器,一般叫做看门狗计时器
(或看门狗定时器);如果在规定时间内没有复位看门狗计时器, 计数器溢出则会对 CPU 产生一个复位信号使系统重启,当然有些看门狗也可以只产生中断信号而不会使系统复位。

struct watchdog_info

struct watchdog_info 结构体描述了看门狗设备的信息,定义如下

struct watchdog_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_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 */

 常见的值:  WDIOF_SETTIMEOUT 表示设备支持设置超时时间;                      WDIOF_KEEPALIVEPING 表示设备支持“喂狗”操作,也就是重置看门狗计时器

2、imx6u的看门狗 

        I.MX6ULL SoC 集成了两个看门狗定时器(WDOG): WDOG1 和 WDOG2; WDOG2 用于安全目的,而 WDOG1 则是一个普通的看门狗,支持产生中断信号以及复位 CPU
        Linux 系统中所注册的看门狗外设,都会在/dev/目录下生成对应的设备节点(设备文件),设备节点名称通常为 watchdogX(X 表示一个数字编号 0、 1、 2、 3 等),譬如/dev/watchdog0、 /dev/watchdog1 等,通过这些设备节点可以控制看门狗外设。

         watchdog0 其实就是 I.MX6U 的 WDOG1 所对应的设备节点

        系统中可能注册了多个看门狗设备, /dev/watchdog 设备节点则代表系统默认的看门狗设备; 通常这指的就是 watchdog0, 所以, 上图中, /dev/watchdog 其实就等于/dev/watchdog0,也就意味着它俩代表的是同一个硬件外设

3、操控看门狗

        应用层控制看门狗其实非常简单,通过 ioctl()函数即可做到,应用程序中,需要包含头文件<linux/watchdog.h>头文件, 该头文件中定义了一些 ioctl 指令宏,每一个不同的指令宏表示向设备请求不同的操作,如下所示:

#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)

比 较 常 用 指 令如下

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

 打开看门狗设备

open("/dev/watchdog", "O_RDWR")

 需要注意的是,当调用 open()打开看门狗设备的时候, 即使程序中没有开启看门狗计时器,所以,当打开设备之后, 需要使用 指令停止看门狗计时,等所有设置完成之后再开启看门狗计时器

开启/关闭看门狗: WDIOC_SETOPTIONS

使用 WDIOC_SETOPTIONS 指令可以开启看门狗计时或停止看门狗计时,使用方式如下:

ioctl(int fd, WDIOC_SETOPTIONS, int *option);

 option 指针指向一个 int 类型变量,该变量可取值如下:

#define WDIOS_DISABLECARD 0x0001 /*Turn off the watchdog timer停止看门狗计时*/
#define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer开启看门狗计时*/

 获取/设置超时时间:WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT

使用 WDIOC_GETTIMEOUT 指令可获取设备当前设置的超时时间,使用方式如下:

ioctl(int fd, WDIOC_GETTIMEOUT, int *timeout);

 使用 WDIOC_SETTIMEOUT 指令可设置看门狗的超时时间,使用方式如下:

ioctl(int fd, WDIOC_SETTIMEOUT, int *timeout);

 超时时间是以秒为单位, 设置超时时间时,不可超过其最大值、否则 ioctl()调用将会失败

喂狗: WDIOC_KEEPALIVE

看门狗计时器启动之后,需要在超时之前,去“喂狗”,否则计时器溢出超时将会导致系统复位或产生一个中断信号,通过 WDIOC_KEEPALIVE 指令喂狗,使用方式如下:

ioctl(int fd, WDIOC_KEEPALIVE, NULL);

4、看门狗应用编程

定义一个看门狗设备信息结构体、超时时间、喂狗时间、文件描述符、 op用来传递值

        先判断命令行传参是否相等,参数分别是运行app和超时时间

         在上面有介绍,打开看门狗之后就会开始计时,所以要先关闭看门狗计时,不关闭时间到了就会重启系统

         从命令行获取超时时间,如果超时时间少于1秒,这里默认为1秒,然后设置超时时间

         设置好超时时间就开始看门狗计时,这里设置喂狗时间为超时前100毫秒,当差100毫秒就超时的时候就喂狗

验证

运行app

 执行程序之后,开门狗计时器就启动了,程序中会不断的喂狗重置计时器,以保证程序不会重启

 按 Ctrl + C 结束程序,结束程序意味着已经停止喂狗了、然后看门狗计时器并没有停止,这样
将会导致计时器溢出、发生复位重启

 按 Ctrl+C 终止进程后,内核打印出“watchdog watchdog0: watchdog did not stop!”信息,表示看门狗计时器还正在计时、未停止,然后就会重启系统了

猜你喜欢

转载自blog.csdn.net/weixin_46829095/article/details/129629350