FreeRTOS(独立看门狗监测任务执行与低功耗Tickless模式)

news2025/1/22 19:36:46

资料来源于硬件家园:资料汇总 - FreeRTOS实时操作系统课程(多任务管理)

目录

一、独立看门狗介绍

二、看门狗监测多任务执行思路

1、监测目标

2、监测方案

3、应用注意事项

三、看门狗监测多任务编程

1、STM32cubeMX配置

 2、代码编写

四、低功耗Tickless模式

1、Tickless模式介绍

2、Tickless模式配置

3、Tickless模式编程

一、独立看门狗介绍

二、看门狗监测多任务执行思路

1、监测目标

① 监测系统死机

② 监测任务执行

2、监测方案

说明:

①、监测任务通过独立看门狗监测自身,如果长时间得不到执行,看门狗将复位系统;

②、监测任务通过事件标志监控其它任务,如果任一任务长时间得不到执行,看门狗将复位系统;

③、监测任务收到全部被监测任务发来的事件标志后,才进行喂狗。

3、应用注意事项

①、监测任务优先级设置最高,以便及时喂狗

②、监测任务与被监测任务均不可以挂起或删除,否则,无法及时喂狗导致系统复位

③、喂狗时间由被监测任务的最大发送事件标志间隔时间确定,并且留有足够裕量

④、考虑事件标志只有低24位可用,被监测任务最多24个,足够使用

三、看门狗监测多任务编程

1、STM32cubeMX配置

监控任务优先级需要设置最高。以便喂狗

 2、代码编写

①设置事件位

/* USER CODE BEGIN PD */
#define BIT_Task01_EVENT	(EventBits_t)(0x0001 << 0)
#define BIT_Task02_EVENT	(EventBits_t)(0x0001 << 1)
#define BIT_Task03_EVENT	(EventBits_t)(0x0001 << 2)
#define BIT_Task04_EVENT	(EventBits_t)(0x0001 << 3)
#define BIT_TaskAll_EVENT BIT_Task01_EVENT | BIT_Task02_EVENT | BIT_Task03_EVENT | BIT_Task04_EVENT
/* USER CODE END PD */

②创建事件

  /* USER CODE BEGIN Init */
	MyEvent01Handle = xEventGroupCreate();//创建事件
  /* USER CODE END Init */

③监测任务

void IWDG_Monitor_Task(void const * argument)
{
  /* USER CODE BEGIN IWDG_Monitor_Task */
	EventBits_t xEvent;
	const TickType_t xTicksToWait = 6000 / portTICK_PERIOD_MS;//设置等待时间

	/* Infinite loop */
	for(;;)
	{
		xEvent = xEventGroupWaitBits(
				MyEvent01Handle,//事件句柄
				BIT_TaskAll_EVENT,//事件
				pdTRUE,//退出时清除事件位
				pdTRUE,//逻辑与,满足所有事件
				xTicksToWait//等待时间
		);
		if((xEvent&(BIT_TaskAll_EVENT)) == (BIT_TaskAll_EVENT))
		{
			sprintf(buff,"%s \r\n","喂狗,监测任务与被监测任务均正常执行");
			HAL_UART_Transmit(&huart2, (uint8_t*)buff,strlen(buff), HAL_MAX_DELAY);
			HAL_IWDG_Refresh(&hiwdg);
		}
		else
		{

		}
	}
  /* USER CODE END IWDG_Monitor_Task */
}

④被监测任务

void StartTask01(void const * argument)
{
  /* USER CODE BEGIN StartTask01 */
  /* Infinite loop */
  for(;;)
  {
	    osDelay(1000);
		xEventGroupSetBits(MyEvent01Handle,BIT_Task01_EVENT);
  }
  /* USER CODE END StartTask01 */
}

void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
	    osDelay(2000);
			xEventGroupSetBits(MyEvent01Handle,BIT_Task02_EVENT);
  }
  /* USER CODE END StartTask02 */
}

void StartTask03(void const * argument)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
  for(;;)
  {
	    osDelay(3000);
			xEventGroupSetBits(MyEvent01Handle,BIT_Task03_EVENT);
  }
  /* USER CODE END StartTask03 */
}

void StartTask04(void const * argument)
{
  /* USER CODE BEGIN StartTask04 */
  /* Infinite loop */
  for(;;)
  {
	    osDelay(4000);
			xEventGroupSetBits(MyEvent01Handle,BIT_Task04_EVENT);
  }
  /* USER CODE END StartTask04 */
}

四、低功耗Tickless模式

①电池类产品,一般要求低功耗设计,比如农业物联网的节点采集设备

②低功耗设计,除了MCU,软件,  硬件设计同等重要

③Tickless模式主要针对睡眠模式,当然,也可以自行使用停机模式,待机模式

1、Tickless模式介绍

Tickless 低功耗机制是当前小型 RTOS 所采用的通用低功耗方法,比如FreeRTOS,RTX 和 uCOS-III等。仅从字母上看,Tick 是滴答时钟的意思,less 是 Tick 的后缀,表示较少的,整体看就是表示减少滴答时钟节拍运行

