【学习FreeRTOS】第4章——FreeRTOS任务创建与删除

1.任务创建和删除的API函数

任务的创建和删除本质就是调用FreeRTOS的API函数

  • 动态方式创建任务——xTaskCreate()
  • 静态方式创建任务——xTaskCreateStatic()
  • 删除任务——vTaskDelete()

动态创建任务:任务的任务控制块以及任务的栈空间所需的内存,均由 FreeRTOS 从 FreeRTOS 管理的堆中分配
静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供

1.1.任务控制块TCB

FreeRTOS中的每一个已创建任务都包含一个任务控制块,任务控制块是一个结构体变量,FreeRTOS用任务控制块结构体存储任务的属性。FreeRTOS的任务控制块结构体中包含了很多成员变量,但是,大部分的成员变量都是可以通过FreeRTOSConfig.h 配置文件中的配置项宏定义进行裁剪的。

typedef struct tskTaskControlBlock       
{volatile StackType_t 	* pxTopOfStack; 						/* 任务栈栈顶,必须为TCB的第一个成员 */ListItem_t 				xStateListItem;           				/* 任务状态列表项 */      ListItem_t 				xEventListItem;							/* 任务事件列表项 */     UBaseType_t 			uxPriority;                				/* 任务优先级,数值越大,优先级越大 */StackType_t 			* pxStack;								/* 任务栈起始地址 */char 					pcTaskName[ configMAX_TASK_NAME_LEN ]; 	/* 任务名字 */		//...省略很多条件编译的成员
} tskTCB;

1.2.动态创建任务xTaskCreate()

typedef struct tskTaskControlBlock * TaskHandle_t;
BaseType_t xTaskCreate
( 	TaskFunction_t 						pxTaskCode,		/* 指向任务函数的指针 */				const char * const 					pcName, 		/* 任务名字,最大长度configMAX_TASK_NAME_LEN */const 	configSTACK_DEPTH_TYPE 		usStackDepth, 	/* 任务堆栈大小,注意字为单位 */void * const 						pvParameters,	/* 传递给任务函数的参数 */UBaseType_t 						uxPriority,		/* 任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */TaskHandle_t * const 				pxCreatedTask 	/* 任务句柄,就是任务的任务控制块 */
)

【注意:在动态创建任务时,任务句柄是指向TCB的指针
返回类型:BaseType_t
返回pdPASS:任务创建成功
返回errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:任务创建失败

实现动态创建任务的流程

此函数创建的任务会立刻进入就绪态,由任务调度器调度运行

  • 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
  • 定义函数入口参数
  • 编写任务函数

动态创建任务的内部实现

  • 申请堆栈内存&任务控制块内存
  • TCB结构体成员赋值
  • 添加新任务到就绪列表中

详细流程如下图:
在这里插入图片描述
在这里插入图片描述

1.3.静态创建任务函数xTaskCreateStatic()

TaskHandle_t xTaskCreateStatic
(TaskFunction_t			pxTaskCode,			/* 指向任务函数的指针 */const char * const		pcName,				/* 任务函数名 */const uint32_t			ulStackDepth, 		/* 任务堆栈大小注意字为单位 */void * const			pvParameters, 		/* 传递的任务函数参数 */UBaseType_t				uxPriority, 		/* 任务优先级 */StackType_t * const		puxStackBuffer, 	/* 任务堆栈,一般为数组,由用户分配 */StaticTask_t * const	pxTaskBuffer		/* 任务控制块指针,由用户分配 */
); 		

【注意:在静态创建任务时,TCB空间由用户申请,其结构与动态TCB类似,任务句柄与TCB关系没有直接关系
返回类型:TaskHandle_t(任务句柄)
返回NULL:用户没有提供相应的内存,任务创建失败
返回其他:任务句柄,任务创建成功

实现静态创建任务的流程

此函数创建的任务会立刻进入就绪态,由任务调度器调度运行

  • 需将宏configSUPPORT_STATIC_ALLOCATION 配置为 1
  • 定义空闲任务&定时器任务(可选)的任务堆栈及TCB
  • 实现空闲任务和定时器任务(可选)接口函数:vApplicationGetIdleTaskMemory( ) 、vApplicationGetTimerTaskMemory ( )
  • 定义函数入口参数
  • 编写任务函数

静态创建任务的内部实现

  • TCB结构体成员赋值
  • 添加新任务到就绪列表中
    在这里插入图片描述

1.4.任务删除函数vTaskDelete()

void vTaskDelete(TaskHandle_t xTaskToDelete);	//参数为待删除任务的任务句柄
  • 被删除的任务将从就绪态任务列表、阻塞态任务列表、挂起态任务列表和事件列表中移除
  • 当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
  • 空闲任务会负责释放被删除任务中由系统分配的内存(动态),但是由用户在任务删除前申请的内存(静态), 则需要由用户在任务被删除前提前释放,否则将导致内存泄露
    【注意:动态创建时,删除任务不是自己,直接释放内存,删除任务是自己,在空闲任务释放内存;静态创建的内存需由用户释放】

