一、用户代码分析1.程序等待ko加载创建字符设备- WaitAtStartup("/dev/watchdog");
- #define WAIT_MAX_COUNT 10
- static void WaitAtStartup(const char *source)
- {
- unsigned int count = 0;
- struct stat sourceInfo;
- unsigned int waitTime = 500000;
- do {
- usleep(waitTime);
- count++;
- } while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < WAIT_MAX_COUNT));
- if (count == WAIT_MAX_COUNT) {
- INIT_LOGE("wait for file:%s failed after %f.", source, WAIT_MAX_COUNT>>1);
- }
- return;
- }
程序起来等待喂狗KO加载创建/dev/watchdog 5s的时间
2.喂狗程序- int interval = 0;
- if (argc >= 2) { // Argument nums greater than or equal to 2.
- interval = atoi(argv[1]);
- }
- interval = (interval > 0) ? interval : DEFAULT_INTERVAL;
- int gap = 0;
- if (argc >= 3) { // Argument nums greater than or equal to 3.
- gap = atoi(argv[2]); // 2 second parameter.
- }
- gap = (gap > 0) ? gap : DEFAULT_GAP;
- INIT_LOGI("watchdoge started (interval %d, margin %d), fd = %dn", interval, gap, fd);
- // 两个入参之和为用户态喂狗超时时间
- int timeoutSet = interval + gap;
- int timeoutGet = 0;
- int ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeoutSet);
- if (ret) {
- INIT_LOGE("Failed to set timeout to %dn", timeoutSet);
- }
- ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeoutGet);
- if (ret) {
- INIT_LOGE("Failed to get timeoutn");
- } else {
- // 用户态设置喂狗超时时间为大于gap 用户态喂狗间隔时间为
- // 获取内核的超时间 - gap,如果小于gap 用户态喂狗超时时间为1s
- interval = (timeoutGet > gap) ? (timeoutGet - gap) : 1;
- }
- while (1) {
- ioctl(fd, WDIOC_KEEPALIVE);
- sleep(interval);
- }
- close(fd);
- fd = -1;
- return -1;
- }
二、喂狗流程
- 加载喂狗KO ——> 创建/dev/watchdog
- ——> 注册内核函数接口open,ioctl,release
- ——> 创建内核喂狗线程hidog,并以30.01s喂狗
- ——> 用户态等待/dev/watchdog创建
- ——> 设置和获取超时时间,并计算用户态喂狗时间间隔
- ——> 以计算的喂狗时间间隔喂狗
如果用户态设置的喂狗时间超过30s,那么用户态喂狗程序退出不会影响内核线程喂狗,系统不会重启。