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 */
常用指令:
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字段主要是以下值的位或:
#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 */
看门狗编程
编程步骤:
- WDIOC_SETTIMEOUT ,设置看门狗超时时间
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信息可以知道系统重启了