FreeRTOS(任务管理的创建、删除、挂起、恢复)

news2024/11/16 9:49:59

目录

一、任务的基本概念

二、任务状态的概念

1、Running—运行态:

2、Ready—就绪态

3、Blocked—阻塞态

4、Suspended—挂起态

三、任务状态的切换

 四、系统启动

1、vTaskStartScheduler()函数

1.1 作用

1.2 启动函数介绍

 2、空闲任务

2.1 空闲任务的作用

五、任务创建

5.1 创建任务的方式

5.2 动态创建任务函数详解

5.3 使用举例

六、任务删除

6.1 删除任务函数详解

6.2 使用举例

七、任务挂起

7.1 挂起任务函数详解

7.2 使用举例

八、任务恢复(普通方式与中断方式)

8.1 普通方式恢复任务函数详解

8.2 中断方式恢复任务函数详解

九、任务管理编程

9. 1 cube配置

 9.2 手动创建任务

9.3 手动删除、挂起任务

9.4 手动创建、恢复任务

资料来源于硬件家园:FreeRTOS实时操作系统第四讲 - 任务管理(创建,删除,挂起,恢复) (qq.com)

一、任务的基本概念

1、从系统的角度看,任务是竞争系统资源的最小运行单元。

2、FreeRTOS是一个支持多任务的操作系统,在FreeRTOS中,任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其他任务运行。

3、每个任务在自己的环境中运行,在任何时刻,只有一个任务得到运行,FreeRTOS调度器决定运行哪个任务。调度器会不断的启动、停止每一个任务,宏观上看,所有的任务都在同时进行。

4、在FreeRTOS中,每个任务都有自己的栈空间(一段连续的内存),用于保存任务运行环境。任务越多,需要的栈空间就越大,而一个系统能运行多少个任务,取决于系统可用的内存。

5、任务通常会运行在一个死循环中,不会退出,如果不需要某个任务,可以调用FreeRTOS中的删除任务API函数将任务删除,释放系统资源。

二、任务状态的概念

FreeRTOS系统中的任务有四种状态:

1、Running—运行态:

当任务处于实际运行时被称之为运行态,即 CPU 的使用权被这个任务占用。

2、Ready—就绪态

处于就绪态的任务是指那些能够运行(没有被阻塞和挂起),但是当前没有运行的任务,因为同优先级或更高优先级的任务正在运行。

3、Blocked—阻塞态

由于等待信号量,消息队列,事件标志组等而处于的状态被称之为阻塞态,另外任务调用延迟函数也会处于阻塞态。

4、Suspended—挂起态

类似阻塞态,通过调用函数 vTaskSuspend()对指定任务进行挂起,挂起后这个任务将不被执行,只有调用函数 xTaskResume()才可以将这个任务从挂起态恢复。

三、任务状态的切换

图片

 四、系统启动

1、vTaskStartScheduler()函数

/*Start scheduler */
osKernelStart();
osStatus osKernelStart (void)l{
vTaskStartScheduler();
return osOK;
}

1.1 作用

启动 FreeRTOS调度

1.2 启动函数介绍

函数原型:void vTaskStartScheduler( void );

函数描述:函数 vTaskStartScheduler 用于启动 FreeRTOS 调度器,即启动 FreeRTOS 的多任务执行。

使用这个函数要注意以下几个问题:

①空闲任务和可选的定时器任务是在调用这个函数后自动创建的。

②正常情况下这个函数是不会返回的。如果有返回,极有可能是用于定时器任务或者空闲任务的内存空间不足造成创建失败,此时需要加大FreeRTOS可管理的内存空间。

图片

 2、空闲任务

空闲任务是FreeRTOS系统中没有其它任务运行时自动进入的系统任务,不需要用户创建,启用调度器时,调度器会自动创建空闲任务。

图片

2.1 空闲任务的作用

① 执行删除任务时,系统并不会立即释放任务的内存空间,只会将任务添加到结束列表中,真正的系统资源回收工作在空闲任务中完成。

②可以在空闲任务中实现低功耗功能。

五、任务创建

5.1 创建任务的方式

① 静态创建任务,xTaskCreateStatic(),需要自行定义任务栈空间与任务控制块,一般不采用,不作介绍。

②动态创建任务,xTaskCreate(),系统动态分配任务栈空间与任务控制块,应用采用此方式。

5.2 动态创建任务函数详解

函数原型:

图片

函数描述:函数 xTaskCreate 用于实现 FreeRTOS 操作系统的任务创建,并且还可以自定义任务栈的大小。

①第 一 个参数填创建任务的函数名

②第 二 个参数是任务名,这个参数主要用于调试的时候方便看是哪个任务

