【学习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直接删除
手动删除
其他-不用担心内存分配失败

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Golang函数以及函数和方法的区别

在接触到go之前,我认为函数和方法只是同一个东西的两个名字而已(在我熟悉的c/c,python,java中没有明显的区别),但是在golang中者完全是两个不同的东西。官方的解释是,方法是包含了接收者的函数。…

00 - 环境配置

1. 环境说明 使用git gitee 2. 安装配置 ubuntuVM-8-3-ubuntu:~/wuxiang/git$ git --version git version 2.25.1 ubuntuVM-8-3-ubuntu:~/wuxiang/git$2.1 配置user信息 ubuntuVM-8-3-ubuntu:~/wuxiang/git$ git config --global user.name wuxxxxx ubuntuVM-8-3-ubuntu:~…

maven的入门使用

maven的入门使用 1.Maven(Maven Apache)是一个流行的项目构建和管理工具,2.项目结构和POM文件:3.POM文件(Project Object Model)4.依赖管理: 在POM文件中5.生命周期和构建过程1.前言2.插件系统3…

Git 入门

一、版本控制 1.1 什么是版本控制 版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。简单说就是用于管理多人协同开…

golang协程池库tunny实践

前言 线程池大家都听过,其主要解决的是线程频繁创建销毁带来的性能影响,控制线程数量。 go协程理论上支持百万协程并发,协程创建调度的消耗极低,但毕竟也是消耗对吧。 而且协程池可以做一些额外的功能,比如限制并发&…

【PCIE体系结构十六】PCIE电源管理之ASPM

👉个人主页:highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容 参考书籍:《PCI.EXPRESS系统体系结构标准教材 Mindshare》 PCIe总线…

面试热题(两数之和)

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答…

STL初探

STL简介 STL(standard template libaray - 标准模板库)是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。 STL的一些版本 原始版本 Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,…

【UE4 RTS】07-Camera Boundaries

前言 本篇实现的效果是当CameraPawn移动到地图边缘时会被阻挡。 效果 步骤 1. 打开项目设置,在“引擎-碰撞”中,点击“新建Object通道” 新建通道命名为“MapBoundaries”,然后点击接受 2. 向视口中添加 阻挡体积 调整阻挡体积的缩放 向四…

孤立随机森林(Isolation Forest)(Python实现)

目录 1 简介 2 孤立随机森林算法 2.1 算法概述 2.2 原理介绍 2.3 算法步骤 3 参数讲解 4 Python代码实现 5 结果 1 简介 孤立森林(isolation Forest)是一种高效的异常检测算法,它和随机森林类似,但每次选择划分属性和划…

Zookeeper 面试题

一、ZooKeeper 基础题 1.1、Zookeeper 的典型应用场景 Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布和订阅。 通过对 Zookeeper 中丰富的数据节点进行交叉使用,配合 Watcher 事件通知机…

EFLFK——ELK日志分析系统+kafka+filebeat架构

环境准备 node1节点192.168.40.16elasticsearch2c/4Gnode2节点192.168.40.17elasticsearch2c/4GApache节点192.168.40.170logstash/Apache/kibana2c/4Gfilebeat节点192.168.40.20filebeat2c/4G https://blog.csdn.net/m0_57554344/article/details/132059066?spm1001.2014.30…

设计模式(2)工厂方法模式

一、 1、介绍:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说…

UML-状态图

目录 状态图 状态图的图符 状态机 状态 ​转换 电话机状态图 活动图和状态图区别: 状态图 状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的事件做出反应。通常我们创建一个UML状态…

中级课程——CSRF

文章目录 案例原理挖掘 案例 原理 挖掘 挖掘详情 首先就是对目标敏感部位进行抓包分析,比如修改信息、转账、添加信息等等。通常一个数据包HTTP请求头里边都会有一个Referer,这个需要特别去验证。比如放到Burpsuit Repeater里边去测试:去掉…

语音同声翻译软件助你跨越语言障碍

嘿,你在日常工作中是否曾经参加过跨国会议,是否也曾由于语言不通而感到尴尬?别担心,因为现在有了会议实时翻译软件,这些问题都将成为过去式!那么你知道会议实时翻译的软件有哪些吗?接下来就让我…

无涯教程-Perl - mkdir函数

描述 此功能使用MODE指定的模式创建一个名称和路径EXPR的目录,为清楚起见,应将其作为八进制值提供。 语法 以下是此函数的简单语法- mkdir EXPR,MODE返回值 如果失败,此函数返回0,如果成功,则返回1。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -w$dirname &…

【计算机视觉|生成对抗】条件生成对抗网络(CGAN)

本系列博文为深度学习/计算机视觉论文笔记,转载请注明出处 标题:Conditional Generative Adversarial Nets 链接:[1411.1784] Conditional Generative Adversarial Nets (arxiv.org) 摘要 生成对抗网络(Generative Adversarial…

最大子数组和——力扣53

文章目录 题目描述解法一 动态规划题目描述 解法一 动态规划 int maxSubArray(vector<int>& nums){int pre=0, res=nums

自动测试框架airtest应用一:将XX读书书籍保存为PDF

一、Airtest的简介 Airtest是网易出品的一款基于图像识别和poco控件识别的一款UI自动化测试工具。Airtest的框架是网易团队自己开发的一个图像识别框架&#xff0c;这个框架的祖宗就是一种新颖的图形脚本语言Sikuli。Sikuli这个框架的原理是这样的&#xff0c;计算机用户不需要…