赞
踩
说明:本文记录基于RT-Thread 的 stm32看门狗的多线程监控方法,这里介绍的方法让看门狗线程监控多个线程,任何被监控的线程的卡死都可以触发看门狗复位。
测试平台:STM32 ,RT-Thread 3.1.5
- #ifndef __iwdg_H
- #define __iwdg_H
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /* Includes ---------------------------------*/
- #include "stm32g4xx.h"
- #include "stm32g4xx_hal.h"
- #include "stm32g4xx_ll_pwr.h"
- #include "rtthread.h"
-
- extern IWDG_HandleTypeDef hiwdg;
-
- void MX_IWDG_Init(void);
- void iwdg_thread_entry(void* parameter);
- void sys_iwdg_app(rt_thread_t thread);
- int sys_iwdg_thread_init(void);
-
- #ifdef __cplusplus
- }
- #endif
- #endif /*__ iwdg_H */
- /* 使用范例 */
- #if 0
- /* step:1 打开看门狗相关头文件宏 stm32g4xx_hal_conf.h 文件的 #define HAL_IWDG_MODULE_ENABLED */
- #define HAL_IWDG_MODULE_ENABLED
-
- /* step:2 打开看门狗初始化函数定义,定义看门狗的溢出时间 */
- MX_IWDG_Init();
-
- /* step:3 系统看门狗管理线程初始化 sys_iwdg_thread_init() */
- sys_iwdg_thread_init();
-
- /* step:4 在需要看护的线程中调用这个函数即可,在线程中循环调用完成线程喂狗 */
- sys_iwdg_app(rt_thread_self());
-
- #endif
-
- /* Includes ------------------------------------------------------------------*/
- #include "iwdg.h"
- #include <stdlib.h>
- #include "stdio.h"
- #include <string.h>
-
- /* 系统线程管理看门狗配置参数 --------------------------------------------------*/
- #define SYS_IWDG_DATA_NUM (10) /* 系统看门狗管理线程数量 */
- #define SYS_IWDG_TIMEOUT (2000) /* 系统看门狗超时时间 :单位 ms,注意必须小于 IWDG_TIMOUT */
- #define SYS_IWDG_TIME (100) /* 系统看门狗超循环监测间隔时间 :单位 ms,注意必须小于 IWDG_TIMOUT */
- #define IWDG_PRINTF (1) /* 系统看门狗超信息打印,1开启,0关闭 */
-
- #define IWDG_TIMOUT (5000) /* 看门狗重启时间,单位 ms,范围(8 - 32760)ms */
- #define IWDG_LSI_RC (32000) /* 看门狗时钟,根据芯片确定, 单位 Hz, */
- #define IWDG_RELOAD (uint32_t)(IWDG_TIMOUT * IWDG_LSI_RC / (256 * 1000)) /* 看门狗重载值,自动计算 */
-
-
- /* IWDG 看门狗管理线程配置*/
- #ifndef IWDG_THREAD_THREAD_PRIORITY_LEVEL
- #define IWDG_THREAD_THREAD_PRIORITY_LEVEL (1) /* 线程优先级 */
- #endif
-
- #ifndef IWDG_THREAD_THREAD_STACKSIZE
- #define IWDG_THREAD_THREAD_STACKSIZE (512) /* 线程堆栈 */
- #endif
-
- #ifndef IWDG_THREAD_THREAD_SLOT_DURATION
- #define IWDG_THREAD_THREAD_SLOT_DURATION (20) /* 线程时间片 */
- #endif
-
- typedef struct
- {
- uint32_t thread; /* 看门狗线程句柄指针 */
- uint32_t tick_time; /* 线程喂狗时间 */
- }sys_iwdg_data_t;
-
- static sys_iwdg_data_t sys_iwdg_data[SYS_IWDG_DATA_NUM]; /* 系统看门狗管理变量 */
-
-
- IWDG_HandleTypeDef hiwdg;
-
- /* IWDG init function 看门狗初始化函数
- * LSI_RC 看门狗独立时钟 32K
- * .看门狗延时计算 (1/32000) * Prescaler * Reload
- * */
-
- void MX_IWDG_Init(void)
- {
- hiwdg.Instance = IWDG;
- hiwdg.Init.Prescaler = IWDG_PRESCALER_256; /* IWDG计数器时钟预分频器 */
- hiwdg.Init.Window = 4095; /* IWDG看门狗窗口值,0~4095 */
- hiwdg.Init.Reload = IWDG_RELOAD; /* IWDG看门狗重置值,0~4095,重置后会自减,减到0时MCU会复位。 */
- if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
- {
- // Error_Handler();
- }
- }
-
-
- /* 线程注册和喂狗函数,如果线程没注册过就自动注册并喂狗 */
- void sys_iwdg_app(rt_thread_t thread)
- {
- /* 查找线程 指针存储位置 */
- for (uint16_t var = 0; var < SYS_IWDG_DATA_NUM; ++var)
- {
- if (sys_iwdg_data[var].thread == 0)
- {
- sys_iwdg_data[var].thread = (uint32_t)thread;
- sys_iwdg_data[var].tick_time = rt_tick_get(); /* 存储线程喂狗时间 */
- break;
- }
- else if (sys_iwdg_data[var].thread == (uint32_t)thread)
- {
- sys_iwdg_data[var].tick_time = rt_tick_get(); /* 存储线程喂狗时间 */
- break;
- }
- }
- }
-
-
- /* 获取时间差 (差值为ms级别 由RT_TICK_PER_SECOND决定的) */
- uint32_t get_time_difference_ms(uint32_t now_tick, uint32_t last_tick)
- {
- if (now_tick >= last_tick)
- {
- return (now_tick - last_tick);
- }
- else
- {
- return (UINT32_MAX - last_tick + now_tick + 1);
- }
- }
-
- /* 看门狗管理线程 */
- void sys_iwdg_thread_entry(void* parameter)
- {
- uint8_t timeout = 0;
- memset(sys_iwdg_data, 0, sizeof(sys_iwdg_data_t));
- while (1)
- {
- for (uint16_t var = 0; var < SYS_IWDG_DATA_NUM; ++var)
- {
- if (sys_iwdg_data[var].thread != 0)
- {
- if (get_time_difference_ms(rt_tick_get(), sys_iwdg_data[var].tick_time) > SYS_IWDG_TIMEOUT)
- {
- #if IWDG_PRINTF
- printf("iwdg_thread_entry():thread timeout : No:%d ,thread_add = 0x%08X ,name = %s\r\n",
- var,sys_iwdg_data[var].thread, ((rt_thread_t) sys_iwdg_data[var].thread)->name);
- #endif
- timeout = 1;
- }
- }
-
- }
-
- if (timeout == 0)
- {
- HAL_IWDG_Refresh(&hiwdg);
- }
-
- rt_thread_mdelay(SYS_IWDG_TIME);
- }
- }
-
- static rt_thread_t sys_iwdg_thread = RT_NULL;
-
- /* 系统看门狗初始化线程 */
- int sys_iwdg_thread_init(void)
- {
- MX_IWDG_Init();
-
- sys_iwdg_thread = rt_thread_create("sys_iwdg_thread", sys_iwdg_thread_entry, RT_NULL, IWDG_THREAD_THREAD_STACKSIZE, IWDG_THREAD_THREAD_PRIORITY_LEVEL, IWDG_THREAD_THREAD_SLOT_DURATION);
- if (sys_iwdg_thread != RT_NULL)
- {
- rt_thread_startup(sys_iwdg_thread);
- }
- else
- {
- #if IWDG_PRINTF
- printf("sys_iwdg_thread_entry():create thread fail!\n\n");
- #endif
- return -1;
- }
- return 1;
- }
-
-
-
- /* USER CODE END 1 */
-
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。