③第 三 个参数是任务栈大小,单位 word,也就是 4 字节

④ 第 四 个参数是创建的任务函数的形参

⑤第 五 个参数是定义任务优先级

⑥第 六 个参数是任务句柄,用于区分不同的任务

5.3 使用举例

图片

STM32cubeMX创建方法:

图片

方法详解:

① 首先利用宏定义定义任务参数结构体变量

图片

图片

#name:将name转化为字符串,等效于"name"

os_thread_def__name:将name以字符串方式拼接,等效于"os_thread_def_name"

① 调用动态创建函数创建任务,形参为上面的结构体地址

图片

图片

图片

六、任务删除

6.1 删除任务函数详解

函数原型:void vTaskDelete( TaskHandle_t xTask ); /* 任务句柄 */ 

函数描述:函数 vTaskDelete 用于实现 FreeRTOS 操作系统的任务删除。 

①第 1 个参数填要删除任务的句柄

使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_vTaskDelete 1

②  如果用往此函数里面填的任务 ID 是 NULL,即数值 0 的话,那么删除的就是当前正在执行的任务,此任务被删除后,FreeRTOS 会切换到任务就绪列表里面下一个要执行的最高优先级任务。

③ 在 FreeRTOS 中,创建任务所需的内存需要在空闲任务中释放,如果用户在 FreeRTOS 中调用了这个函数的话,一定要让空闲任务有执行的机会,否则这块内存是无法释放的。另外,创建的这个任务在使用中申请了动态内存,这个内存不会因为此任务被删除而删除,这一点要注意,一定要在删除前将此内存释放。

6.2 使用举例

图片

七、任务挂起

7.1 挂起任务函数详解

函数原型:void vTaskSuspend( TaskHandle_t xTaskToSuspend); /* 任务句柄 */ 

函数描述:函数 vTaskSuspend 用于实现 FreeRTOS 操作系统的任务挂起。 

第 1 个参数填要挂起任务的句柄

 使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_vTaskSuspend 1

如果用往此函数里面填的任务 ID 是 NULL,即数值 0 的话,那么挂起的就是当前正在执行的任务,此任务被挂起后,FreeRTOS 会切换到任务就绪列表里面下一个要执行的高优先级任务。

③ 多次调用此函数的话,只需调用一次 vTaskResume 即可将任务从挂起态恢复。

7.2 使用举例

图片

八、任务恢复(普通方式与中断方式)

8.1 普通方式恢复任务函数详解

函数原型:void vTaskResume( TaskHandle_t xTaskToResume); /* 任务句柄 */ 

函数描述:函数 vTaskResume 用于实现 FreeRTOS 操作系统的任务挂起

①第 1 个参数填要恢复任务的句柄

使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_vTaskSuspend  1

② 多次调用函数 vTaskSuspend 的话,只需调用一次 vTaskResume 即可将任务从挂起态恢复。

此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用的xTaskResumeFromISR(),以后缀 FromISR 结尾。

使用举例:

图片

8.2 中断方式恢复任务函数详解

函数原型:BaseType_t  vTaskResumeFromISR( TaskHandle_t xTaskToResume); /* 任务句柄 */ 

函数描述:函数 vTaskResumeFromISR 用于实现 FreeRTOS 操作系统的任务恢复。

①第 1 个参数填要恢复任务的句柄

使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_xResumeFromISR 1

② 多次调用函数 vTaskSuspend 的话,只需调用一次 vTaskResumeFromISR 即可将任务从挂起态恢复。

③ 如果用户打算采用这个函数实现中断与任务的同步,要注意一种情况,如果此函数的调用优先于函数vTaskSuspend 被调用,那么此次同步会丢失,这种情况下建议使用信号量来实现同步。

④此函数是用于中断服务程序中调用的,故不可以在任务中使用此函数,任务中使用的是 vTaskResume。

使用举例:

图片

九、任务管理编程

9. 1 cube配置

修改FreeRTOS_Debug的配置

修改内存分配方式为动态分配

 9.2 手动创建任务

在freertos.c中进行定义

①定义句柄

/* USER CODE BEGIN Variables */
extern volatile uint32_t CPU_RunTime;
osThreadId KEY1Handle;
/* USER CODE END Variables */

②定义入口函数

/* USER CODE BEGIN FunctionPrototypes */
void KEY1_Task(void const * argument);
/* USER CODE END FunctionPrototypes */

③创建任务

  /* USER CODE BEGIN RTOS_THREADS */
  osThreadDef(KEY1, KEY1_Task, osPriorityIdle, 0, 128);
  KEY1Handle = osThreadCreate(osThread(KEY1), NULL);
  /* USER CODE END RTOS_THREADS */

 ④入口函数实现

