|
|
@@ -1,11 +1,3 @@
|
|
|
-
|
|
|
-/*
|
|
|
- * it87_wdt_test.c - IT87 看门狗驱动测试程序
|
|
|
- *
|
|
|
- * 编译: gcc -o it87_wdt_test it87_wdt_test.c -Wall
|
|
|
- * 运行: sudo ./it87_wdt_test [选项]
|
|
|
- */
|
|
|
-
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
@@ -17,178 +9,178 @@
|
|
|
#include <linux/watchdog.h>
|
|
|
|
|
|
#define WATCHDOG_DEV "/dev/watchdog"
|
|
|
-#define DEFAULT_KEEPALIVE 5 // 默认喂狗间隔(秒)
|
|
|
+#define DEFAULT_KEEPALIVE 5
|
|
|
|
|
|
static int wdt_fd = -1;
|
|
|
static volatile int running = 1;
|
|
|
-static int test_mode = 0; // 0=正常喂狗, 1=停止喂狗测试重启, 2=触发喂狗后退出
|
|
|
+static int test_mode = 0; // 0=normal dog feeding, 1=stop dog feeding test restart, 2=exit after triggering dog feeding
|
|
|
|
|
|
-/* 信号处理:优雅退出 */
|
|
|
+/* Signal Processing: Graceful Exit */
|
|
|
static void signal_handler(int sig)
|
|
|
{
|
|
|
- printf("\n[%d] 收到信号 %d,准备退出...\n", getpid(), sig);
|
|
|
+ printf("\n[%d] Receive signal %d,exit...\n", getpid(), sig);
|
|
|
running = 0;
|
|
|
}
|
|
|
|
|
|
-/* 打印使用说明 */
|
|
|
+/* Print instructions */
|
|
|
static void print_usage(const char *prog)
|
|
|
{
|
|
|
- printf("IT87 看门狗驱动测试程序\n\n");
|
|
|
- printf("用法: %s [选项]\n\n", prog);
|
|
|
- printf("选项:\n");
|
|
|
- printf(" -h 显示帮助\n");
|
|
|
- printf(" -t <秒> 设置喂狗间隔 (默认: %d秒)\n", DEFAULT_KEEPALIVE);
|
|
|
- printf(" -T <秒> 设置看门狗超时时间 (需要驱动支持)\n");
|
|
|
- printf(" -m 测试模式: 启动后停止喂狗,测试系统重启\n");
|
|
|
- printf(" -e 测试模式: 喂狗一次后立即退出(测试 nowayout)\n");
|
|
|
- printf(" -i 获取看门狗信息\n");
|
|
|
- printf(" -c 启用魔法关闭字符 'V'\n");
|
|
|
- printf(" -d 禁用看门狗(如果支持)\n");
|
|
|
- printf("\n示例:\n");
|
|
|
- printf(" %s # 正常测试,每5秒喂狗\n", prog);
|
|
|
- printf(" %s -t 2 # 每2秒喂狗一次\n", prog);
|
|
|
- printf(" %s -m -t 10 # 10秒后停止喂狗,系统应该重启\n", prog);
|
|
|
- printf(" %s -e # 测试 nowayout 模式\n", prog);
|
|
|
- printf("\n警告: 使用 -m 或 -e 选项会导致系统重启!\n");
|
|
|
+ printf("IT87 Watchdog Driver Test Program\n\n");
|
|
|
+ printf("Usage: %s [Option]\n\n", prog);
|
|
|
+ printf("Option:\n");
|
|
|
+ printf(" -h Show Help\n");
|
|
|
+ printf(" -t <second> Set dog feeding interval (Default: %dsecond)\n", DEFAULT_KEEPALIVE);
|
|
|
+ printf(" -T <second> Set the watchdog timeout (driver support required)\n");
|
|
|
+ printf(" -m Test mode: Stop feeding the dog after startup, test system reboot\n");
|
|
|
+ printf(" -e Test mode: Exit immediately after feeding the dog once (testing nowayout)\n");
|
|
|
+ printf(" -i Get watchdog information\n");
|
|
|
+ printf(" -c Enable magic to close characters 'V'\n");
|
|
|
+ printf(" -d Disable the watchdog (if supported)\n");
|
|
|
+ printf("\nExample:\n");
|
|
|
+ printf(" %s # Normal test, feed the dog every 5 seconds\n", prog);
|
|
|
+ printf(" %s -t 2 # Feed the dog every 2 seconds\n", prog);
|
|
|
+ printf(" %s -m -t 10 # Stop feeding the dog after 10 seconds, the system should restart\n", prog);
|
|
|
+ printf(" %s -e # Test nowayout mode\n", prog);
|
|
|
+ printf("\nWarning: Using the -m or -e option will cause the system to restart!\n");
|
|
|
}
|
|
|
|
|
|
-/* 获取看门狗信息 */
|
|
|
+/* Get watchdog information */
|
|
|
static void get_watchdog_info(int fd)
|
|
|
{
|
|
|
struct watchdog_info info;
|
|
|
|
|
|
if (ioctl(fd, WDIOC_GETSUPPORT, &info) < 0) {
|
|
|
- perror("WDIOC_GETSUPPORT 失败");
|
|
|
+ perror("WDIOC_GETSUPPORT Failure");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- printf("\n========== 看门狗信息 ==========\n");
|
|
|
- printf("标识: %s\n", info.identity);
|
|
|
- printf("固件版本: %u\n", info.firmware_version);
|
|
|
- printf("选项支持:\n");
|
|
|
- if (info.options & WDIOF_OVERHEAT) printf(" - 过热检测\n");
|
|
|
- if (info.options & WDIOF_FANFAULT) printf(" - 风扇故障\n");
|
|
|
- if (info.options & WDIOF_EXTERN1) printf(" - 外部信号1\n");
|
|
|
- if (info.options & WDIOF_EXTERN2) printf(" - 外部信号2\n");
|
|
|
- if (info.options & WDIOF_POWERUNDER) printf(" - 电源不足\n");
|
|
|
- if (info.options & WDIOF_CARDRESET) printf(" - 卡片重启\n");
|
|
|
- if (info.options & WDIOF_POWEROVER) printf(" - 电源过载\n");
|
|
|
- if (info.options & WDIOF_SETTIMEOUT) printf(" - 设置超时时间 ✓\n");
|
|
|
- if (info.options & WDIOF_MAGICCLOSE) printf(" - 魔法关闭 ✓\n");
|
|
|
- if (info.options & WDIOF_PRETIMEOUT) printf(" - 预超时\n");
|
|
|
- if (info.options & WDIOF_ALARMONLY) printf(" - 仅报警\n");
|
|
|
- if (info.options & WDIOF_KEEPALIVEPING) printf(" - 喂狗支持 ✓\n");
|
|
|
+ printf("\n========== Watchdog Information ==========\n");
|
|
|
+ printf("Logo: %s\n", info.identity);
|
|
|
+ printf("Firmware Version: %u\n", info.firmware_version);
|
|
|
+ printf("Option support:\n");
|
|
|
+ if (info.options & WDIOF_OVERHEAT) printf(" - Overheat Detection\n");
|
|
|
+ if (info.options & WDIOF_FANFAULT) printf(" - Fan malfunction\n");
|
|
|
+ if (info.options & WDIOF_EXTERN1) printf(" - External signal1\n");
|
|
|
+ if (info.options & WDIOF_EXTERN2) printf(" - External signal2\n");
|
|
|
+ if (info.options & WDIOF_POWERUNDER) printf(" - Insufficient power\n");
|
|
|
+ if (info.options & WDIOF_CARDRESET) printf(" - Card restart\n");
|
|
|
+ if (info.options & WDIOF_POWEROVER) printf(" - Power overload\n");
|
|
|
+ if (info.options & WDIOF_SETTIMEOUT) printf(" - Set timeout ✓\n");
|
|
|
+ if (info.options & WDIOF_MAGICCLOSE) printf(" - Magic Off ✓\n");
|
|
|
+ if (info.options & WDIOF_PRETIMEOUT) printf(" - Pre-timeout\n");
|
|
|
+ if (info.options & WDIOF_ALARMONLY) printf(" - Alarm only\n");
|
|
|
+ if (info.options & WDIOF_KEEPALIVEPING) printf(" - Support feeding the dog ✓\n");
|
|
|
printf("================================\n\n");
|
|
|
}
|
|
|
|
|
|
-/* 获取当前超时时间 */
|
|
|
+/* Get the current timeout */
|
|
|
static int get_timeout(int fd)
|
|
|
{
|
|
|
int timeout = 0;
|
|
|
if (ioctl(fd, WDIOC_GETTIMEOUT, &timeout) < 0) {
|
|
|
- perror("WDIOC_GETTIMEOUT 失败");
|
|
|
+ perror("WDIOC_GETTIMEOUT fail");
|
|
|
return -1;
|
|
|
}
|
|
|
return timeout;
|
|
|
}
|
|
|
|
|
|
-/* 设置超时时间 */
|
|
|
+/* Set timeout */
|
|
|
static int set_timeout(int fd, int timeout)
|
|
|
{
|
|
|
- printf("设置超时时间为 %d 秒...\n", timeout);
|
|
|
+ printf("Set the timeout to %d second...\n", timeout);
|
|
|
if (ioctl(fd, WDIOC_SETTIMEOUT, &timeout) < 0) {
|
|
|
- perror("WDIOC_SETTIMEOUT 失败");
|
|
|
+ perror("WDIOC_SETTIMEOUT fail");
|
|
|
return -1;
|
|
|
}
|
|
|
- printf("实际设置的超时时间: %d 秒\n", timeout);
|
|
|
+ printf("The actual timeout set: %d second\n", timeout);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* 喂狗(keepalive) */
|
|
|
+/* (keepalive) */
|
|
|
static int keepalive(int fd)
|
|
|
{
|
|
|
int dummy;
|
|
|
if (ioctl(fd, WDIOC_KEEPALIVE, &dummy) < 0) {
|
|
|
- perror("WDIOC_KEEPALIVE 失败");
|
|
|
+ perror("WDIOC_KEEPALIVE fail");
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* 禁用看门狗 */
|
|
|
+/* Disable the watchdog */
|
|
|
static int disable_watchdog(int fd)
|
|
|
{
|
|
|
- printf("尝试禁用看门狗...\n");
|
|
|
- /* 方法1: 魔法关闭字符 */
|
|
|
+ printf("Try to disable the watchdog...\n");
|
|
|
+ /* Method 1: Magic Close Character */
|
|
|
if (write(fd, "V", 1) != 1) {
|
|
|
- perror("魔法关闭字符写入失败");
|
|
|
+ perror("Magic failed to write character");
|
|
|
return -1;
|
|
|
}
|
|
|
- printf("已发送魔法关闭字符 'V'\n");
|
|
|
+ printf("Magic shutdown character sent 'V'\n");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/* 主测试循环 */
|
|
|
+/* Main Test Loop */
|
|
|
static void test_loop(int fd, int keepalive_interval, int mode)
|
|
|
{
|
|
|
int count = 0;
|
|
|
time_t start_time = time(NULL);
|
|
|
|
|
|
- printf("\n========== 开始测试 ==========\n");
|
|
|
+ printf("\n========== Start testing ==========\n");
|
|
|
printf("PID: %d\n", getpid());
|
|
|
- printf("喂狗间隔: %d 秒\n", keepalive_interval);
|
|
|
- printf("当前超时设置: %d 秒\n", get_timeout(fd));
|
|
|
+ printf("Keepalive interval: %d seconds\n", keepalive_interval);
|
|
|
+ printf("Current timeout setting: %d seconds\n", get_timeout(fd));
|
|
|
|
|
|
if (mode == 1) {
|
|
|
- printf("\n⚠️ 测试模式: 将在 %d 秒后停止喂狗,系统应该重启!\n",
|
|
|
+ printf("\n⚠️ Test mode: Will stop feeding the dog after %d seconds, the system should restart!\n",
|
|
|
keepalive_interval * 3);
|
|
|
} else if (mode == 2) {
|
|
|
- printf("\n⚠️ 测试模式: 喂狗一次后立即退出,测试 nowayout\n");
|
|
|
+ printf("\n⚠️ Test mode: Exit immediately after feeding the dog once (testing nowayout)\n");
|
|
|
} else {
|
|
|
- printf("\n正常模式: 按 Ctrl+C 停止\n");
|
|
|
+ printf("\nNormal mode: Press Ctrl+C to stop\n");
|
|
|
}
|
|
|
printf("==============================\n\n");
|
|
|
|
|
|
- /* 第一次喂狗(启动看门狗) */
|
|
|
+ /* First keepalive (start watchdog) */
|
|
|
if (keepalive(fd) < 0) {
|
|
|
- fprintf(stderr, "初始喂狗失败\n");
|
|
|
+ fprintf(stderr, "Initial keepalive failed\n");
|
|
|
return;
|
|
|
}
|
|
|
- printf("[%3d] 初始喂狗完成,看门狗已启动\n", count++);
|
|
|
+ printf("[%3d] Initial keepalive completed, watchdog started\n", count++);
|
|
|
|
|
|
if (mode == 2) {
|
|
|
- /* 测试模式: 立即退出 */
|
|
|
- printf("立即退出,如果 nowayout=1,系统将在超时后重启\n");
|
|
|
+ /* Test mode: exit immediately */
|
|
|
+ printf("Exit immediately, if nowayout=1, the system will restart after timeout\n");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- /* 主循环 */
|
|
|
+ /* Main loop */
|
|
|
while (running) {
|
|
|
sleep(keepalive_interval);
|
|
|
|
|
|
if (!running)
|
|
|
break;
|
|
|
|
|
|
- /* 测试模式1: 在指定次数后停止喂狗 */
|
|
|
+ /* Test mode 1: stop feeding after specified times */
|
|
|
if (mode == 1 && count >= 3) {
|
|
|
- printf("\n⚠️ 故意停止喂狗!系统应在 %d 秒后重启...\n",
|
|
|
+ printf("\n⚠️ Intentionally stop feeding the dog! The system should restart in %d seconds...\n",
|
|
|
get_timeout(fd));
|
|
|
- printf("等待重启中(按 Ctrl+C 可尝试中断)...\n");
|
|
|
+ printf("Waiting for restart (Ctrl+C can try to interrupt)...\n");
|
|
|
|
|
|
- /* 继续循环但不喂狗 */
|
|
|
+ /* Continue loop but don't feed */
|
|
|
while (1) {
|
|
|
sleep(1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* 正常喂狗 */
|
|
|
+ /* Normal keepalive */
|
|
|
if (keepalive(fd) < 0) {
|
|
|
- fprintf(stderr, "喂狗失败\n");
|
|
|
+ fprintf(stderr, "Keepalive failed\n");
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
time_t elapsed = time(NULL) - start_time;
|
|
|
- printf("[%3d] 已喂狗 (运行时间: %ld 秒)\n", count++, elapsed);
|
|
|
+ printf("[%3d] Keepalive fed (running time: %ld seconds)\n", count++, elapsed);
|
|
|
fflush(stdout);
|
|
|
}
|
|
|
}
|
|
|
@@ -202,7 +194,7 @@ int main(int argc, char *argv[])
|
|
|
int magic_close = 0;
|
|
|
int disable = 0;
|
|
|
|
|
|
- /* 解析命令行参数 */
|
|
|
+ /* Parse command line arguments */
|
|
|
while ((opt = getopt(argc, argv, "ht:T:meicd")) != -1) {
|
|
|
switch (opt) {
|
|
|
case 'h':
|
|
|
@@ -211,7 +203,7 @@ int main(int argc, char *argv[])
|
|
|
case 't':
|
|
|
keepalive_interval = atoi(optarg);
|
|
|
if (keepalive_interval < 1) {
|
|
|
- fprintf(stderr, "错误: 喂狗间隔必须 >= 1 秒\n");
|
|
|
+ fprintf(stderr, "Error: keepalive interval must be >= 1 second\n");
|
|
|
return 1;
|
|
|
}
|
|
|
break;
|
|
|
@@ -219,10 +211,10 @@ int main(int argc, char *argv[])
|
|
|
new_timeout = atoi(optarg);
|
|
|
break;
|
|
|
case 'm':
|
|
|
- test_mode = 1; // 停止喂狗测试重启
|
|
|
+ test_mode = 1; // stop feeding test restart
|
|
|
break;
|
|
|
case 'e':
|
|
|
- test_mode = 2; // 立即退出测试 nowayout
|
|
|
+ test_mode = 2; // exit immediately test nowayout
|
|
|
break;
|
|
|
case 'i':
|
|
|
show_info = 1;
|
|
|
@@ -239,30 +231,30 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* 注册信号处理 */
|
|
|
+ /* Register signal handler */
|
|
|
signal(SIGINT, signal_handler);
|
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
|
|
- printf("IT87 看门狗测试程序\n");
|
|
|
- printf("打开设备: %s\n", WATCHDOG_DEV);
|
|
|
+ printf("IT87 Watchdog Test Program\n");
|
|
|
+ printf("Opening device: %s\n", WATCHDOG_DEV);
|
|
|
|
|
|
- /* 打开看门狗设备 */
|
|
|
- /* O_CLOEXEC: 防止子进程继承,但看门狗通常需要保持打开 */
|
|
|
+ /* Open watchdog device */
|
|
|
+ /* O_CLOEXEC: prevent child process inheritance, but watchdog usually needs to stay open */
|
|
|
wdt_fd = open(WATCHDOG_DEV, O_WRONLY);
|
|
|
if (wdt_fd < 0) {
|
|
|
- perror("无法打开看门狗设备(需要 root 权限?)");
|
|
|
- fprintf(stderr, "提示: 尝试 sudo %s\n", argv[0]);
|
|
|
+ perror("Cannot open watchdog device (need root privileges?)");
|
|
|
+ fprintf(stderr, "Hint: try sudo %s\n", argv[0]);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- printf("设备打开成功 (fd=%d)\n", wdt_fd);
|
|
|
+ printf("Device opened successfully (fd=%d)\n", wdt_fd);
|
|
|
|
|
|
- /* 获取信息 */
|
|
|
+ /* Get information */
|
|
|
if (show_info) {
|
|
|
get_watchdog_info(wdt_fd);
|
|
|
}
|
|
|
|
|
|
- /* 设置新的超时时间 */
|
|
|
+ /* Set new timeout */
|
|
|
if (new_timeout > 0) {
|
|
|
if (set_timeout(wdt_fd, new_timeout) < 0) {
|
|
|
close(wdt_fd);
|
|
|
@@ -270,37 +262,37 @@ int main(int argc, char *argv[])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* 显示当前超时 */
|
|
|
+ /* Show current timeout */
|
|
|
int current_timeout = get_timeout(wdt_fd);
|
|
|
if (current_timeout > 0) {
|
|
|
- printf("当前看门狗超时: %d 秒\n", current_timeout);
|
|
|
+ printf("Current watchdog timeout: %d seconds\n", current_timeout);
|
|
|
}
|
|
|
|
|
|
- /* 禁用看门狗 */
|
|
|
+ /* Disable watchdog */
|
|
|
if (disable) {
|
|
|
if (disable_watchdog(wdt_fd) < 0) {
|
|
|
- fprintf(stderr, "禁用看门狗失败(可能 nowayout=1)\n");
|
|
|
+ fprintf(stderr, "Failed to disable watchdog (nowayout may be 1)\n");
|
|
|
}
|
|
|
close(wdt_fd);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- /* 主测试循环 */
|
|
|
+ /* Main test loop */
|
|
|
test_loop(wdt_fd, keepalive_interval, test_mode);
|
|
|
|
|
|
- /* 清理 */
|
|
|
- printf("\n关闭看门狗设备...\n");
|
|
|
+ /* Cleanup */
|
|
|
+ printf("\nClosing watchdog device...\n");
|
|
|
|
|
|
if (magic_close) {
|
|
|
- /* 尝试魔法关闭 */
|
|
|
- printf("发送魔法关闭字符 'V'...\n");
|
|
|
+ /* Try magic close */
|
|
|
+ printf("Sending magic close character 'V'...\n");
|
|
|
if (write(wdt_fd, "V", 1) != 1) {
|
|
|
- perror("魔法关闭失败");
|
|
|
+ perror("Magic close failed");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
close(wdt_fd);
|
|
|
- printf("测试程序结束\n");
|
|
|
+ printf("Test program ended\n");
|
|
|
|
|
|
return 0;
|
|
|
}
|