RTOS中如何使用看门狗 ---- 以RT-thread为例

Nimat ·
更新时间:2024-09-21
· 760 次阅读

When given the choice between being right or being kind, choose kind.
当你要在正确和善良之间做选择的时候,选择善良。
一、 在RTOS使用看门狗的策略

在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称“看门狗”(watchdog)。”
看门狗通常是一个定时器,定时器定时到预定时间就会产生复位信号让单片机复位。要想避免看门狗复位单片机,要及时“喂狗”(恢复定时器初始值),也就是说只要程序能正常运行,就能及时喂狗,避免复位。反之,若程序跑飞,则无法及时喂狗,导致单片机能够复位,解决了程序跑飞的问题。

1.1、回顾裸机中看门狗的使用

通常在裸机中编程的时候,一般都是一个大循环,采用时间片的方式去执行各种形式的任务。通常选择一个固定的时间片(比如每5ms)给看门狗喂狗,当然遇到一些可能会操作比较久的任务时,会追加一些额外的喂狗操作。

1.2、RTOS中使用看门狗

查看了网上很多关于如何在RTOS中使用看门狗的策略,其实每种策略都有其使用场景,下面主要提到的几种方式。

1、建立一个看门狗的定时任务,并将该任务定义为最低优先级。
这种方式需要保证看门狗定时器的溢出时间一般要足够长,且单片机不是经常满负荷运行。(保证CPU的使用权不是一直被高优先级的线程抢占) 2、建立一个看门狗的定时任务,并将该任务定义为最高优先级。
这种方式保证了喂狗的及时性,但是如果只有低优先级的任务死了(经历少,倒是没遇到过),这种方式下的看门狗就起不到作用。 3、多任务监测实现思路
将看门狗“喂狗”置于最高优先级,每个任务(或者某几个重要的任务)定时向看门狗任务法消息,如果看门狗任务在一定时间内收全其他任务发来的消息才喂狗。这保证了能够监测尽量多的任务。 二、RT-thread&STM32 中使用看门狗

使用STM32CubeMX来配置STM32的内部看门狗,超时时间为1000ms。
在这里插入图片描述
我们定义一个线程每200ms喂一次狗,优先级为RT_THREAD_PRIORITY_MAX-2。(这里只是举例,任务多了得仔细考虑如何喂狗)

extern IWDG_HandleTypeDef hiwdg; /* 200ms 喂一次看门狗 */ static void iwdg_control(void *parameter) { int i = 0; while(1) { rt_thread_mdelay(200); i++; /* Refresh IWDG: reload counter */ HAL_IWDG_Refresh(&hiwdg); rt_kprintf("第%d次喂狗\n",i); } } static rt_thread_t iwdg_tid = RT_NULL; int iwdg_init(void) { /* 创建电机线程*/ iwdg_tid = rt_thread_create("iwdg_thread", // 线程名字 iwdg_control, // 线程入口函数 RT_NULL, // 线程入口参数 512, // 堆栈大小, RT_THREAD_PRIORITY_MAX-2, // 线程优先级 5); // 时间片长度 /* 如果获得线程控制块,启动这个线程 */ if (iwdg_tid != RT_NULL) rt_thread_startup(iwdg_tid); return 0; } INIT_DEVICE_EXPORT(iwdg_init); // 自动初始化

效果如下:
在这里插入图片描述
接下来屏蔽喂狗操作,可以看到看门狗起作用了,单片机不断复位。

extern IWDG_HandleTypeDef hiwdg; /* 200ms 喂一次看门狗 */ static void iwdg_control(void *parameter) { int i = 0; while(1) { rt_thread_mdelay(200); i++; rt_kprintf("第%d次200ms\n",i); } } static rt_thread_t iwdg_tid = RT_NULL; int iwdg_init(void) { /* 创建电机线程*/ iwdg_tid = rt_thread_create("iwdg_thread", // 线程名字 iwdg_control, // 线程入口函数 RT_NULL, // 线程入口参数 512, // 堆栈大小, RT_THREAD_PRIORITY_MAX-2, // 线程优先级 5); // 时间片长度 /* 如果获得线程控制块,启动这个线程 */ if (iwdg_tid != RT_NULL) rt_thread_startup(iwdg_tid); return 0; } INIT_DEVICE_EXPORT(iwdg_init); // 自动初始化

可以看到每5次200ms,单片机就会重启。
在这里插入图片描述

参考资料 STM32CubeMX系列教程15:看门狗(WDG) 单片机看门狗定义及其作用分析 如何在RTOS中使用看门狗定时器? 第29章 FreeRTOS独立看门狗监测任务执行状态 M3 + MDK RTOS + 硬件看门狗 + 独立看门狗 = 随机性死机 RTOS 与看门狗的亲密合作 UC/OS-II,多任务喂狗实现 对于使用嵌入式操作系统的工程如何使用看门狗 [讨论] 大家ucos里面还用看门狗吗? 如何在RTOS中使用看门狗定时器? freertos - 在多任務環境中,給看門狗提供的策略
作者:GlYoung



rt-thread

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章