/* USER CODE BEGIN Application */
void KEY1_Task(void const * argument)
{
  /* USER CODE BEGIN KEY1_Task */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END KEY1_Task */
}
/* USER CODE END Application */

9.3 手动删除、挂起任务

void KEY0_Task(void const * argument)
{
  /* USER CODE BEGIN KEY0_Task */
  /* Infinite loop */
  for(;;)
  {
	int KeyState=0;
	//按键检测
	if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET)
	{
		KeyState=1;
		while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET)
		{
			osDelay(20);//必须用阻塞延时
		}
	}
	if(KeyState)
	{
		vTaskSuspend(LED1Handle);//挂起LED1_Task
		HAL_UART_Transmit(&huart2,(uint8_t*)"KEY0 depress... \r\n", 20, HAL_MAX_DELAY);
		if(LED0Handle != NULL)
		{
			vTaskDelete(LED0Handle);
			LED0Handle=NULL;
			HAL_UART_Transmit(&huart2,(uint8_t*)"delete LED0_Task... \r\n", 20, HAL_MAX_DELAY);
		}
		else
		{
			HAL_UART_Transmit(&huart2,(uint8_t*)"None LED0_Task... \r\n", 20, HAL_MAX_DELAY);
		}
	}
    osDelay(1);
  }
  /* USER CODE END KEY0_Task */
}

9.4 手动创建、恢复任务

void KEY1_Task(void const * argument)
{
  /* USER CODE BEGIN KEY1_Task */
  /* Infinite loop */
  for(;;)
  {
	int KeyState=0;
	//按键检测
	if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_RESET)
	{
		KeyState=1;
		while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_RESET)
		{
			osDelay(20);//必须用阻塞延时
		}
	}
	if(KeyState)
	{
		vTaskResume(LED1Handle);//恢复LED1_Task
		HAL_UART_Transmit(&huart2,(uint8_t*)"KEY1 depress... \r\n", 20, HAL_MAX_DELAY);
		if(LED0Handle == NULL)
		{
			  osThreadDef(LED0, LED0_Task, osPriorityNormal, 0, 128);
			  LED0Handle = osThreadCreate(osThread(LED0), NULL);
			if(LED0Handle!=NULL)
			HAL_UART_Transmit(&huart2,(uint8_t*)"LED0_Task create success... \r\n", 20, HAL_MAX_DELAY);
		}
		else
		{
			HAL_UART_Transmit(&huart2,(uint8_t*)"exist LED0_Task ... \r\n", 20, HAL_MAX_DELAY);
		}
	}
    osDelay(1);
  }
  /* USER CODE END KEY1_Task */
}

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

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

相关文章

mac安装vscode 配置git

1、安装vscode 官网地址 下载mac稳定版安装很慢的解决办法 (转自) mac电脑如何解决下载vscode慢的问题 选择谷歌浏览器右上角的3个点,选择下载内容,右键选择复制链接地址,在新窗口粘贴地址, 把地址中的一段替换成下面的cscode.sd…

新的里程碑!纪念正月十六工作室博客总访问量突破两百万

时值盛夏,清风徐徐,不觉间我们的博客访问量又迈入了新的里程碑——访问量突破两百万! 总访问量突破百万: 个人成就: 记得上次突破重大里程碑还是去年夏天,那时我们重修岳阳楼,追往忆&#…

小程序商品如何设置阶梯价?

阶梯价在电商小程序中是一种常见的销售策略,可以吸引更多的消费者并提高销售额。下面将介绍一些怎么设置小程序产品的阶梯价的方法。 1. 添加/修改商品的时候,点击阶梯价,会弹出阶梯价设置界面。 2. 设置阶梯价规则。例如,当消费者…

http相关知识点

文章目录 长链接http周边会话保持方案1方案2 基本工具postmanFiddlerFiddler的原理 长链接 一张网页实际上可能会有多种元素组成,这也就说明了网页需要多次的http请求。可由于http是基于TCP的,而TCP创建链接是有代价的,因此频繁的创建链接会…

gSpan算法执行步骤详解示例

目录 1. 问题描述2. gSpan算法步骤2.1 数据预处理2.2 深度递归挖掘频繁子图2.2.1 获取所有的频繁边2.2.2 深度递归挖掘频繁子图 参考文献 1. 问题描述 gSpan 是一款图规则挖掘算法,目标是从现有的图集中挖掘频繁子图。如下图中包含三个图: 其中圆圈为顶…

centos安装python3的多个版本

标题 原本安装了python3.6,但是又有一个项目需要py3.7,所以需要让两个版本共存 操作 1、下载py3.7 wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz2、解压 tar -xzvf Python-3.7.3.tgz进入到文件夹 cd Python-3.7.33、安装 本人c…