在FreeRTOS系统中,当用户任务都被挂起或者阻塞时,最低优先级的空闲任务会得到执行。那么 STM32 支持的低功耗模式就可以放在空闲任务里面实现。为了实现低功耗最优设计,我们还不能直接把睡眠模式放在空闲任务就可以了。由于Tick中断停止,将导致无法及时运行阻塞超时的任务,进入空闲任务后,首先要计算可以执行低功耗的最大时间,也就是求出下一个要执行的高优先级任务还剩多少时间。然后就是把低功耗的唤醒时间设置为这个求出的时间(其实就是重载Systick),如果没有其它中断或事件唤醒STM32,到时间后Systick中断会将STM32唤醒,继续执行任务。

这个就是所谓的 Tickless 模式。从上面的讲解中可以看出,实现Tickless模式最麻烦的是计算低功耗可以执行的时间。这个难题,FreeRTOS 已为我们做好。

2、Tickless模式配置

① 将宏定义configUSE_TICKLESS_IDLE设置为1即可

② 配置 configEXPECTED_IDLE_TIME_BEFORE_SLEEP,只有当系统可运行于低功耗模式的时钟节拍数大于等于这个参数时,系统才可以进入到低功耗模式。此参数已在 FreeRTOS.h文件中定义了,默认为2,用户可以自定义时,不能小于2

3、Tickless模式编程

①STM32cubeMX配置

②configEXPECTED_IDLE_TIME_BEFORE_SLEEP设置

(进入低功耗的最小Tick,如果实际比设置Tick小,则不进入低功耗)一般默认2个Tick就够了,如果需要修改不要在源码里修改,在FreeRTOSConfig.h里重定义宏

/* USER CODE BEGIN 1 */
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 10
/* USER CODE END 1 */

③在进入与退出Tickless模式时增加代码,通常是关闭外设等

这样写只是为了验证有没有开启低功耗成功

/* USER CODE BEGIN PREPOSTSLEEP */
__weak void PreSleepProcessing(uint32_t *ulExpectedIdleTime)
{
	//进入休眠前,关闭外设等
/* place for user code */
	HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
}

__weak void PostSleepProcessing(uint32_t *ulExpectedIdleTime)
{
	//退出休眠,开启外设等
/* place for user code */
	HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
}
/* USER CODE END PREPOSTSLEEP */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/883483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT笔记——QProcess学习

我们常常想通过某一个类&#xff0c;来启动一个外部进程 本文将讲解如何通过QProcess来进行启动外部进程 一&#xff1a;了解QProcess QProcess是Qt框架提供的一个类&#xff0c;用于在应用程序中执行外部进程。它提供了一系列函数来启动、控制和与外部进程进行交互 1.启动进程…

02 基于51单片机的LED闪烁实验

目录 前言 一、整体目录结构 二、代码展示 三、main.c代码解析 四、下载到单片机中 总结 前言 前面我们已经学会了点亮一个led的实验&#xff0c;今天我们来实现LED闪烁。前面我们讲到想要让LED亮的话&#xff0c;只要给单片机引脚高电平就好了&#xff0c;如果给LED低电平的话…

Flink之Task解析

Flink之Task解析 对Flink的Task进行解析前,我们首先要清楚几个角色TaskManager、Slot、Task、Subtask、TaskChain分别是什么 角色注释TaskManager在Flink中TaskManager就是一个管理task的进程,每个节点只有一个TaskManagerSlotSlot就是TaskManager中的槽位,一个TaskManager中可…

Vue2-配置脚手架、分析脚手架、render函数、ref属性、props配置项、mixin配置项、scoped样式、插件

&#x1f954;:总有一段付出了没有回报的日子 是在扎根 更多Vue知识请点击——Vue.js VUE2-Day6 配置脚手架脚手架结构render函数vue.js与vue.runtime.xxx.js的区别引入render函数为什么要引入残缺的vue呢&#xff1f; 脚手架默认配置ref属性props配置项传递数据接收数据注意点…

elementui form组件出现英文提示

今天让解决一个bug&#xff0c;是表单组件提示词会出现英文。 问题情景如下&#xff1a; 有时会出现中文&#xff0c;有时会出现英文。 解决方法&#xff1a; 经查看&#xff0c;代码采用的是elementui的form组件&#xff0c;在el-form-item中使用了required属性&#xff0c;同…

企业权限管理(十)-用户详情

