利用STM32CubeMX和keil模拟器,3天入门FreeRTOS(2.0) —— 如何删除任务

news2024/9/24 3:21:43

前言

(1)FreeRTOS是我一天过完的,由此回忆并且记录一下。个人认为,如果只是入门,利用STM32CubeMX是一个非常好的选择。学习完本系列课程之后,再去学习网上的一些其他课程也许会简单很多。
(2)本系列课程是使用的keil软件仿真平台,所以对于没有开发板的同学也可也进行学习。
(3)叠甲,再次强调,本系列课程仅仅用于入门。学习完之后建议还要再去寻找其他课程加深理解。
(4)本系列博客对应代码仓库:
(5)前面我们已经了解了如何创建任务,但是,如果有些任务我们并不是要一直执行,可能要根据情况进行删除任务。那么本文将会介绍如何如何对任务进行删除,但是需要注意,一般情况,删除任务用到少。因为任务自杀要考虑的方面很多,容易出问题,所以新手小白建议了解即可。

实战

(1)任务删除是非常简单的,但是他需要考虑很多问题,所以我不建议新手小白频繁的删除和创建任务。但是,为了保证知识的完整性,我依旧会对此进行讲解。
(2)在上一篇博客的工程基础上进行调整。

在这里插入图片描述

删除任务要注意的宏定义

(1)如果需要调用删除任务的函数,需要在FreeRTOSConfig.h文件种确认INCLUDE_vTaskDelete这个宏被置1了。

在这里插入图片描述

删除任务

(1)首先,我打算使用让GPIOC14引脚作为任务创建删除的控制引脚,因此需要在STM32CubeMX中将这个引脚设置为下拉输入。

在这里插入图片描述

(2)在StartCubemxTask函数中进行如下补充即可。(按Ctrl+F搜索StartCubemxTask即可找到任务函数)

void StartCubemxTask(void *argument)
{
  /* USER CODE BEGIN StartCubemxTask */
	char *CubemxTaskPrintf = (char *)argument;
	uint8_t Task_Status = 0;
  /* Infinite loop */
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_14) == GPIO_PIN_SET)
		{
			printf(CubemxTaskPrintf);
			Task_Status++;
			while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_14) == GPIO_PIN_SET);
		}
		switch(Task_Status)
		{
			case 1:
				if(keilTaskHandle != NULL)
				{
					// 删除 keilTask 任务
					vTaskDelete(keilTaskHandle);			
					keilTaskHandle = NULL;
				}					
				break;
			case 2:
				if(keilTaskHandle == NULL)
				{
					// 重新创建 keilTask 任务
					keilTaskHandle = xTaskCreateStatic(StartKeilTask,"KeilTask", 128, NULL, osPriorityLow1, g_pucStackKeilTaskBuff,&g_TCBKeilTask);
					if(keilTaskHandle == NULL)
					{
						printf("KeilTask creation failed\r\n");
					}		
				}					
				break;
			case 3:
				// 任务自杀
				CubemxTaskHandle = NULL;
				vTaskDelete(NULL);				
				break;
			default:
				Task_Status = 0;
				break;
		}
  }
  /* USER CODE END StartCubemxTask */
}

(3)在StartKeilTask函数中进行如下补充即可。(按Ctrl+F搜索Private application code即可找到任务函数)

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
int fputc(int ch, FILE *f)
{
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);
	return ch;
}
void StartKeilTask(void *argument)
{
	printf("StartKeilTask Creat\r\n");
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
		HAL_Delay(100);
	}
}
/* USER CODE END Application */

测试结果

keil调试配置

(1)打开微库。

在这里插入图片描述

(2)配置模拟器
DARMSTM.DLL
pSTM32F103C8

在这里插入图片描述

配置虚拟示波器

(1)打开调试界面

在这里插入图片描述

(2)选择逻辑分析仪,检测PC13引脚。为什么下面输入的是PORTC.13,原因很简单,格式为PORTx.yx表示端口,y表示具有引脚数值,注意’.'必须是英文的!

在这里插入图片描述
在这里插入图片描述

配置虚拟串口

(1)如下图

在这里插入图片描述

打开GPIO引脚电平配置界面

(1)因为我们需要模拟一个按下按键的操作,因此可以进行如下操作。

在这里插入图片描述

实测

(1)先全速跑

在这里插入图片描述

(2)勾选上PC14引脚。

在这里插入图片描述

(3)取消勾选PC14。

在这里插入图片描述

(4)勾选上PC14引脚。

在这里插入图片描述

(5)取消勾选PC14。

在这里插入图片描述

(6)再次进行电平翻转工作,之后无论怎么反转PC14的电平,我们会发现,方波会一直存在。因为第三次反转PC14的电平是进行任务自杀,所以最终不会有任何现象发生。

在这里插入图片描述

理论

vTaskDelete()函数介绍

(1)这个任务使用起来还是很容易的,只需要传入一个任务句柄即可。不过需要注意的是,删除任务有两种方式,第一种是删除其他的任务,第二种是任务自杀。
<1>删除其他任务:当你需要在任务A中删除任务B,只需要在任务A中调用任务B的句柄即可。如果任务B在创建的时候,任务句柄传入的是NULL,那么任务B将只能自杀,无法被其他任务杀死。
<2>任务自杀:任务自杀只需要传入一个NULL即可。

/**
 * @brief  RTOS 内核管理中移除任务
 *
 * @param  要移除任务的任务句柄,如果是任务自杀,传入NULL
 *
 * @return 无
 */
void vTaskDelete( TaskHandle_t xTaskToDelete );

两种任务删除要注意的点

(1)任务自杀通常由任务自己主动发起,而删除其他任务是由系统中的某个任务请求删除另一个任务。
(2)在实际应用中,需要根据具体的需求和设计来选择使用哪种方法。在任何情况下,都需要确保在删除任务之前,已经合理地释放了任务占用的资源,以避免资源泄漏和系统不稳定性。删除任务释放的资源要考虑以下内容:

  • 避免删除正在执行的任务:尽量避免删除正在执行的任务,因为这可能导致未定义的行为。通常,应该在目标任务主动结束执行或者在任务的代码中检查某些条件后再请求删除。
  • 处理资源释放:确保在删除任务之前释放任务使用的资源。这包括释放动态分配的内存、关闭文件句柄、释放占用的硬件资源等。如果任务在删除时仍然占用资源,可能会导致资源泄漏或系统不稳定。
  • 处理同步和互斥:如果目标任务与其他任务之间存在同步或互斥关系,确保在删除任务之前解除这些关系,以免引起竞态条件或死锁。
  • 避免删除空闲任务:在 FreeRTOS 中,空闲任务(Idle Task)用于在系统没有其他任务需要执行时运行。删除空闲任务可能导致系统无法正常工作,应该谨慎使用。例如,任务删除之后的堆栈释放,是在空闲任务中执行,当空闲任务删除之后,堆栈将需要通过其他任务手动释放,这样将会增加工作量。

重新创建任务需要注意的点

(1)其实从实操中已经知道了,当我们重新创建任务的时候。任务会从头执行,因此这里我们将能够看到两次StartKeilTask Creat到底字符数据打印。

在这里插入图片描述

参考

(1)FreeRTOS官方文档:vTaskDelete函数介绍

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

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

相关文章

基于Java开发的校园跳蚤市场管理系统详细设计和实现【附源码】

基于Java开发的校园跳蚤市场管理系统详细设计和实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种…

React进阶 - 12(浅谈 state、props与render函数的关系)

本章内容 目录 一、state 与 render 函数的关系二、props 与 render函数的关系 上一节我们讲了如何使用 PropTypes及 DefaultProps来进行属性的类型校验及设置属性默认值。本节内容我们来了解一下 state、props与render函数的关系。 一、state 与 render 函数的关系 我们知道…

助力焊接场景下自动化缺陷检测识别,基于YOLOv8【n/s/m/l/x】全系列参数模型开发构建工件表面焊接裂纹缺陷检测识别分析系统

焊接是一个不陌生但是对于开发来说相对小众的场景&#xff0c;在工件表面焊接场景下常常有对工件表面缺陷智能自动化检测识别的需求&#xff0c;工业AI结合落地是一个比较有潜力的场景&#xff0c;在我们前面的博文开发实践中也有一些相关的实践&#xff0c;感兴趣的话可以自行…

防御第二次作业-防火墙组网实验(2)

目录 实验拓扑图 实验要求 一般组网步骤 to isp区域ping通 dmz区域 trust区域 实验拓扑图 实验要求 1.防火墙向下使用子接口分别对应两个内部区域 2.所有分区设备可以ping通网关 一般组网步骤 1.先配ip、接口、区域、安全策略 2.内网配置回包路由 3.配置dmz区域的服务器映…

vue2(Vuex)、vue3(Pinia)、react(Redux)状态管理

vue2状态管理Vuex Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它使用集中式存储管理应用的所有组件的状态&#xff0c;以及规则保证状态只能按照规定的方式进行修改。 State&#xff08;状态&#xff09;:Vuex 使用单一状态树&#xff0c;即一个对象包含全部的应用层…

分布式日志

1 日志管理 1.1 日志管理方案 服务器数量较少时 直接登录到目标服务器捞日志查看 → 通过 rsyslog 或shell/python 等脚本实现日志搜集并集中保存到统一的日志服务器 服务器数量较多时 ELK 大型的日志系统&#xff0c;实现日志收集、日志存储、日志检索和分析 容器环境 …

基于SpringBoot Vue汽车租赁系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

【代码随想录】刷题笔记Day54

前言 差单调栈就结束代码随想录一刷啦&#xff0c;回家二刷打算改用python补充进博客&#xff0c;小涛加油&#xff01;&#xff01;&#xff01; 647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; 双指针法 中心点外扩&#xff0c;注意中心点可能有一个元素可能有两个…

Android14源码剖析:MediaPlayer与MediaPlayerService区别?(五十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

C#,入门教程(35)——哈希表(Hashtable)的基础知识与用法

上一篇&#xff1a; C#&#xff0c;入门教程(34)——关于函数的参数之引用&#xff08;ref&#xff09;的一点知识与源程序https://blog.csdn.net/beijinghorn/article/details/125411351 有一段故事&#xff1a; King Log The frogs in the lake had an easy life doing ex…

神经网络算法与逻辑回归:优势与差异

神经网络算法和逻辑回归都是预测模型中的重要工具&#xff0c;但它们在处理复杂和非线性问题时表现出不同的性能。本文将深入探讨神经网络算法相对于逻辑回归的优势&#xff0c;以及它们在不同场景下的适用性。 一、引言 神经网络算法和逻辑回归都是预测模型中的重要工具&…

C# CefSharp 根据输入日期段自动选择日期

前言 搞这个Demo整整搞几天通宵&#xff0c;爆肝了。后做的效果出来&#xff0c;还是不错的。给小伙伴看看效果图。 2, 遇到的问题 日期之间相差多少个月数。开始时间框点击对应月份要点击多少次&#xff0c;结束时间框点击对应月份要点击多少次Xpath获取问题。找到对应html元…

力扣刷题第七天 分割数组的最大值

给定一个非负整数数组 nums 和一个整数 k &#xff0c;你需要将这个数组分成 k 个非空的连续子数组。 设计一个算法使得这 k 个子数组各自和的最大值最小。 注&#xff1a; 1 < nums.length < 10000 < nums[i] < 1061 < k < min(50, nums.length) 示例一 输入…

cdh6.3.2的hive配udf

背景 大数据平台的租户要使用udf&#xff0c;他们用beeline连接&#xff0c; 意味着要通过hs2&#xff0c;但如果有多个hs2&#xff0c;各个hs2之间不能共享&#xff0c;需要先把文件传到hdfs&#xff0c;然后手动在各hs2上create function。之后就可以永久使用了&#xff0c;…

宠物互联网医院系统

在数字时代&#xff0c;宠物医疗迎来了一场革新&#xff0c;动物互联网医院系统以其先进的技术和智能的特性成为宠物护理的领军者。本文将介绍宠物互联网医院系统的一些关键技术和代码示例&#xff0c;揭示这一科技奇迹的实现原理。 1. 远程医疗服务的实现 远程医疗服务是宠…

<蓝桥杯软件赛>零基础备赛20周--第15周--快速幂+素数

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

Spring-配置文件

一、引子 了解完Spring的基本概念后&#xff0c;我们紧接着来了解Spring中的核心文件--Spring配置文件。 二、配置Bean 我们在上一节Spring的基本概念中快速使用了一下Spring&#xff0c;其中我们在配置文件中主要涉及到就是Bean标签的配置&#xff1a;主要的配置字段有id, …

[设计模式Java实现附plantuml源码~创建型] 对象的克隆~原型模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

C++ //练习 2.36 关于下面的代码,请指出每一个变量的类型以及程序结束时它们各自的值。

C Primer&#xff08;第5版&#xff09; 练习 2.36 练习 2.36 关于下面的代码&#xff0c;请指出每一个变量的类型以及程序结束时它们各自的值。 int a 3, b 4; decltype(a) c a; decltype((b)) d a; c; d;环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09;…

基本语法和 package 与 jar

3.基本语法 1.输入输出 // 导入 java.util 包中的 Scanner 类 import java.util.Scanner;// 定义名为 ScannerExample 的公共类 public class ScannerExample {// 主方法&#xff0c;程序的入口点public static void main(String[] args) {// 创建 Scanner 对象&#xff0c;用…