【Go 基础篇】Go语言初探:第一段代码与执行过程解析

介绍 Go语言(也称为Golang)作为一门现代化的编程语言,以其简洁的语法、高效的性能和丰富的标准库而受到了广泛关注和使用。对于初学者来说,编写和执行第一段Go代码是迈向这门语言的重要一步。本篇博客将带您深入了解Go语言的第一…

BLE蓝牙协议栈分析

BLE——协议层次结构 一、BLE Controller Controller实现射频相关的模拟和数字部分,完成最基本的数据发送和接收,Controller对外接口是天线,对内接口是主机控制器接口HCI(Hostcontroller interface); 控制…

46.利用matlab绘制维安尼曲线(matlab程序)

1.代码 clear close all syms s t k u r; x12*sin(s)*cos(t);y12*sin(s)*sin(t);z12*cos(s); x2-2*cos(k)*cos(k);y22*sin(k)*cos(k);z2u; subplot(1,2,1);ezmeshc(x2,y2,z2,[0,pi,-2,2]); %绘制圆柱面 hold on; ezsurf(x1,y1,z1,[-pi,pi,0,pi]); %绘制球面 title( 球面与圆柱…

SpringBoot--发邮件的方法(有示例)

原文网址&#xff1a;SpringBoot--发邮件的方法(有示例)_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SpringBoot发邮件的方法(有示例)。 依赖 pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-ma…

nginx简介与安装配置,目录结构和配置文件介绍

一.nginx简介 1.简介 2.特性 二.nginx安装 1.rpm包方式 &#xff08;1&#xff09;下载扩展源 &#xff08;2&#xff09;安装扩展rpm包&#xff0c;nginx -V查看配置参数&#xff0c;后面源码安装时要用到 2.源码方式 &#xff08;1&#xff09;建议提前下好所需要的部…

C语言系列之原码、反码和补码

一.欢迎来到我的酒馆 讨论c语言中&#xff0c;原码、反码、补码。 目录 一.欢迎来到我的酒馆二.原码 二.原码 2.1在计算机中&#xff0c;所有数据都是以二进制存储的&#xff0c;但不是直接存储二进制数&#xff0c;而是存储二进制的补码。原码很好理解&#xff0c;就是对应的…

Python读取excel数据并创建文件目录树-全解析过程及逻辑

需求描述&#xff1a; 需要将以下excel内的结构解析&#xff0c;并创建对应的文件目录 实现思路&#xff1a; 实现思路是通过解析Excel文件中的目录结构&#xff0c;并根据目录结构创建对应的文件夹。 具体的实现步骤如下&#xff1a; 1. 加载指定的Excel文件&#xff0c…

阿里云内容审核服务使用(图片审核)

说明&#xff1a;在项目中&#xff0c;我们经常会对用户上传的内容&#xff08;如文字、图片&#xff09;等资源内容进行审核&#xff0c;审核包括两方面&#xff0c;一方面是内容与描述不符&#xff0c;一方面是违反法律法规。本文介绍使用阿里提供的内容审核服务&#xff0c;…

《算法竞赛·快冲300题》每日一题:“最大团”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 最…

zookeeperAPI操作与写数据原理

要执行API操作需要在idea中创建maven项目 &#xff08;改成自己的阿里仓库&#xff09;导入特定依赖 添加日志文件 上边操作做成后就可以进行一些API的实现了 目录 导入maven依赖&#xff1a; 创建日志文件&#xff1a; 创建API客户端&#xff1a; &#xff08;1&#xff09…

Java实现八皇后问题

八皇后问题说明 八皇后问题&#xff0c;是一个古老而著名的问题&#xff0c;是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯贝瑟尔于 1848 年提出&#xff1a;在 88 格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即&#xff1a;任意两个皇后都不…

【数据库】Redis可以替代Mysql吗

Redis和Mysql的搭配 Redis可以替代Mysql吗什么是RedisRedis适用的场景以及优点Redis的缺点 什么是MysqlMysql的优点Mysql缺点 总结 Redis可以替代Mysql吗 Redis不能代替MySQL&#xff0c; Redis和MySQL只能是一种互补。 什么是Redis Redis是一种非关系型数据库&#xff0c;也…

IDEA全局设置MyBatis中写SQL语句提示

把这两个设置改成MySQL即可&#xff1a;

clickhouse 删除操作

OLAP 数据库设计的宗旨在于分析适合一次插入多次查询的业务场景&#xff0c;市面上成熟的 AP 数据库在更新和删除操作上支持的均不是很好&#xff0c;当然 clickhouse 也不例外。但是不友好不代表不支持&#xff0c;本文主要介绍在 clickhouse 中如何实现数据的删除&#xff0c…