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

目录

一、任务的基本概念

二、任务状态的概念

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_TaskHAL_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_TaskHAL_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.rhkb.cn/news/83248.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ChatGPT 指令大全】销售怎么借力ChatGPT提高效率

目录 销售演说 电话销售 产出潜在客户清单 销售领域计划 销售培训计划 总结 随着人工智能技术的不断进步,我们现在有机会利用ChatGPT这样的智能助手来改进我们的销售工作。在接下来的时间里,我将为大家介绍如何运用ChatGPT提高销售效率并取得更好的…

nbcio-boot因升级mybatis-plus到3.5.3.1和JSQLParser 到4.6引起的online表单开发的数据库导入出错解决

更多功能看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 nbcio-boot因升级…

专业的ADAS测试记录仪ETHOS

随着ADAS驾驶辅助系统技术的快速发展及日臻成熟,近年来ADAS在全球汽车市场已开始快速普及和商业化,而如何确保ADAS系统的可靠和安全俨然成为汽车领域的重要问题。因此,ADAS驾驶辅助系统的测试也成为了各大整车厂及零部件厂商所关注的焦点。 一…

NodeJS原型链污染ctfshow_nodejs

文章目录 NodeJS原型链污染&ctfshow_nodejs前言0x01.原型与原型链0x02.prototype和__proto__分别是什么?0x03.原型链继承不同对象的原型链* 0x04.原型链污染原理0x05.merge()导致原型链污染0x06.ejs模板引擎RCEejs模板引擎另一处rce 0x07.jade模板引擎RCE【ctfs…

mysql数据库如何转移到oracle

mysql数据库转移到oracle 在研发过程中,可能会用到将表数据库中的表结构及数据迁移到另外一种数据库中, 比如说从mysql中迁移到oracle中, 常用的方法有好些,如下 1、使用powerdesigner,先连接mysql然后生成mysql的p…

自动化测试的生命周期是什么?

软件测试发展到今日,已经逐渐标准化且能力更强,其流程每天都在发展。测试人员的技术熟练程度对于整个测试阶段的成功来说至关重要。测试不再意味着仅仅发现错误;它的范围已经扩大,从任何开发项目开始就可以看出它的重要性。 当谈论…

《合成孔径雷达成像算法与实现》Figure3.9

代码复现如下: clc clear close all% 参数设置 TBP 100; % 时间带宽积 T 7.2e-6; % 脉冲持续时间 t_0 1e-6; % 脉冲回波时延% 参数计算 B TBP/T; …

管理类联考——逻辑——论证逻辑——汇总篇——真题和典例——支持

支持 没有特点的 199-2017-1-30——支持论点 离家300米的学校不能上,却被安排到2千米外的学校就读,某市一位适龄儿童在上小学时就遭遇了所在区教育局这样的安排,而这一安排是区教育局根据儿童户籍所在施教区做出的。根据该市教育局规定的“…

使用 Spring Boot 发送电子邮件(SMTP 集成)

本文探讨了 Spring Boot 与 SMTP 的集成以及如何从您自己的 Spring Boot 应用程序发送电子邮件。 本文探讨如何从您自己的Spring Boot应用程序发送电子邮件。 是的,您可以拥有专用的 REST API,它接受电子邮件发送者和接收者的电子邮件地址、主题…

图的遍历之 深度优先搜索和广度优先搜索

深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各…

虹科新闻 | 虹科与Power-MI正式建立合作伙伴关系

近日,虹科与Power-MI正式建立合作伙伴关系,双方就工业预测性维护领域进行深入的交流与合作,未来将共同致力于为亚洲市场提供完整的、更高质量的预测性维护解决方案,解决亚洲客户的工业自动化挑战。 虹科与Power-MI都表示十分期待…

(2023Arxiv)Meta-Transformer: A Unified Framework for Multimodal Learning

论文链接:https://arxiv.org/abs/2307.10802 代码链接:https://github.com/invictus717/MetaTransformer 项目主页:https://kxgong.github.io/meta_transformer/ 【注】:根据实验结果来看,每次输入一种数据源进行处…

【uniapp】一文读懂app端安装包升级

一、前言 首先,在app端开发上线的过程中,会面临一个问题,就是关于app端的版本升级的问题。如果不做相关处理来引导用户的话,那么app就会出现版本没有更新出现的各种问题,我们常见的有在线升级和去指定地址下载安装两种…

【JPCS出版】第五届能源、电力与电网国际学术会议(ICEPG 2023)

第五届能源、电力与电网国际学术会议(ICEPG 2023) 2023 5th International Conference on Energy, Power and Grid 最近几年,不少代表委员把目光投向能源电力领域,对促进新能源发电产业健康发展、电力绿色低碳发展,提…

0基础学习VR全景平台篇 第81篇:全景相机-临云镜如何直播推流

临云镜全景相机是阿里巴巴定制全景设备,实现空间三维信息的快速采集,与阿里云三维空间重建平台搭配,帮助品牌商与平台以较低的成本完成空间的快速采集,并支持对室内/室外空间的三维全景展示及空间漫游,同时支持VR浏览、…

【深度学习注意力机制系列】—— SKNet注意力机制(附pytorch实现)

SKNet(Selective Kernel Network)是一种用于图像分类和目标检测任务的深度神经网络架构,其核心创新是引入了选择性的多尺度卷积核(Selective Kernel)以及一种新颖的注意力机制,从而在不增加网络复杂性的情况…

利用Halcon绘制ROI区域或Mask区域

利用Halcon绘制ROI区域或Mask区域 概述内容补充参考老版本的ROI绘制(Halcon 12-17) 概述 ROI是Halcon中的一个很重要的概念,为了减少计算量,只关注待检测物体或该物体周围的一片区域即可,ROI就是图像处理所关注的区域…

LC-1289. 下降路径最小和 II(记忆化搜索==> 动态规划)

1289. 下降路径最小和 II 难度困难108 给你一个 n x n 整数矩阵 grid ,请你返回 非零偏移下降路径 数字和的最小值。 非零偏移下降路径 定义为:从 grid 数组中的每一行选择一个数字,且按顺序选出来的数字中,相邻数字不在原数组…

vue 项目中 utils 中 js 文件早于 main.js 文件调用

vue项目中utils中js文件早于main.js文件调用

Kotlin反射访问androidx.collection.LruCache类私有变量

Kotlin反射访问androidx.collection.LruCache类私有变量 androidx.collection.LruCache类中定义了一个名为map的LinkedHashMap,map存储了所有LruCache的数据,有时候需要遍历访问该LinkedHashMap,取出里面的值,但是LruCache代码实…