用户详情 UserController findById方法 Controller RequestMapping("/user") public class UserController {Autowiredprivate IUserService userService;//查询指定id的用户RequestMapping("/findById.do")public ModelAndView findById(String id) thro…

Python面向对象进阶教程,Python面向对象进阶知识笔记

类方法、静态方法 1. 类方法 第一个形参是类对象的方法需要用装饰器classmethod来标识其为类方法&#xff0c;对于类方法&#xff0c;第一个参数必须是类对象&#xff0c;一般以cls作为第一个参数。 class Dog(object): __type "狗" # 类方法&#xff0c;用class…

数据结构中公式前中后缀表达式-二叉树应用

目录 数据结构中公式前中后缀表达式-二叉树应用 数据结构中公式前中后缀表达式-二叉树应用 什么是前缀表达式、中缀表达式、后缀表达式 前缀表达式、中缀表达式、后缀表达式&#xff0c;是通过树来存储和计算表达式的三种不同方式 以如下公式为例 通过树来存储该公式&#x…

Avalonia 11 WebAssembly中文乱码

文章目录 0x00 原因0x01 解决方法FontForge 0x02 使用自定义字体App.axaml控件使用效果 0x00 原因 新建的Avalonia 11 WebAssembly项目&#xff0c;直接运行的话&#xff0c;会发现中文都是乱码&#xff0c;并且直接在控件上修改FontFamily属性是无法生效的。 0x01 解决方法…

MySQL学习笔记 - 进阶部分

MySQL进阶部分 字符集的相关操作&#xff1a;字符集和比较规则&#xff1a;utf8与utf8mb4&#xff1a;比较规则&#xff1a;常见的字符集和对应的Maxlen&#xff1a; Centos7中linux下配置字符集&#xff1a;各个级别的字符集&#xff1a;执行show variables like %character%语…

matlab画图中多个图例分开绘制

在matlab绘图中&#xff0c;线条较多时导致图例较长回遮挡原图/将图例分类&#xff0c;解决方案将图例分为多个。 一、多个图例一起显示 r 10; a 0; b 0; t0:0.1:2.1*pi; xar*cos(t); ybr*sin(t); plot(x,y,r,linewidth,4);hold on axis equal plot([0 0],[1 10],b,linewi…

双碳目标下基于“遥感+”多技术融合在碳储量、碳排放、碳循环、温室气体等领域应用教程

详情点击链接&#xff1a;双碳目标下基于“遥感”多技术融合在碳储量、碳排放、碳循环、温室气体等领域应用教程 一&#xff1a;双碳视角下遥感技术的研究方向 1.双碳背景及遥感的现实需求 2.全球碳库、碳收支及碳循环现状 3.碳储量、碳收支与碳循环中的遥感技术 4.ENVI及ArcG…

海龟绘图——n个正方形组成的图案

运行结果&#xff1a; 代码&#xff1a; import turtle# 创建海龟对象 nint(input()) t turtle.Turtle()# 设置海龟的颜色和线条粗细 t.color(blue) t.pensize(3)# 画四条直线lengths10 for j in range(n):for i in range(4):lengths20t.forward(lengths)# 旋转90度t.left(90)…

数据治理:打造可信赖的BI环境

章节一&#xff1a;引言 随着信息时代的不断发展&#xff0c;数据已经成为企业决策的重要支撑。而在大数据时代&#xff0c;海量的数据需要被整理、分析&#xff0c;以便为企业提供正确的指导。商业智能&#xff08;BI&#xff09;系统的兴起为企业提供了强大的数据分析能力&am…

利用Lifecycle,管理一个计时器生命周期

Lifecycle是Android Jetpack中的一个组件&#xff0c;用于管理Android应用程序组件&#xff08;如Activity或Fragment&#xff09;的生命周期。它可以帮助开发者在不同的生命周期阶段执行特定的操作&#xff0c;以便更好地管理资源、处理数据和提供用户体验。 Lifecycle作用 …

Python程序设计——对象和类

学习目标 描述对象和类&#xff0c;以及使用类来建模对象定义带数据域和方法的类使用构造方法调用初始化程序来创建和初始化数据域以构建一个对象使用圆点运算符(.)访问对象成员使用self参数引用对象本身使用UML图符号来描述类和对象区分不可变对象和可变对象隐藏数据域以避免数…

应届生运维简历攻略

导语&#xff1a; 当下&#xff0c;计算机科学与技术已经成为一个炙手可热的行业&#xff0c;而作为这个行业中的一份子&#xff0c;运维人员的角色无疑至关重要。如果你是一位即将毕业的应届生&#xff0c;并希望在运维领域打拼&#xff0c;那么一份出色的运维简历将是你踏入…

PS常用快捷按键

1、Ctrl J 键复制&#xff08;快速复制图层&#xff0c;作为备份&#xff09;&#xff1b; 2、快速选择对象&#xff0c;进行移动ctrl 右键 3、放大ctrl 缩小ctrl 4、对同一个图片的多个不同颜色的图片进行截取的时候&#xff0c;注意每次都用同一个切图框&#xff0c;截图保…

【C++】stack容器

1.stack基本概念 英stk 美stk n.&#xff08;整齐的&#xff09;一堆&#xff1b;<英> 垛&#xff0c;堆&#xff1b;大量&#xff0c;许多&#xff1b;&#xff08;尤指工厂的&#xff09;大烟囱&#xff1b;&#xff08;图书馆的&#xff09;藏书架&#xff0c;双面书架…

Redis实现共享Session

Redis实现共享Session 分布式系统中&#xff0c;sessiong共享有很多的解决方案&#xff0c;其中托管到缓存中应该是最常用的方案之一。 1、引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM…