用香橙派跑图片爬虫确实很方便,但有时候香橙派会自己死机,也不知道为什么。查了下用户手册发现香橙派Zero2的其实是有一个硬件看门狗的,可以在系统挂掉以后自动重启芯片。
使用看门狗的大概的流程是打开一个叫/dev/watchdog
的设备文件,然后使用ioctl
函数配置超时时间和手动喂狗。
官方只提供了一个c语言示例程序,所以我打算用python语言来做这个看门狗,但过程不是很顺利。python里需要用到fcntl包下的ioctl方法,这个方法需要传入两个uint类型(32位)的参数。但我的数据因为第32位是1,占用了符号位,python自动给我换成了取值范围更大的类型中去了,导致死活就是传不进去fcntl.ioctl
方法,一直提示Python Overflow error: int too large to convert to C long
。
我试过很多种方法来绕过去,比如直接and 1 << 31
,或者通过数字计算来添加第32位为1,这些方法都不行,随后便放弃了python,还是改用c写。
具体的看门狗程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <time.h>
#include <getopt.h>
#include <sys/signal.h>
#include <termios.h>
#define WATCHDOG_IOCTL_BASE 'W'
#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int) //27
#define WDIOS_DISABLECARD 0x0001
#define WDIOS_ENABLECARD 0x0002
#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)
#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
int running = 1;
void ctl(int fd, unsigned int cmd, unsigned long arg)
{
int result = ioctl(fd, cmd, &arg);
if (result < 0)
printf("ioctl(%d, %ld) fails: %d\n", cmd, arg, result);
}
void signal_handler(int signal)
{
printf("signal %d\n", signal);
running = 0;
}
int main(int argc,char **argv)
{
setbuf(stdout, 0);
int fd = open("/dev/watchdog", O_RDWR);
if(fd < 0)
{
printf("fail to open watchdog\n");
return -1;
}
// listening linux signals
signal(SIGINT, signal_handler);
// enable the watchdog
ctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
// set a new timeout
ctl(fd, WDIOC_SETTIMEOUT, 10);
printf("watchdog is enabled\n");
// feed dog
while (running)
{
ctl(fd, WDIOC_KEEPALIVE, 0);
// printf("feed\n");
sleep(3);
}
// disable the watchdog
ctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD);
close(fd);
printf("watchdog is disabled\n");
return 0;
}
代码编译很简单,香橙派自带gcc,只需要gcc wdt.c -o wdt
就可以编译出可执行文件了。
程序运行后会自动启动看门狗,并会每隔3秒喂狗一次。若超过10秒没有喂狗,系统会自动重启。同时当进程收到SIGINT信号时,程序会禁用看门狗并正常退出运行。(SIGINT信号使用Ctrl+C就可以发出)
所以当系统挂掉以后,会导致这个看门狗喂狗程序停止运行,然后系统会自动重启。
另附上systemd.service文件(ExecStart需要自己修改成实际路径)
[Unit]
Description=a watchdog program for OrangePiZero2
[Service]
ExecStart=/home/orangepi/wdt/wdt
TimeoutStopSec=10
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target