企业网站的制作哪家好,html5网页设计工具,瑞安网站建设优化,企业网站建设的可行性分析看门狗应用编程 看门狗应用编程介绍
看门狗定时器的基本概念 看门狗是一个可以在一定时间内被复位/重置的计数器 如果在规定时间内没有复位#xff0c;看门狗计时器溢出会对CPU产生复位信号使系统重启 有些看门狗可以只产生中断信号而不会使系统复位
I.MX6UL/I.MX6ULL So…看门狗应用编程 看门狗应用编程介绍
看门狗定时器的基本概念 看门狗是一个可以在一定时间内被复位/重置的计数器 如果在规定时间内没有复位看门狗计时器溢出会对CPU产生复位信号使系统重启 有些看门狗可以只产生中断信号而不会使系统复位
I.MX6UL/I.MX6ULL SoC 中的看门狗定时器 集成了两个看门狗定时器WDOG1 和 WDOG2 WDOG2 用于安全目的 WDOG1 是一个普通的看门狗支持产生中断信号和复位CPU
Linux 系统中的看门狗设备节点 注册的看门狗外设在 /dev/ 目录下生成设备节点通常命名为 watchdogXX为数字编号 例如 /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/watchdogint 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而未停止看门狗计时器时计时器会溢出导致系统重启 计时器溢出系统重启