STM32 看门狗多线程状态监护 - 裸机使用方法

发布时间:2024年01月04日

说明:本文记录stm32看门狗的多线程监控方法,线程是rtos中的称呼,这里可以理解为各个独立循环执行的中断。这里介绍的方法可以监控多个循环当某个循环死机、卡死时都可触发看门狗复位。

测试平台:STM32F334C8T6

1.详见代码:

1.1 iwdg.h

#ifndef __IWDG_H__
#define __IWDG_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

#define  WDG_START_EN                     (1) // 看门狗:1 开启,0 关闭
#define  IWDG_TICK                     uwTick // 看门狗时钟源,这里采用 stm32的全局定时变量,默认是 1 khz,即1ms数据 +1;
#define  IWDG_REFRESH_TICK_TIME         (400) // 看门狗喂狗间隔时间,单位 ms

// 定义需要监护的线程或中断
#define WDG_REF_HRTIM1      0
#define WDG_REF_TIME2      1
#define WDG_REF_TIME3      2
#define WDG_REF_COUNT      3

extern uint8_t  iwdg_ref_d[WDG_REF_COUNT];

void MX_IWDG_Init(void);
void wdg_refresh(void);


#ifdef __cplusplus
}
#endif

#endif /* __IWDG_H__ */

1.2 iwdg.c

//看门狗复位时间:  Tout = (Prescaler * Reload) / LSIRC(看门狗时钟) = (4 * 4095)/40k = 409.5 ms

//使用说明:
//step1:调用 MX_IWDG_Init() 完成初始化;
//step2:在看门狗监护循环中调用看门狗监控喂狗函数 wdg_refresh() 注意调用间隔时间不要超过看门狗复位时间。
//step3:在各个需要喂狗的地方清零看门狗标志,如: iwdg_ref_d[WDG_REF_TIME2] = 0;

uint8_t  iwdg_ref_d[WDG_REF_COUNT] = {0};                // 看门狗监护变量,需要监护几个地方(线程)在头文件处定义;
uint32_t iwdg_count = 0;
uint32_t wdg_refresh_Last_time = 0;

IWDG_HandleTypeDef hiwdg;

/* IWDG init function */
void MX_IWDG_Init(void)
{
    hiwdg.Instance = IWDG;
    hiwdg.Init.Prescaler = IWDG_PRESCALER_8;
    hiwdg.Init.Window = 4095;
    hiwdg.Init.Reload = 4095;
    if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
    {
        Error_Handler();
    }
}

//看门狗喂狗
void wdg_refresh(void)
{
    if (IWDG_TICK - wdg_refresh_Last_time > IWDG_REFRESH_TICK_TIME)
    {
        wdg_refresh_Last_time = IWDG_TICK;
        uint8_t wdg_r = 0;
        for (int var = 0; var < WDG_REF_COUNT; ++var) //检查监护线程的喂狗状态
        {
            wdg_r = iwdg_ref_d[var] + wdg_r;
        }
        if (wdg_r == 0) //如果每个线程都有喂狗,那 wdg_r 应该为 0
        {
#if WDG_START_EN
            HAL_IWDG_Refresh(&hiwdg); // 喂狗
#endif

            for (int var = 0; var < WDG_REF_COUNT; ++var) // 初始化看门狗线程管理值
            {
                iwdg_ref_d[var] = 1;
            }
            ++iwdg_count;
        }
    }
}

文章来源:https://blog.csdn.net/yutian0606/article/details/135246870
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。