watchdog概述

来源:互联网 发布:淘宝申请部分退款 编辑:程序博客网 时间:2024/06/05 20:11

http://blog.csdn.net/wyzxg/article/details/5579415

watchdog工作原理:

 

在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去复位看门狗,
那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以在使用有看门狗的芯片时要注意复位看门狗。

 

看门狗有硬件和软件的。常见的硬件看门狗是PCI接口和USB接口,体积很小。

 

Linux 自带了一个 watchdog 的软件程序,用于监视系统的运行,它包括一个内核 watchdog module
和一个用户空间的 watchdog 程序。

 

内核 watchdog 模块

 

通过 /dev/watchdog 这个字符设备与用户空间通信。用户空间程序一旦打开 /dev/watchdog 设备,
就会导致在内核中启动一个 1分钟的定时器,此后,用户空间程序需要保证在 1分钟之内向这个设备写入数据,每次写
操作会导致重新设定定时器。如果用户空间程序在 1分钟之内没有写操作,定时器到期会导致一次系统 reboot 操作。

 

用户空间程序可通过关闭 /dev/watchdog 来停止内核中的定时器。

 

用户空间的 watchdog 守护进程:


在用户空间,还有一个叫做 watchdog 的守护进程,它可以定期对系统进行检测,包括:

 

* Is the process table full?
* Is there enough free memory?
* Are some files accessible?
* Have some files changed within a given interval?
* Is the average work load too high?
* Has a file table overflow occurred?
* Is a process still running? The process is specified by a pid file.
* Do some IP addresses answer to ping?
* Do network interfaces receive traffic?
* Is the temperature too high? (Temperature data not always available.)
* Execute a user defined command to do arbitrary tests.

 

如果某项检测失败,则可能导致一次 soft reboot (模拟一次 shutdown 命令的执行),它还可以通过 /dev/watchdog 来触发内核 watchdog 的运行。

 

内核级”watchdog”与用户空间的”watchdog”的主要区别是,内核态的”watchdog”抗干扰能力强,运行稳定。

 

 

例子1:

 

[cpp] view plaincopyprint?
  1. /* 
  2.  * Watchdog usage. 
  3.  * Author: Serval Li 
  4.  * Date: Jun 27th, 2012 
  5.  * */  
  6. #include <stdio.h>   
  7. #include <string.h>   
  8. #include <stdlib.h>   
  9. #include <unistd.h>   
  10. #include <sys/ioctl.h>   
  11. #include <sys/types.h>   
  12. #include <sys/stat.h>   
  13. #include <fcntl.h>   
  14.   
  15. #include <signal.h>   
  16.   
  17. #include <linux/types.h>   
  18. #include <linux/watchdog.h>   
  19.   
  20. int main(void)  
  21. {  
  22.         int fd;  
  23.         int timeout, flag;  
  24.         char cmd[256];  
  25.   
  26.         if ((fd = open("/dev/watchdog", O_RDWR)) < 0) {  
  27.                 perror("");  
  28.                 exit(1);  
  29.         }  
  30.   
  31.         ioctl(fd, WDIOC_GETTIMEOUT, &timeout);  
  32.         printf("Default timeout: %d\n", timeout);  
  33.   
  34.         timeout = 12;  
  35.         printf("Set timeout to %d\n", timeout);  
  36.         ioctl(fd, WDIOC_SETTIMEOUT, &timeout);  
  37.   
  38.         ioctl(fd, WDIOC_GETTIMEOUT, &timeout);  
  39.         printf("New timeout: %d\n", timeout);  
  40.   
  41.         flag = fcntl(0, F_GETFL, 0);  
  42.         flag |= O_NONBLOCK;  
  43.         if (fcntl(0, F_SETFL, flag) < 0) {      /* fgets no-block now */  
  44.                 perror("Set stdin to non-block fails.");  
  45.                 exit(1);  
  46.         }  
  47.   
  48.         while (1) {  
  49.                 ioctl(fd, WDIOC_KEEPALIVE, 0);  
  50.                 fgets(cmd, sizeof(cmd) - 1, stdin);  
  51.                 if(strncmp(cmd, "stop", 4) == 0)  
  52.                         goto stopwd;  
  53.                 sleep(timeout / 2);  
  54.         }  
  55.   
  56. stopwd:  
  57.         write(fd, "V", 1);      /* This is "V", not "v"! */  
  58.         close(fd);  
  59.         printf("Close watchdog!");  
  60.   
  61.         return 0;  
  62. }  

 例子2:

[cpp] view plaincopyprint?
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #include <sys/types.h>   
  5. #include <sys/stat.h>   
  6. #include <unistd.h>   
  7. #include <fcntl.h>   
  8. #include <sys/ioctl.h>   
  9. #include <errno.h>   
  10. #include <sys/time.h>   
  11. #include <unistd.h>   
  12. #include <time.h>   
  13. #include <getopt.h>   
  14. #include <sys/signal.h>   
  15. #include <termios.h>   
  16.   
  17. struct watchdog_info{  
  18.     unsigned int options;   //options the card/driver supprots 19           
  19.     unsigned int firmware_version;  //firmcard version of the card  
  20.     unsigned char identity[32];     //identity of the board 21  
  21.  };  
  22.   
  23. #define WATCHDOG_IOCTL_BASE 'W'  
  24. #define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)  
  25. #define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)  
  26. #define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int) 27   
  27. #define WDIOS_DISABLECARD 0x0001        /* Turn off the watchdog timer */  
  28. #define WDIOS_ENABLECARD 0x0002 /* Turn on the watchdog timer */  
  29. #define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)  
  30. #define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)  
  31.   
  32. int Getch (void)   //无回显的从屏幕输入字符,来达到喂狗的目的  
  33.   
  34. {  
  35.   
  36.      int ch;  
  37.      struct termios oldt, newt;   //终端设备结构体  
  38.      tcgetattr(STDIN_FILENO, &oldt);   //获得终端属性  
  39.      newt = oldt;  
  40.      newt.c_lflag &= ~(ECHO|ICANON);   //设置无回显属性  
  41.      tcsetattr(STDIN_FILENO, TCSANOW, &newt);  //设置新的终端属性  
  42.      ch = getchar();   //从键盘输入一个数据   
  43.      tcsetattr(STDIN_FILENO, TCSANOW, &oldt);  //恢复终端设备初始设置  
  44.      return ch;  
  45.   
  46. }  
  47.  //suspend some seconds   
  48. int zsleep(int millisecond)  
  49.   
  50. {  
  51.      unsigned long usec;  
  52.      usec=1000*millisecond;  
  53.      usleep(usec); //睡眠usec秒   
  54. }  
  55. int Init()  
  56. {   
  57.      int fd;  
  58.      //open device file   
  59.      fd = open("/dev/watchdog",O_RDWR);   //打开看门狗设备  
  60.       if(fd < 0)  
  61.      {  
  62.          printf("device open fail\n");  
  63.          return -1;  
  64.      }  
  65.      return fd;  
  66. }  
  67.   
  68. int main(int argc,char **argv)  
  69. {  
  70.      int fd,ch;  
  71.      int i,j;  
  72.      char c;  
  73.      struct watchdog_info wi;  
  74.      fd=Init();  //打开终端看门狗设备   
  75.      //读板卡信息,但不常用   
  76.   
  77.       ioctl(fd,WDIOC_GETSUPPORT,&wi);  
  78.      printf("%d,%s\n",wi.options,wi.identity);  
  79.      //读看门狗溢出时间,默认是5s   
  80.   
  81.      //重新设置时间为10s   
  82.   
  83.      i=5;  
  84.      printf("%d\n",ioctl(fd,WDIOC_SETTIMEOUT,&i));  
  85.      //读新的设置时间   
  86.   
  87.       printf("%d\n",ioctl(fd,WDIOC_GETTIMEOUT,&i));  
  88.      printf("%d\n",i);   
  89.      //看门狗开始和停止工作,打开和关闭设备具有同样的功能  
  90.   
  91.      //关闭   
  92.       i=WDIOS_DISABLECARD;  
  93.      printf("%d\n",ioctl(fd,WDIOC_SETOPTIONS,&i));  
  94.      //打开   
  95.       i=WDIOS_ENABLECARD;  
  96.      printf("%d\n",ioctl(fd,WDIOC_SETOPTIONS,&i));  
  97.      while(1)  
  98.      {  
  99.            zsleep(100);  
  100.            if((c=Getch())!=27){  
  101.                 //输入如果不是ESC,就喂狗,否则不喂狗,到时间后系统重启  
  102.   
  103.                 ioctl(fd,WDIOC_KEEPALIVE,NULL);  
  104.                 //write(fd,NULL,1);     //同样是喂狗  
  105.   
  106.            }  
  107.      }  
  108.     close(fd);   //关闭设备   
  109.      return 0;  
  110. }  
原创粉丝点击