当前位置: 首页 > article >正文

stm32 单片机使用 rt-thread 的syswatch 系统守护软件包

一、系统看守(syswatch)组件 介绍

系统看守(syswatch)组件 主要功能是保障实时操作系统正常运行,防止系统死机以及各种异常引起的线程阻塞,保障整个系统长期正常运行。
系统看守具备以下几种行为模式:
1、系统崩溃或硬件异常导致系统失去调度时,执行 系统复位 恢复系统正常运行。
2、当有异常导致某些线程长时间阻塞时,可根据用户的配置实施 系统复位 / 杀掉阻塞线程 / 重启阻塞线程 的方式恢复系统正常运行。

原理介绍
系统看守(syswatch)组件 使用实时操作系统中允许的最高优先级作为看守线程的优先级,保障看守线程不会被阻塞,同时看守线程由看门狗提供看护,保障看守线程正常运行。系统看守通过 线程调度回调接口 监测线程的调度情况,当检测到有线程发生异常阻塞时,开始检测和确认具体哪个线程发生了异常阻塞,最后根据异常解决模式执行 系统复位 / 杀掉阻塞线程 / 重启阻塞线程 清除异常,使系统恢复正常运行。

配置参数说明
在这里插入图片描述
注意事项
1、syswatch 依赖于看门狗设备而工作,使用本组件时请确认已注册了看门狗设备。
2、syswatch 全权管理看门狗,请不要在其它线程中使用和操作看门狗。
3、syswatch 提供了3种异常解决模式,请根据实际需要配置适合的工作模式。
4、syswatch_set_event_hook 提供用户安装事件回调函数,以便针对重要事件发生时进行一些必要处理,如系统复位前须对重要数据进行保存时,可设置回调函数完成相应处理,如不需要可不设置。

二、开发配置

2.1 开发环境

基于 env 进行配置开发。RT-Thread Env 工具包括配置器和包管理器,用来对内核和组件的功能进行配置,对组件进行自由裁剪,对线上软件包进行管理,使得系统以搭积木的方式进行构建,简单方便。
硬件:基于野火 stm32f407 开发板
软件:rt-thread 4.1.1 版本,基于 stm32f407-atk-explorer bsp包

2.2 时钟配置

stm32f407-atk-explorer bsp包的外部晶振是8MHZ,野火 stm32f407 开发板外部晶振是25MHZ,需要先修改配置系统时钟。
参考野火教程:
在这里插入图片描述
系统时钟的计算:SYSCLK=PLLCLK=HSE/m*n/p
HSE 使用 25M,参数 m 设置为 25,所以需要修改系统时钟的时候只需要修改参数 n 和 p 即可,SYSCLK=PLLCLK=HSE/m*n/p。

在这里插入图片描述
在这里插入图片描述
系统时钟配置完整代码如下:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

  /**Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /**Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE
                              |RCC_OSCILLATORTYPE_LSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /**Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
}

2.3 开启看门狗

在这里插入图片描述
Kconfig 文件 相关
在这里插入图片描述

    config BSP_USING_WDT
        bool "Enable Watchdog Timer"
        select RT_USING_WDT
        default n

开始之后,下面的选项会自动勾选。
在这里插入图片描述
Kconfig 文件 相关
在这里插入图片描述

config RT_USING_WDT
    bool "Using Watch Dog device drivers"
    default n

重新编译,下载到开发板,查看设备
在这里插入图片描述
使用的是独立看门狗(IWDG)
在这里插入图片描述

区分独立看门狗(IWDG)和窗口看门狗(WWDG)

2.4 syswatch 组件

开启 syswatch 组件
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

下载软件包
在这里插入图片描述
编译
在这里插入图片描述

三、测试

下载到开发板,运行如下
在这里插入图片描述

查看线程
在这里插入图片描述
配置的异常解决模式是2,可知可重启异常线程。
在这里插入图片描述

测试代码,编写异常线程:

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-11-06     SummerGift   first version
 * 2018-11-19     flybreak     add stm32f407-atk-explorer bsp
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        5

static rt_thread_t tid1 = RT_NULL;

/* defined the LED0 pin: PF6 */
#define LED0_PIN    GET_PIN(F, 6)
#define LED1_PIN    GET_PIN(C, 6)


/* 线程 1 的入口函数 */
static void thread1_entry(void *parameter)
{
    rt_kprintf("hello world\r\n");
    while(1)
    {
    }
}

int main(void)
{
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
    
    
 /* 创建线程 1,名称是 thread1,入口是 thread1_entry*/
    tid1 = rt_thread_create("thread1",
                            thread1_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);

    /* 如果获得线程控制块,启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);
    
    while (1)
    {
        rt_pin_write(LED0_PIN, PIN_HIGH);
        rt_pin_write(LED1_PIN, PIN_HIGH);
        rt_thread_mdelay(500);
        rt_pin_write(LED0_PIN, PIN_LOW);
        rt_pin_write(LED1_PIN, PIN_LOW);
        rt_thread_mdelay(500);
    }
}

测试结果,异常线程可重新重启
在这里插入图片描述

参考:
https://gitee.com/RT-Thread-Mirror/rt-thread-syswatch
STM32库开发实战指南——基于野火霸天虎开发板


http://www.kler.cn/a/354148.html

相关文章:

  • 【论文阅读笔记】IC-Light
  • 【ES6复习笔记】模板字符串(3)
  • 【Rust自学】6.3. 控制流运算符-match
  • Mac mini m4安装PD和Crack和关闭SIP
  • JAVA HTTP压缩数据
  • JavaScript中的Set、Map、WeakSet和WeakMap
  • 27.第二阶段x86游戏实战2-遍历周围NPC跳出递归循环
  • Unity3D Shader预热生成详解
  • Vue 之 插件与组件的区别
  • appium启动hbuild打包的apk异常解决
  • Raid盘类型及其特点
  • Flask框架@app.route中的路径及其视图函数
  • 如何有效参与机器人顶会?——周易教授PRE-IROS 2024分享
  • 【数据分析】影响系数 =(今日量-昨日量)/(今日总量-昨日总量)
  • git 操作暂存区命令用法大全
  • ChatGPT 现已登陆 Windows 平台
  • html和css实现页面
  • 文件加密技术解析:守护敏感信息的第一道防线
  • 技术分享:A-23OH型树脂在汽车涂装废溶剂回收中的应用
  • YOLOv11改进策略【卷积层】| SPD-Conv 针对小目标和低分辨率图像的检测任务
  • Django一分钟:DRF中序列化器字段source参数的作用
  • H5对接海康硬盘录像机视频简单说明
  • mac git管理(新)
  • 【前端】Matter:物体的高级控制
  • selenium获取cookie的方法
  • T3矩阵看功率