实现删除任务的流程

  • 使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1
  • 入口参数输入需要删除的任务句柄(NULL代表删除本身)

删除任务的内部实现

  • 获取所要删除任务的控制块:通过传入的任务句柄,判断所需要删除哪个任务,NULL代表删除自身
  • 将被删除任务移除所在列表:将该任务在所在列表中移除,包括:就绪、阻塞、挂起、事件等列表
  • 判断所需要删除的任务
    删除任务自身,需先添加到等待删除列表,内存释放将在空闲任务执行
    删除其他任务,释放内存,任务数量–
  • 更新下个任务的阻塞时间:更新下一个任务的阻塞超时时间,以防被删除的任务就是下一个阻塞超时的任务
  • 调度器正在运行且删除任务自身,则需要进行一次任务切换

2.任务创建和删除(动态方法)

  • 实验目的:学会 xTaskCreate( ) 和 vTaskDelete( ) 的使用
  • 实验设计:将设计四个任务:start_task、task1、task2、task3
    start_task:用来创建其他的三个任务
    task1:实现LED0每500ms闪烁一次
    task2:实现LED1每500ms闪烁一次
    task3:判断按键KEY0是否按下,按下则删掉task1
    在这里插入图片描述

3.任务创建和删除(静态方法)

  • 实验目的:学会 xTaskCreateStatic( ) 和 vTaskDelete( ) 的使用
  • 实验设计:将设计四个任务:start_task、task1、task2、task3
    start_task:用来创建其他的三个任务
    task1:实现LED0每500ms闪烁一次
    task2:实现LED1每500ms闪烁一次
    task3:判断按键KEY0是否按下,按下则删掉task1
    在这里插入图片描述

4.总结

  • 在实际的应用中,动态方式创建任务是比较常用的,除非有特殊的需求,一般都会使用动态方式创建任务
  • 静态创建:可将任务堆栈放置在特定的内存位置,并且无需关心对内存分配失败的处理
  • 临界区保护,保护那些不想被打断的程序段,关闭freertos所管理的中断,中断无法打断,滴答中断和PendSV中断无法进行不能实现任务调度

以下是动态创建任务和静态创建任务的区别

动态创建静态创建
TCB与堆栈内存自动分配手动分配
TCB与任务句柄的关系句柄是动态TCB的指针与静态TCB无特定关系
返回值BaseType_tTaskHandle_t(句柄)
创建流程-额外定义空闲任务与定时器任务(可选)
任务删除NULL空闲任务删除
非NULL直接删除
手动删除
其他-不用担心内存分配失败

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

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

相关文章

[Kubernetes]Kubeflow Pipelines - 基本介绍与安装方法

1. 背景 近些年来,人工智能技术在自然语言处理、视觉图像和自动驾驶方面都取得不小的成就,无论是工业界还是学术界大家都在惊叹一个又一个的模型设计。但是对于真正做过算法工程落地的同学,在惊叹这些模型的同时,更多的是在忧虑如…

【论文阅读】Deep Instance Segmentation With Automotive Radar Detection Points

基于汽车雷达检测点的深度实例分割 一个区别: automotive radar 汽车雷达 : 分辨率低,点云稀疏,语义上模糊,不适合直接使用用于密集LiDAR点开发的方法 ; 返回的物体图像不如LIDAR精确,可以…

Redis追本溯源(四)集群:主从模式、哨兵模式、cluster模式

文章目录 一、主从模式1.主从复制——全量复制2.主从复制——增量复制 二、哨兵模式1.实时监控与故障转移2.Sentinel选举领导者 三、cluster模式1.三种分片方案2.cluster模式 Redis 有多种集群搭建方式,比如,主从模式、哨兵模式、Cluster 模式。 一、主…

15.4 【Linux】可唤醒停机期间的工作任务

15.4.1 什么是 anacron anacron 并不是用来取代 crontab 的,anacron 存在的目的就在于我们上头提到的,在处理非24 小时一直启动的 Linux 系统的 crontab 的执行! 以及因为某些原因导致的超过时间而没有被执行的调度工作。 其实 anacron 也是…

DERT:End-to-End Object Detection with Transformers

文章目录 摘要1、简介2、相关工作2.1、集合预测2.2、Transformer与并行解码2.3、目标检测 3、DETR模型3.1、目标检测集合预测损失3.2、DETR架构 4、实验4.1、与Faster R-CNN的对比4.2、消融4.3、分析4.4、用于全景分割的DETR 5、结论附录 AA.1、初步:多头注意层A.2、损失A.3、详…

Attacks in NLP

