SSD_Watchdog使用参考
1. 概述¶
Watchdog 采用标准的linux 框架,提供硬件的watchdog,上层应用可以设定time out时间,自己来keep alive。
Watchdog默认是关闭的,可自行决定是否开启。开启建议在主线程中操作,如果在其他线程中操作,watchdog会随着线程的关闭而关闭。
2. BOOT配置¶
如图,在boot打开Enabel watchdog 的config来打开WATCHDOG即可,不需要额外call接口设置,同时可以通过 HW WATCHDOG Timeout 设置time out时间(Default为10s)
3. Kernel配置¶
4. WATCHDOG控制¶
4.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 }
4.2. 关闭WATCHDOG¶
参考代码如下:
int option = WDIOS_DISABLECARD; ioctl(wdt_fd, WDIOC_SETOPTIONS, &option); if (wdt_fd != -1) { close(wdt_fd); wdt_fd = -1; }
4.3. 设定TIMEOUT¶
通过标准的IOCTL命令WDIOC_SETTIMEOUT
,来设定timeout,单位是second,timeout的时间建议大于5s,参考代码如下:
int timeout = 20; ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);
4.4. KEEP ALIVE¶
通过标准的IOCTL命令WDIOC_KEEPALIVE
来喂狗,喂狗时间按照设定的timeout来决定,喂狗时间应该比timeout小,参考代码如下:
ioctl(wdt_fd, WDIOC_KEEPALIVE, 0);
5. 完整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; }