看门狗应用编程-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

news2024/12/23 14:29:19

看门狗应用编程

在这里插入图片描述

看门狗应用编程介绍

看门狗定时器的基本概念

  • 看门狗是一个可以在一定时间内被复位/重置的计数器

  • 如果在规定时间内没有复位,看门狗计时器溢出会对CPU产生复位信号使系统重启

  • 有些看门狗可以只产生中断信号而不会使系统复位

I.MX6UL/I.MX6ULL SoC 中的看门狗定时器

  • 集成了两个看门狗定时器:WDOG1 和 WDOG2

  • WDOG2 用于安全目的

  • WDOG1 是一个普通的看门狗,支持产生中断信号和复位CPU

Linux 系统中的看门狗设备节点

  • 注册的看门狗外设在 /dev/ 目录下生成设备节点,通常命名为 watchdogX(X为数字编号)

  • 例如 /dev/watchdog0、/dev/watchdog1

  • 这些设备节点用于控制看门狗外设

默认看门狗设备节点

  • /dev/watchdog0 对应 I.MX6U 的 WDOG1

  • 系统中可能注册多个看门狗设备,/dev/watchdog 是系统默认的看门狗设备节点

  • 通常 /dev/watchdog 代表系统默认的看门狗设备,即 watchdog0

应用层控制看门狗的方法

  • 通过 ioctl() 函数控制看门狗

  • 需要包含 <linux/watchdog.h> 头文件

  • 头文件中定义了多种 ioctl 指令宏,对应不同的操作

    • #define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
      #define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int)
      #define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int)
      #define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int)
      #define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)
      #define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
      #define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
      #define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int)
      #define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
      #define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int)
      #define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int
  • 常用的 ioctl 指令宏

看门狗应用编程流程

打开设备

  • 在调用 ioctl()函数之前,需要先打开看门狗设备得到文件描述符

    • int fd;

fd = open(“/dev/watchdog”, “O_RDWR”);
if (0 > fd)
fprintf(stderr, “open error: %s: %s\n”, “/dev/watchdog”, strerror(errno));

获取设备支持哪些功能:WDIOC_GETSUPPORT

  • 调用 ioctl() 函数来获取功能信息

    • ioctl(int fd, WDIOC_GETSUPPORT, struct watchdog_info *info);

    • fd:文件描述符

    • WDIOC_GETSUPPORT:指令宏,获取设备的信息

    • info:指向 struct watchdog_info 的指针

  • struct watchdog_info 结构体

    • struct watchdog_info {
      __u32 options; /* Options the card/driver supports /
      _u32 firmware_version; /
      Firmware version of the card /
      __u8 identity[32]; /
      Identity of the board */
      }

    • options:记录设备支持的功能或选项

      • #define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat /
        #define WDIOF_FANFAULT 0x0002 /
        Fan failed /
        #define WDIOF_EXTERN1 0x0004 /
        External relay 1 /
        #define WDIOF_EXTERN2 0x0008 /
        External relay 2 /
        #define WDIOF_POWERUNDER 0x0010 /
        Power bad/power fault /
        #define WDIOF_CARDRESET 0x0020 /
        Card previously reset the CPU /
        #define WDIOF_POWEROVER 0x0040 /
        Power over voltage /
        #define WDIOF_SETTIMEOUT 0x0080 /
        Set timeout (in seconds) /
        #define WDIOF_MAGICCLOSE 0x0100 /
        Supports magic close char /
        #define WDIOF_PRETIMEOUT 0x0200 /
        Pretimeout (in seconds), get/set /
        #define WDIOF_ALARMONLY 0x0400 /
        Watchdog triggers a management or other external alarm
        not a reboot /
        #define WDIOF_KEEPALIVEPING 0x8000 /
        Keep alive ping reply */

      • 常见的 options 值

        • WDIOF_SETTIMEOUT:设备支持设置超时时间

        • WDIOF_KEEPALIVEPING:设备支持“喂狗”操作(重置看门狗计时器)

    • firmware_version:记录设备的固件版本号

    • identity:描述性的字符串

  • 使用示例

    • struct watchdog_info info;
      if (0 > ioctl(fd, WDIOC_GETSUPPORT, &info)) {
      fprintf(stderr, “ioctl error: WDIOC_GETSUPPORT: %s\n”, strerror(errno));
      return -1;
      }
      printf(“identity: %s\n”, info.identity);
      printf(“version: %u\n”, info.firmware_version);
      if (0 == (WDIOF_KEEPALIVEPING & info.options))
      printf(“设备不支持喂狗操作\n”);
      if (0 == (WDIOF_SETTIMEOUT & info.options))
      printf(“设备不支持设置超时时间\n”);

