1、环境介绍
硬件:飞凌ok3568-c开发板
软件:原厂rk356x sdk
2、看门狗介绍
看门狗是一种硬件或软件机制,用于监视计算机系统的运行状态。如果系统由于某种原因停止响应(即“挂起”或“死机”),看门狗会触发一个复位信号,使系统重新启动。这在嵌入式系统和关键任务系统中尤为重要,以确保系统的高可用性和可靠性。
在硬件层面,看门狗通常是一个独立的计时器芯片,它接收来自主CPU的周期性信号(称为“喂狗”信号)。如果主CPU停止发送这些信号(即没有在规定时间内“喂狗”),看门狗就会触发复位信号。
在软件层面,看门狗可以是一个后台任务或线程,它定期检查系统的关键组件或服务的状态。如果检测到异常,软件看门狗可能会采取一系列恢复措施,如重启服务或整个系统。
3、dts配置
看门狗相关配置已经在rk3568.dtsi中开启:
wdt: watchdog@fe600000 {
compatible = "snps,dw-wdt";
reg = <0x0 0xfe600000 0x0 0x100>;
clocks = <&cru TCLK_WDT_NS>, <&cru PCLK_WDT_NS>;
clock-names = "tclk", "pclk";
interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
status = "okay";
};
4、内核配置
CONFIG_WATCHDOG=y
驱动文件在<font style="color:rgb(0,0,0);">drivers/watchdog/dw_wdt.c</font>
5、看门狗测试
5.1、命令行测试
看门狗设备节点:/dev/watchdog
# 1. 设置看门狗超时时间,这里写入除大写V以外的任意字符
echo A > /dev/watchdog
# 2. 开启定时喂狗(如果不执行这句,过一段时间,系统就会自动重启)
echo V > /dev/watchdog
5.2、应用程序测试
主要通过ioctl来设置和控制看门狗:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <linux/watchdog.h>
#define WDOG_DEV "/dev/watchdog"
int main(int argc, char **argv)
{
int fd;
int time;
int timeout = 0;
int op;
int ret;
/* 检查输入参数 */
if (argc != 2)
{
printf("usage : %s <timeout>\n", argv[0]);
printf("e.g. : %s 20\n", argv[0]);
exit(EXIT_FAILURE);
}
/* 打开设备节点,一打开看门狗就开始计时 */
fd = open(WDOG_DEV, O_RDWR);
if (0 > fd)
{
fprintf(stderr, "open error: %s: %s\n", WDOG_DEV, strerror(errno));
exit(EXIT_FAILURE);
}
/* 先关闭看门狗 */
op = WDIOS_DISABLECARD;
if (0 > ioctl(fd, WDIOC_SETOPTIONS, &op))
{
fprintf(stderr, "ioctl error: WDIOC_SETOPTIONS: %s\n", strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
timeout = atoi(argv[1]);
if (1 > timeout)
timeout = 1;
/* 设置超时时间 */
printf("watchdog timeout: %ds\n", timeout);
if (0 > ioctl(fd, WDIOC_SETTIMEOUT, &timeout))
{
fprintf(stderr, "ioctl error: WDIOC_SETTIMEOUT: %s\n", strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
/* 获取实际设置的超时时间 */
if (0 > ioctl(fd, WDIOC_GETTIMEOUT, &timeout))
{
fprintf(stderr, "ioctl error: WDIOC_SETTIMEOUT: %s\n", strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
printf("the termial watchdog timeout: %ds\n", timeout);
/* 开启看门狗 */
op = WDIOS_ENABLECARD;
if (0 > ioctl(fd, WDIOC_SETOPTIONS, &op))
{
fprintf(stderr, "ioctl error: WDIOC_SETOPTIONS: %s\n", strerror(errno));
close(fd);
exit(EXIT_FAILURE);
}
/* 计时到达前100ms喂狗 */
time = (timeout * 1000 - 100) * 1000;
while (1)
{
ret = write(fd, "\0", 1);
if (ret != 1)
break;
usleep(time);
}
/* 关闭后,将不再喂狗 */
close(fd);
return 0;
}
编译后,将程序拷贝到板卡,并执行应用程序(程序输入的超时时间只作为一个参考,并不一定就是实际设置的超时时间):
按ctrl c
退出程序后,在22s内,由于没有喂狗,系统会重启。
6、总结
嵌入式Linux学习交流群:424571391
参考文章: