TX2之WDT看门狗测试程序

匿名 (未验证) 提交于 2019-12-02 23:43:01

参考:https://developer.toradex.cn/knowledge-base/watchdog-(linux)

1 背景

看门狗,又叫watchdog timer,是一个定时器电路,一般有一个输入,叫喂狗(kicking the dog/service the dog),一个输出到MCU的RST端,MCU正常工作的时候,每隔一段时间输出一个信号到喂狗端,给 WDT清零,如果超过规定的时间不喂狗(一般在程序跑飞时),WDT定时超过,就会给出一个复位信号到MCU,使MCU复位。防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。

看门狗分硬件看门狗和软件看门狗。硬件看门狗是利用一个定时器电路,其定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零(俗称“喂狗”),因此程序正常工作时,定时器总不能溢出,也就不能产生复位信号。如果程序出现故障,不在定时周期内复位看门狗,就使得看门狗定时器溢出产生复位信号并重启系统。软件看门狗原理上一样,只是将硬件电路上的定时器用处理器的内部定时器代替,这样可以简化硬件电路设计,但在可靠性方面不如硬件定时器,比如系统内部定时器自身发生故障就无法检测到。当然也有通过双定时器相互监视,这不仅加大系统开销,也不能解决全部问题,比如中断系统故障导致定时器中断失效。

2 TX2看门狗模块

在英伟达官方文档中,我们可以看到它是支持看门狗的,参考文档《NVIDIA Tegra Linux Driver Package

在文档中,我们可以找到官方提供的示例

 int fd, ret; int timeout = 0;   /* open WDT0 device (WDT0 enables itself automatically) */ fd = open("/dev/watchdog0", O_RDWR); if(fd < 0) {     fprintf(stderr, "Open watchdog device failed!\n");     return -1;  } /* WDT0 is counting now,check the default timeout value */ ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeout); if(ret) {     fprintf(stderr, "Get watchdog timeout value failed!\n");     return -1;  } fprintf(stdout, "Watchdog timeout value: %d\n", timeout);   /* set new timeout value 60s */ /* Note the value should be within [5, 1000] */ timeout = 60; ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeout); if(ret) {     fprintf(stderr, "Set watchdog timeout value failed!\n");     return -1; } fprintf(stdout, "New watchdog timeout value: %d\n", timeout);     /*Kick WDT0, this should be running periodically */ ret = ioctl(fd, WDIOC_KEEPALIVE, NULL); if(ret) {     fprintf(stderr, "Kick watchdog failed!\n");     return -1; }

3 测试程序

封装一下,测试代码如下

 #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <sys/ioctl.h> #include <linux/watchdog.h>   static int api_watchdog_fd = -1;   int api_watchdog_open(const char * watchdog_device) { 	int ret = -1; 	if (api_watchdog_fd >= 0){ 		fprintf(stderr, "Watchdog already opened\n"); 		return ret; 	} 	api_watchdog_fd = open(watchdog_device, O_RDWR); 	if (api_watchdog_fd < 0){ 		fprintf(stderr, "Could not open %s: %s\n", watchdog_device, strerror(errno)); 		return api_watchdog_fd; 	} 	return api_watchdog_fd; }   int api_watchdog_hwfeed(void) { 	int ret = -1; 	if (api_watchdog_fd < 0){ 		fprintf(stderr, "Watchdog must be opened first!\n"); 		return ret; 	} 	ret = ioctl(api_watchdog_fd, WDIOC_KEEPALIVE, NULL); 	if (ret < 0){ 		fprintf(stderr, "Could not pat watchdog: %s\n", strerror(errno)); 	} 	return ret; }   int api_watchdog_init(const char *pcDevice) { 	printf("Open WatchDog\n"); 	int ret = 0; 	ret = api_watchdog_open("/dev/watchdog"); 	if(ret < 0){ 		return ret; 	} 	ret = api_watchdog_hwfeed(); 	return ret; }   int main(int argc, char **argv) { 	int ret = 0; 	ret = api_watchdog_init("/dev/watchdog"); 	if(ret < 0) { 		fprintf(stderr, "Could not init watchdog: %s\n", strerror(errno)); 	} 	while(1) 	{ 		ret = api_watchdog_hwfeed(); 		if(ret < 0) { 			return ret; 		} 		sleep(1); 	} }

4 API接口

WDT看门狗模块主要调用了ioctl接口,关于该函数的具体参数和调用方法,参考该链接

文章来源: https://blog.csdn.net/zong596568821xp/article/details/92625488
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!