获取/设置超时时间:WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT

  • 获取超时时间

    • 使用指令:WDIOC_GETTIMEOUT

    • 功能:获取设备当前设置的超时时间

    • ioctl(int fd, WDIOC_GETTIMEOUT, int *timeout);

    • timeout:指向一个整数的指针,用于存储获取的超时时间(单位:秒)

  • 设置超时时间

    • 使用指令:WDIOC_SETTIMEOUT

    • 功能:设置看门狗的超时时间

    • ioctl(int fd, WDIOC_SETTIMEOUT, int *timeout);

    • timeout:指向一个整数的指针,包含要设置的超时时间(单位:秒)

  • 超时时间限制

    • 设置超时时间不得超过设备的最大值,否则 ioctl() 调用将失败
  • 使用示例

    • int timeout;

/* 获取超时时间 */
if (0 > ioctl(fd, WDIOC_GETTIMEOUT, &timeout)) {
fprintf(stderr, “ioctl error: WDIOC_GETTIMEOUT: %s\n”, strerror(errno));
return -1;
}

printf(“current timeout: %ds\n”, timeout);

/* 设置超时时间 */
timeout = 10; //10 秒钟
if (0 > ioctl(fd, WDIOC_SETTIMEOUT, &timeout)) {
fprintf(stderr, “ioctl error: WDIOC_SETTIMEOUT: %s\n”, strerror(errno));
return -1;
}

开启/关闭看门狗:WDIOC_SETOPTIONS

  • 开启看门狗计时

    • 设置好超时时间后,可以开启看门狗计时

    • 使用指令:WDIOC_SETOPTIONS

  • 停止看门狗计时

    • 同样使用指令:WDIOC_SETOPTIONS
  • 调用方式

    • ioctl(int fd, WDIOC_SETOPTIONS, int *option);

    • option:指向一个 int 类型变量的指针,用于控制开启或停止看门狗计时

      • #define WDIOS_DISABLECARD 0x0001 /* Turn off the watchdog timer /
        #define WDIOS_ENABLECARD 0x0002 /
        Turn on the watchdog timer */
  • 使用示例

    • int option = WDIOS_ENABLECARD; // 开启看门狗计时
      // int option = WDIOS_DISABLECARD; // 停止看门狗计时
      if (0 > ioctl(fd, WDIOC_SETOPTIONS, &option)) {
      fprintf(stderr, “ioctl error: WDIOC_SETOPTIONS: %s\n”, strerror(errno));
      return -1;
      }
  • 注意事项

    • 当调用 open() 打开看门狗设备时,即使程序中没有显式开启看门狗计时器,当 close() 关闭设备时,看门狗会自动启动

    • 因此,在打开设备后,需要立即使用 WDIOC_SETOPTIONS 指令停止看门狗计时器,完成所有设置后再开启看门狗计时器

喂狗:WDIOC_KEEPALIVE

  • 看门狗计时器启动后喂狗的必要性

    • 启动看门狗计时器后,需要在设定的超时时间之前进行“喂狗”操作

    • 如果未在超时前喂狗,计时器溢出将导致系统复位或产生中断信号

  • 喂狗的指令

    • 使用指令:WDIOC_KEEPALIVE

    • 作用:重置看门狗计时器,防止系统复位或产生中断信号

  • 调用方式

    • ioctl(int fd, WDIOC_KEEPALIVE, NULL);

    • fd:看门狗设备的文件描述符

    • WDIOC_KEEPALIVE:喂狗指令宏

    • NULL:指示不需要额外的参数

  • 使用示例

    • if (0 > ioctl(fd, WDIOC_KEEPALIVE, NULL)) {
      fprintf(stderr, “ioctl error: WDIOC_KEEPALIVE: %s\n”, strerror(errno));
      }

看门狗应用编程实战

