当前位置:   article > 正文

STM32 看门狗多线程状态监护 - 基于RT-Thread应用 - 源码_看门狗监测代码

看门狗监测代码

说明:本文记录基于RT-Thread 的 stm32看门狗的多线程监控方法,这里介绍的方法让看门狗线程监控多个线程,任何被监控的线程的卡死都可以触发看门狗复位。

测试平台:STM32 ,RT-Thread 3.1.5

1.详见代码:

1.1 iwdg.h

  1. #ifndef __iwdg_H
  2. #define __iwdg_H
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. /* Includes ---------------------------------*/
  7. #include "stm32g4xx.h"
  8. #include "stm32g4xx_hal.h"
  9. #include "stm32g4xx_ll_pwr.h"
  10. #include "rtthread.h"
  11. extern IWDG_HandleTypeDef hiwdg;
  12. void MX_IWDG_Init(void);
  13. void iwdg_thread_entry(void* parameter);
  14. void sys_iwdg_app(rt_thread_t thread);
  15. int sys_iwdg_thread_init(void);
  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif /*__ iwdg_H */

1.2 iwdg.c

  1. /* 使用范例 */
  2. #if 0
  3. /* step:1 打开看门狗相关头文件宏 stm32g4xx_hal_conf.h 文件的 #define HAL_IWDG_MODULE_ENABLED */
  4. #define HAL_IWDG_MODULE_ENABLED
  5. /* step:2 打开看门狗初始化函数定义,定义看门狗的溢出时间 */
  6. MX_IWDG_Init();
  7. /* step:3 系统看门狗管理线程初始化 sys_iwdg_thread_init() */
  8. sys_iwdg_thread_init();
  9. /* step:4 在需要看护的线程中调用这个函数即可,在线程中循环调用完成线程喂狗 */
  10. sys_iwdg_app(rt_thread_self());
  11. #endif
  12. /* Includes ------------------------------------------------------------------*/
  13. #include "iwdg.h"
  14. #include <stdlib.h>
  15. #include "stdio.h"
  16. #include <string.h>
  17. /* 系统线程管理看门狗配置参数 --------------------------------------------------*/
  18. #define SYS_IWDG_DATA_NUM (10) /* 系统看门狗管理线程数量 */
  19. #define SYS_IWDG_TIMEOUT (2000) /* 系统看门狗超时时间 :单位 ms,注意必须小于 IWDG_TIMOUT */
  20. #define SYS_IWDG_TIME (100) /* 系统看门狗超循环监测间隔时间 :单位 ms,注意必须小于 IWDG_TIMOUT */
  21. #define IWDG_PRINTF (1) /* 系统看门狗超信息打印,1开启,0关闭 */
  22. #define IWDG_TIMOUT (5000) /* 看门狗重启时间,单位 ms,范围(8 - 32760)ms */
  23. #define IWDG_LSI_RC (32000) /* 看门狗时钟,根据芯片确定, 单位 Hz, */
  24. #define IWDG_RELOAD (uint32_t)(IWDG_TIMOUT * IWDG_LSI_RC / (256 * 1000)) /* 看门狗重载值,自动计算 */
  25. /* IWDG 看门狗管理线程配置*/
  26. #ifndef IWDG_THREAD_THREAD_PRIORITY_LEVEL
  27. #define IWDG_THREAD_THREAD_PRIORITY_LEVEL (1) /* 线程优先级 */
  28. #endif
  29. #ifndef IWDG_THREAD_THREAD_STACKSIZE
  30. #define IWDG_THREAD_THREAD_STACKSIZE (512) /* 线程堆栈 */
  31. #endif
  32. #ifndef IWDG_THREAD_THREAD_SLOT_DURATION
  33. #define IWDG_THREAD_THREAD_SLOT_DURATION (20) /* 线程时间片 */
  34. #endif
  35. typedef struct
  36. {
  37. uint32_t thread; /* 看门狗线程句柄指针 */
  38. uint32_t tick_time; /* 线程喂狗时间 */
  39. }sys_iwdg_data_t;
  40. static sys_iwdg_data_t sys_iwdg_data[SYS_IWDG_DATA_NUM]; /* 系统看门狗管理变量 */
  41. IWDG_HandleTypeDef hiwdg;
  42. /* IWDG init function 看门狗初始化函数
  43. * LSI_RC 看门狗独立时钟 32K
  44. * .看门狗延时计算 (1/32000) * Prescaler * Reload
  45. * */
  46. void MX_IWDG_Init(void)
  47. {
  48. hiwdg.Instance = IWDG;
  49. hiwdg.Init.Prescaler = IWDG_PRESCALER_256; /* IWDG计数器时钟预分频器 */
  50. hiwdg.Init.Window = 4095; /* IWDG看门狗窗口值,0~4095 */
  51. hiwdg.Init.Reload = IWDG_RELOAD; /* IWDG看门狗重置值,0~4095,重置后会自减,减到0时MCU会复位。 */
  52. if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  53. {
  54. // Error_Handler();
  55. }
  56. }
  57. /* 线程注册和喂狗函数,如果线程没注册过就自动注册并喂狗 */
  58. void sys_iwdg_app(rt_thread_t thread)
  59. {
  60. /* 查找线程 指针存储位置 */
  61. for (uint16_t var = 0; var < SYS_IWDG_DATA_NUM; ++var)
  62. {
  63. if (sys_iwdg_data[var].thread == 0)
  64. {
  65. sys_iwdg_data[var].thread = (uint32_t)thread;
  66. sys_iwdg_data[var].tick_time = rt_tick_get(); /* 存储线程喂狗时间 */
  67. break;
  68. }
  69. else if (sys_iwdg_data[var].thread == (uint32_t)thread)
  70. {
  71. sys_iwdg_data[var].tick_time = rt_tick_get(); /* 存储线程喂狗时间 */
  72. break;
  73. }
  74. }
  75. }
  76. /* 获取时间差 (差值为ms级别 由RT_TICK_PER_SECOND决定的) */
  77. uint32_t get_time_difference_ms(uint32_t now_tick, uint32_t last_tick)
  78. {
  79. if (now_tick >= last_tick)
  80. {
  81. return (now_tick - last_tick);
  82. }
  83. else
  84. {
  85. return (UINT32_MAX - last_tick + now_tick + 1);
  86. }
  87. }
  88. /* 看门狗管理线程 */
  89. void sys_iwdg_thread_entry(void* parameter)
  90. {
  91. uint8_t timeout = 0;
  92. memset(sys_iwdg_data, 0, sizeof(sys_iwdg_data_t));
  93. while (1)
  94. {
  95. for (uint16_t var = 0; var < SYS_IWDG_DATA_NUM; ++var)
  96. {
  97. if (sys_iwdg_data[var].thread != 0)
  98. {
  99. if (get_time_difference_ms(rt_tick_get(), sys_iwdg_data[var].tick_time) > SYS_IWDG_TIMEOUT)
  100. {
  101. #if IWDG_PRINTF
  102. printf("iwdg_thread_entry():thread timeout : No:%d ,thread_add = 0x%08X ,name = %s\r\n",
  103. var,sys_iwdg_data[var].thread, ((rt_thread_t) sys_iwdg_data[var].thread)->name);
  104. #endif
  105. timeout = 1;
  106. }
  107. }
  108. }
  109. if (timeout == 0)
  110. {
  111. HAL_IWDG_Refresh(&hiwdg);
  112. }
  113. rt_thread_mdelay(SYS_IWDG_TIME);
  114. }
  115. }
  116. static rt_thread_t sys_iwdg_thread = RT_NULL;
  117. /* 系统看门狗初始化线程 */
  118. int sys_iwdg_thread_init(void)
  119. {
  120. MX_IWDG_Init();
  121. 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);
  122. if (sys_iwdg_thread != RT_NULL)
  123. {
  124. rt_thread_startup(sys_iwdg_thread);
  125. }
  126. else
  127. {
  128. #if IWDG_PRINTF
  129. printf("sys_iwdg_thread_entry():create thread fail!\n\n");
  130. #endif
  131. return -1;
  132. }
  133. return 1;
  134. }
  135. /* USER CODE END 1 */
  136. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/713173
推荐阅读
相关标签
  

闽ICP备14008679号