一般来说,看门狗有两种,一种软件一种硬件。
1 软件看门狗
软件就是一个进程,设置一段时间就要收到一个信号,如果没有收到,则自动重启。
有以下三个步骤:
初始化:系统启动时,初始化软件看门狗定时器,并设置超时时间。
喂狗:系统正常运行过程中,定期重置定时器(称为“喂狗”)。
超时处理:如果系统因故障未能在超时时间内“喂狗”,看门狗超时处理程序会被触发,通常执行系统重启操作。
下面是个例子:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#define TIMEOUT 5 // 超时时间(秒)
volatile sig_atomic_t watchdog_flag = 0;
void watchdog_handler(int signum) {
if (signum == SIGALRM) {
fprintf(stderr, "Watchdog timeout! System reset required.\n");
exit(EXIT_FAILURE);
}
}
void* watchdog_thread(void* arg) {
while (1) {
sleep(TIMEOUT);
if (watchdog_flag == 0) {
raise(SIGALRM); // 超时,触发信号处理程序
} else {
watchdog_flag = 0; // 重置标志
}
}
}
void start_watchdog() {
pthread_t thread;
struct sigaction sa;
sa.sa_handler = watchdog_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
pthread_create(&thread, NULL, watchdog_thread, NULL);
pthread_detach(thread);
}
void reset_watchdog() {
watchdog_flag = 1;
}
int main() {
start_watchdog();
while (1) {
sleep(2);
printf("System is running.\n");
reset_watchdog(); // 定期“喂狗”
}
return 0;
}
2 硬件看门狗
硬件看门狗是通过专用硬件实现的监控机制。它通常是一个独立的硬件模块,相对来说稳定性和可靠性更好。
举两个例子
Arduino Watchdog Timer
调用里面的wdt接口,设置看门狗。
#include <avr/wdt.h>
void setup() {
wdt_enable(WDTO_8S); // 设置看门狗定时器,8秒超时
}
void loop() {
// 正常运行代码
delay(1000);
wdt_reset(); // 定期“喂狗”
}
2 Raspberry Pi
树莓派也支持硬件看门狗
sudo apt-get install watchdog
sudo systemctl enable watchdog
sudo systemctl start watchdog
之后编辑配置文件 /etc/watchdog.conf 以启用和配置硬件看门狗。看配置可以看出,基本上就是系统资源耗尽的时候就会重启。
watchdog-device = /dev/watchdog
watchdog-timeout = 15
max-load-1 = 24
interface = wlan0
min-memory = 1
allocatable-memory = 1
也可以配置监控某一个进程或者服务
pidfile = /var/run/myservice.pid
3 小结
硬件看门狗不占用系统资源,通过独立的硬件模块实现,不依赖系统的正常运行,在系统严重故障时依然有效。
一般来说,在可靠性要求较高的关键任务系统中,硬件看门狗是首选,因为它能在系统严重故障时确保系统自动恢复。在非关键任务系统或需要灵活定制的场景中,软件看门狗是一个更方便的选择。