#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[])
{
    struct watchdog_info info;   // 看门狗信息结构体
    int timeout;    // 超时时间变量
    int time;   // 喂狗间隔时间变量
    int fd; // 文件描述符
    int op; // 操作选项变量

    if (2 != argc) {
        fprintf(stderr, "usage: %s <timeout>\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("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);
    }

    /* 开启看门狗计时器 */
    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);
    }

    /* 喂狗 */
    time = (timeout * 1000 - 100) * 1000;//喂狗时间设置us微秒、在超时时间到来前100ms喂狗
    for ( ; ; ) {

        usleep(time);
        ioctl(fd, WDIOC_KEEPALIVE, NULL);
    }
}

大致流程与上一级内容一致,实现了看门狗计时器的启动、停止、超时时间设置以及喂狗操作,确保系统在正常工作时不会因为超时导致复位重启

在开发板测试

看门狗默认已经被其他功能使用,需要其手动关闭

  • 打开/etc/init.d/watchdog.sh 文件,在开头加个 exit 0 将整个文件注释掉,然后开发板重新启动,再执行程序

执行程序后,看门狗计时器自动启动,并持续进行喂狗操作。当程序被终止(如通过 Ctrl + C)而未停止看门狗计时器时,计时器会溢出导致系统重启

  • 计时器溢出系统重启

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何减少内存碎片的产生——页

文章目录 1 页的设计目的2 进程块和主存块的对应关系3 页、页框、页表3.1 页&#xff08;Page&#xff09;3.2 页框&#xff08;Page Frame&#xff09;3.3 页表&#xff08;Page Table&#xff09; 4 逻辑地址到物理地址的转换4.1 转换过程4.2 具体示例4.3 图示 参考资料封面 …

C语言程序设计25

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.2 分析下面程序的运行结果&#xff0c;然后上机验证。 代码&#xff1a; //《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 //习题2.2 分析下面程序的运行结果&#xff0c;然后上机验证。#inc…

【C语言篇】操作符详解(下篇)

文章目录 操作符详解&#xff08;下篇&#xff09;前言条件操作符移位操作符左移操作符右移操作符 位操作符下标引用操作符函数调用操作符 操作符的属性&#xff1a;优先级和结合性优先级结合性表达式求值整形提升算术转换 操作符详解&#xff08;下篇&#xff09; 前言 操作…

JavaScript基础——JavaScript常见语句(判断语句、循环语句、控制流语句)

JavaScript提供了丰富的语句来控制程序的执行流程&#xff0c;包括用于条件判断的if、switch和三元运算符&#xff0c;以及用于循环的for、while、do...while、for...in和for...of。此外&#xff0c;还有控制流语句如break、continue和return。 判断语句 if 语句 if 语句&…

C/C++开发,opencv轮廓提取实现

一、cv::findContours轮廓提取函数 1.1 cv::findContours函数简介 cv::findContours 函数是用于从二值图像&#xff08;灰度图&#xff09;中检索轮廓。这个函数在OpenCV的不同版本中参数可能有所不同&#xff0c;但基本概念保持一致。特别是在OpenCV 3.x和4.x版本中&#xff…

贪吃蛇(使用QT)

