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

news2025/2/10 7:59:29

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.coloradmin.cn/o/864547.html

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

相关文章

美团研究院:2022年剧本娱乐行业发展报告(附下载)

关于报告的所有内容,公众【营销人星球】获取下载查看 核心观点 户外赛道本质上迎合了全球共性需求的增长,在全球普遍进入大规模城市化、市场经 随着居民收入水乎提高,中国消费者日益注重精神文化生活,文化娱乐成为人们重要的体闲…

Android的学习系列之Android Studio Setup安装

Android的学习系列之Android Studio Setup安装 [TOC](Android的学习系列之Android Studio Setup安装) 前言Android平台搭建总结 前言 还是项目需要,暂时搭建安卓的运行平台。 Android平台搭建 安装包 双击安装包,进入安装。 下一步 根据自己需求&a…

kinit报错 /etc/host.conf: line 3: bad command `nospoof on‘

kinit报错 /etc/host.conf: line 3: bad command nospoof on’ linux7.5不再支持nospoof命令了, 修改/etc/host.conf注释掉nospoof on即可。

chatGPT小白快速入门培训课程-001

一、前言 本文是《chatGPT小白快速入门培训课程》的第001篇文章,全部内容采用chatGPT和chatGPT开源平替软件生成。完整内容大纲详见:《chatGPT小白快速入门课程大纲》。 本系列文章,参与: AIGC征文活动 #AIGC技术创作内容征文# …

39 printf 的输出到设备层的调试

前言 在前面 printf 的调试 我们只是调试到了 glibc 调用系统调用, 封装了参数 stdout, 带输出的字符缓冲, 以及待输出字符长度 然后内核这边 只是到了 write 的系统调用, 并未向下细看 我们这里 稍微向下 细追一下, 看看 到达设备层面 这里是怎么具体的 impl 的 测试用例…

宋浩线性代数笔记(五)矩阵的对角化

本章的知识点难度和重要程度都是线代中当之无愧的T0级,对于各种杂碎的知识点,多做题复盘才能良好的掌握,良好掌握的关键点在于:所谓的性质A与性质B,是谁推导得谁~

【ultralytics仓库使用自己的数据集训练RT-DETR】

ultralytics仓库使用自己的数据集训练RT-DETR RT-DETR由百度开发,是一款尖端的端到端物体检测器(基于transformer架构),在提供实时性能的同时保持高精度。它利用视觉变换器(ViT)的力量,通过解耦…

MongoDB的下载和安装

一、MongoD下载 下载地址:https://www.mongodb.com/try/download/community 二、安装 因为选择下载的是 .zip 文件,直接跳过安装,一步到位。 选择在任一磁盘创建空文件夹(不要使用中文路径),解压之后把文…

关于安卓打包生成aar,jar实现(一)

关于安卓打包生成aar,jar方式 背景 在开发的过程中,主项目引入三方功能的方式有很多,主要是以下几个方面: (1)直接引入源代码module(优点:方便修改源码,易于维护&#…

ChatGLM2-6B在Windows下的微调

ChatGLM2-6B在Windows下的微调 零、重要参考资料 1、ChatGLM2-6B! 我跑通啦!本地部署微调(windows系统):这是最关键的一篇文章,提供了Windows下的脚本 2、LangChain ChatGLM2-6B 搭建个人专属知识库:提供…

Linux命令200例:tree用于以树状结构显示文件和目录

🏆作者简介,黑夜开发者,全栈领域新星创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 &…

非计算机科班如何丝滑转码?

近年来,很多人想要从其他行业跳槽转入计算机领域。非计算机科班如何丝滑转码? 如何规划才能实现转码? 对于非计算机科班的人来说,想要顺利转码成为计算机相关岗位的从业者,需要经过以下几个步骤: 规划转码…

Linux如何开启指定端口号

本文已收录于专栏 《运维》 目录 概念说明防火墙端口号 提供服务具体分类具体操作防火墙操作端口号操作 总结提升 概念说明 防火墙 防火墙是一种网络安全设备或软件,用于监控和控制网络流量,保护网络免受恶意攻击和未经授权的访问。防火墙可以根据预定义…

Idea的基本使用带案例---详细易懂

一.idea是什么 有专业人士说,idea是天生适合做微软,当时我还想肯定是夸大其词了,但当你用起来的时候确实很爽,😊😊 ntelliJ IDEA是一种集成开发环境(IDE),由JetBrains开发…

游戏弱网测试之测试用例

首先来看下网络差会对游戏造成什么影响: 1、延迟大,PING值高,游戏画面不同步,各种飞天遁地 2、画面卡住。(卡住后,下场往往一言难尽) 3、显示不全 还有一些跟金钱挂钩的,充值不到账…

802.11K/V/R协议介绍

802.11K/V/R协议介绍 1.传统无线漫游介绍 1.1 什么是无线漫游 一台无线终端备(STA)通过连接Wi-Fi获取上网体验,Wi-Fi名称(又称为SSID)是由无线接入网(AP)提供的,因为一台AP设备的覆…

Pads输出器件坐标文件时,如何更改器件坐标精度

相信对于用pads软件的工程师么,在完成PCB设计的时候都需要输出生产文件给板厂和贴片厂,今天我们需要给大家介绍的是如何在在pads软件上面输出器件坐标文件以及如何更改器件坐标文件的精度。 首先我们需要点击工具-基本脚本-基本脚本接下来会跳到下面这个…

手游测试之新功能的通用测试点

当我们测试手游的一个新功能的时候,除了具体的功能需求外,也需要考虑测试点,这篇文章的目的就是为了提高测试点的覆盖率,总结的一些手游测试的通用测试点,可以拿来直接用。 一、UI 1、按钮不可拖动 按钮除了有按压效…

纯前端 -- html转pdf插件总结

一、html2canvasjsPDF(文字会被截断): 将HTML元素呈现给添加到PDF中的画布对象,不能仅使用jsPDF,需要html2canvas或rasterizeHTML html2canvasjsPDF的具体使用链接 二、html2pdf(内容显示不全文字会被截断…

【立创EDA】【1】原理图绘制常用操作

总线使用 作用:总线可以方便多个元件的连接总线必须配合总线分支使用原理图上的总线只是视觉上的效果,欲使网络完整,还需添加网络标签(如下图,未添加网络标签时,即使总线连接完成,网络依旧不完…