一、 Introduction NLP对抗攻击是人工智能对抗攻击的一个重要的组成部分,但是最近几年才逐渐开始兴起,究其原因在于NLP对抗攻击与传统computer vision或者audio对抗攻击有很大的不同,主要在于值空间的连续性(CV、audio&#xff0…

SpringCloud整体架构概览

什么是SpringCloud 目标 协调任何服务,简化分布式系统开发。 简介 构建分布式系统不应该是复杂的,SpringCloud对常见的分布式系统模式提供了简单易用的编程模型,帮助开发者构建弹性、可靠、协调的应用程序。SpringCloud是在SpringBoot的基…

【Wamp】安装 | 局域网内设备访问

安装教程: https://wampserver.site/article/1.html 下载 https://www.wampserver.com/en/ 安装路径上不能有中文 安装好之后图标呈绿色 放入网页文件 将网页文件放置于wamp文件夹的www子文件夹 例如:\Wamp\program\www 修改http端口 WAMP服务器…

C# 使用FFmpeg.Autogen对byte[]进行编解码

C# 使用FFmpeg.Autogen对byte[]进行编解码,参考:https://github.com/vanjoge/CSharpVideoDemo 入口调用类: using System; using System.IO; using System.Drawing; using System.Runtime.InteropServices; using FFmpeg.AutoGen;namespace F…

虚拟世界探索:科技之下的未来可能性

随着科技的飞速发展,人们对于虚拟世界的憧憬和探索也日益加深。虚拟世界,那是一个超越现实的概念,一个充满想象力和创造力的领域。然而,虚拟世界究竟有可能实现吗?这是一个引人深思的问题。 虚拟世界,首先让…

激光切割机的操作中蛙跳技术是什么意思

其实,蛙跳技术就是指在激光切割机运行的过程中,机器换位置的方式。打个比方,你刚刚在这儿把孔1切好了,接下来就得跑到那儿把孔2切了。 在这个过程中,激光切割机就像是一只青蛙,要从一个位置跳到另一个位置。…

机器学习笔记值优化算法(十四)梯度下降法在凸函数上的收敛性

机器学习笔记之优化算法——梯度下降法在凸函数上的收敛性 引言回顾:收敛速度:次线性收敛二次上界引理 梯度下降法在凸函数上的收敛性收敛性定理介绍证明过程 引言 本节将介绍梯度下降法在凸函数上的收敛性。 回顾: 收敛速度:次…

数据结构 | 二叉树的应用

目录 一、解析树 二、树的遍历 一、解析树 我们可以用解析树来表示现实世界中像句子或数学表达式这样的构造。 我们可以将((73)*(5-2))这样的数学表达式表示成解析树。这是完全括号表达式,乘法的优先级高于加法和减法,但因为有括号,所以在…

【Linux进阶之路】进程(上)

文章目录 前言一、操作系统加载过程二、进程1.基本概念2.基本信息①运行并观察进程②创建子进程③僵尸与孤儿进程(父子进程衍生出来的问题)1. 僵尸进程(Zombie状态)2. 孤儿进程 3.基本状态①操作系统的状态(统一&#…

5.利用matlab完成 符号矩阵的转置和 符号方阵的幂运算(matlab程序)

1.简述 Matlab符号运算中的矩阵转置 转置向量或矩阵 B A. B transpose(A) 说明 B A. 返回 A 的非共轭转置,即每个元素的行和列索引都会互换。如果 A 包含复数元素,则 A. 不会影响虚部符号。例如,如果 A(3,2) 是 12i 且 B A.&#xff0…

【C++】红黑树模拟实现插入功能(包含旋转和变色)

红黑树模拟实现并封装为map和set 前言正式开始红黑树概念红黑树基本要求大致框架树节点树 调整红黑树使其平衡第一种:cur红,p红,g黑,u存在且为红第二种:cur红,p红,g黑,u不存在或为黑…

CentOS7安装Maven详细教程

😊 作者: Eric 💖 主页: https://blog.csdn.net/weixin_47316183?typeblog 🎉 主题:CentOS7安装Maven详细教程 ⏱️ 创作时间: 2023年08月06日 第一步:上传或下载安装包&#x…

2021年12月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;输出整数部分 输入一个双精度浮点数f&#xff0c; 输出其整数部分。 时间限制&#xff1a;1000 内存限制&#xff1a;65536 输入 一个双精度浮点数f(0 < f < 100000000)。 输出 一个整数&#xff0c;表示浮点数的整数部分。 样例输入 3.8889 样例输出 3…

opencv实战项目 手势识别-手势控制鼠标

手势识别系列文章目录 手势识别是一种人机交互技术&#xff0c;通过识别人的手势动作&#xff0c;从而实现对计算机、智能手机、智能电视等设备的操作和控制。 1. opencv实现手部追踪&#xff08;定位手部关键点&#xff09; 2.opencv实战项目 实现手势跟踪并返回位置信息&…

设计模式--策略模式

目录 一.场景 1.1场景 2.2 何时使用 2.3个人理解 二. 业务场景练习 2.1业务: 2.2具体实现 2.3思路 三.总结 3.1策略模式的特点&#xff1a; 3.2策略模式优点 3.3策略模式缺点 一.场景 1.1场景 许多相关的类仅仅是行为有异&#xff0c;也就是说业务代码需要根据场景不…