贪吃蛇小游戏 一.项目介绍**[贪吃蛇项目地址](https://gitee.com/strandingzy/QT/tree/zyy/snake)**界面一&#xff1a;游戏大厅界面二&#xff1a;关卡选择界面界面三&#xff1a;游戏界面 二.项目实现2.1 游戏大厅2.2关卡选择界面2.3 游戏房间2.3.1 封装贪吃蛇数据结构2.3.2 …

如何通过谷歌外链快速增加网站流量?

利用谷歌外链提升流量的方法非常直接&#xff0c;但实际上&#xff0c;外链影响的是关键词排名&#xff0c;关键词排名提升了&#xff0c;自然就会有流量&#xff0c;所以谷歌外链不是直接能提升网站流量&#xff0c;而是间接的&#xff0c;下面&#xff0c;我会详细介绍几种有…

验收测试:确保软件符合业务需求和合同要求

目录 前言1. 验收测试的概念1.1 用户验收测试&#xff08;UAT&#xff09;1.2 操作验收测试&#xff08;OAT&#xff09; 2. 验收测试的主要作用2.1 确认业务需求的满足2.2 验证合同要求的实现2.3 提升用户信心 3. 验收测试在整个测试中的地位3.1 测试的最后一道关卡3.2 用户与…

niushop逻辑漏洞

niushop逻辑漏洞 安装环境 这里控制不了 抓包在数据包中可以改数据

非线性系统稳定控制器设及案例仿真(s-function函数)

目录 前沿一、案例11. 系统模型 二、案例21. 系统模型2. 稳定性分析3. 仿真(包含代码)1. 仿真效果2. 仿真结果3. 仿真剖析4. 仿真图与代码 前沿 定义一个系统 x ˙ f ( x , u ) \dot{x} f(x,u) x˙f(x,u), 其中 x x x 为状态变量&#xff0c; u u u 为系统输入&#xff0c…

跨平台终端工具Tabby安装配置与远程ssh连接Linux_ubuntu详细教程

文章目录 前言1. Tabby下载安装2. Tabby相关配置3. Tabby简单操作4. ssh连接Linux4.1 ubuntu系统安装ssh4.2 Tabby远程ssh连接ubuntu 5. 安装内网穿透工具5.1 创建公网地址5.2 使用公网地址远程ssh连接 6. 配置固定公网地址 前言 今天和大家分享一下如何在Windows系统使用Tabb…

构建LVS负载均衡群集

构建LVS负载均衡群集 实验环境实验环境 201:客户端 101:调度器 (需要用到2个网卡) 102:web 103:web 104:NFS存储 101:(添加一个网卡) 2 [root@localhost ~]# cd /etc/sysconfig/network-scripts/ 3 4 //查看另一个网卡的名字ens36 5 [root@localhost network-scrip…

人工智能深度学习系列—深度学习中的相似性追求:Triplet Loss 全解析

文章目录 1. 背景介绍2. Loss计算公式3. 使用场景4. 代码样例5. 总结 1. 背景介绍 在机器学习和模式识别领域&#xff0c;相似性度量是核心问题之一。Triplet Loss&#xff0c;作为一种特殊的损失函数&#xff0c;被设计用来学习数据的相对距离&#xff0c;从而使得相似样本更…

5.C_Demo_排序

冒泡排序法 原理&#xff1a; 依次比较相邻的两个元素&#xff0c;如果顺序错误就交换。 思路&#xff1a; 这种方法&#xff0c;显然需要很多轮才能完成&#xff0c;每一轮只能排序一个最大值或最小值(第一层for)&#xff0c;将全部的数据排序完成&#xff0c;需要很多轮(第…

第三期书生大模型实战营之书生大模型全链路开源开放体系

一. Introduction 大模型是发展通用人工智能的重要途经 二. 开源历程以及InternLM2 2024年1月17日 InternLM2 2开源 三. 书生浦语2.0的主要亮点 3.1 超长上下文 3.2 综合性能全面提升 3.3 优秀的对话和创作体验 3.4 工具调用能力整体升级 3.5 突出的数理能力和实用的…

Among Us 私服的制作之路

文章目录 Among Us 私服的制作之路这游戏通常包括以下核心元素&#xff1a;角色设定&#xff1a;游戏机制&#xff1a;游戏界面&#xff1a; 第四步&#xff1a;添加社交特性第五&#xff1a;测试与优化方面 十分基础的框架(Web)注意事项 Among Us 私服的制作之路 作者正在准备…

嵌入式:简单的UI框架

1&#xff1a;UI框架简介 除了服务框架外&#xff0c;我们还需要对外显示UI&#xff0c;所以我们就需要一个UI的框架&#xff0c;跟服务框架一样&#xff0c;不用这个UI框架我们也是可以实现&#xff0c;但是这样每个人写的UI都会有差异&#xff0c;需要的事件&#xff0c;数据…

牛客JS题(二十)判断斐波那契数组

注释很详细&#xff0c;直接上代码 涉及知识点&#xff1a; 循环判断斐波那契数列组递归判断斐波那契数列组合法性判断 题干&#xff1a; 我的答案 <!DOCTYPE html> <html><head><meta charset"utf-8" /></head><body><scrip…

嵌入式数据库 sqlite3

数据库文件与普通文件区别: 1.普通文件对数据管理(增删改查)效率低 2.数据库对数据管理效率高,使用方便 常用数据库: 1.关系型数据库 将复杂的数据结构简化为二维表格形式 大型:Oracle、DB2 中型:MySql、SQLServer 小型:Sqlite …

c# .net core项目角色授权机制

前言 角色授权机制是确保应用程序安全性的重要组成部分,它允许开发者根据用户的角色来限制对应用程序中不同资源的访问。 基本概念: 角色授权基于用户角色的访问控制,即根据用户所属的角色来决定其能够访问的资源或执行的操作。在.NET Core中,这通常与身份认证(Authent…