FreeRTOS——任务创建(静态、动态创建)、任务删除以及内部实现剖析

news2024/12/23 13:42:52

任务创建和删除的API函数

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

API函数描述
xTaskCreate()动态方式创建任务
xTaskCreateStatic()静态方式创建任务
vTaskDelete()删除任务

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

静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供

动态创建任务函数

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, // 函数指针, 任务函数
                        const char * const pcName, // 任务的名字
                        const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位为word,10表示40字节
                        void * const pvParameters, // 调用任务函数时传入的参数
                        UBaseType_t uxPriority,    // 优先级
                        TaskHandle_t * const pxCreatedTask ); // 任务句柄, 以后使用它来操作这个任务

注意:pcName的长度根据在FreeRTOSConfig.h中不同定义而不同

对于32位计算机,1字=32位=4字节

返回值描述
pdPASS任务创建成功
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY任务创建失败

实现动态创建任务流程

1、将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1

2、定义函数入口参数

3、编写任务函数

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

静态创建任务函数

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,/*任务控制块指针,由用户分配*/
);
返回值描述
NULL用户没有提供相应的内存,任务创建失败
其他值任务句柄,任务创建成功

实现静态创建任务流程

1、将宏configSUPPORT_STATIC_ALLOCATION配置为1

2、定义空闲任务&定时器任务的任务堆栈及TCB

3、实现两个接口函数(vApplicationGetIdle TaskMemory()、vApplicationGetTimerTaskMemory())空闲任务和软件定时器的内存赋值

4、定义函数入口参数

5、编写任务函数

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

 任务删除函数

void vTaskDelete(TaskHandle_t xTaskToDelete);

形参描述
xTaskToDelete待删除任务的任务句柄

用于删除已经被创建的任务。

被删除的任务从就绪任务列表、阻塞态任务列表、挂起态任务列表和事件列表中删除

注意:

1、当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)自杀。

2、空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存,则需要由用户在任务被删除前提前释放,否则将其导致内存泄漏。

例如:我们动态创建了两个任务Task1和Task2,在Task1中调用删除函数,参数为Task2,则系统给Task2分配的内存在Task1中释放;如果参数为NULL,系统为Task1分配的内存在空闲任务中释放;

而静态创建的任务,用户自己申请的内存需要在任务删除前用户自己去提前释放,否则会导致内存泄漏。

删除任务流程

1、使用删除任务函数,需将宏INCLUDE_vTaskDelete配置为1

2、入口参数输入需要删除的任务句柄(NULL代表删除本身)

内部实现过程:

1)获取所要删除的任务控制块,(通过传入的任务句柄,判断所需要删除拿个任务,NULL代表删除本身,任务句柄是指向任务控制块的指针)

2)将被删除任务,移除所在列表(将该任务在所在列表中移除,包括:就绪、阻塞、挂起、事件等列表)

3)判断所需要删除的任务(将任务自身,需先添加到等待删除列表、内存释放将在空闲任务执行;删除其他任务,释放内存,任务数量--)

4)更新下个任务的阻塞时间(更新下一个任务的阻塞超时时间,以防被删除的任务就是下一个阻塞超时的任务)

实战编程

 1、实验目的:学会xTaskCreate()和vTaskDelete()的使用

2、实验设计:将设计四个任务:start task、task1、task2、task3

四个任务的功能如下:

start_task:用来创建其他的三个任务,只执行一次,执行完毕后调用vTaskDelete()自杀

task1:实现LED0每500ms闪烁一次

task2:实现LED1每500ms闪烁一次

task3:判断按键KEY0是否按下,按下删除task1

步骤:

(1)将支持动态创建任务的宏置1

(2)创建任务入口

(3)在main函数前进行一些宏定义以及函数声明

 (4)编写start_task的任务函数

 (5)宏定义三个任务的优先级、栈深度、定义任务句柄以及任务函数的声明

(6)编写三个任务的任务函数

 

 优先级数字越大,优先级越高。

但是执行的顺序却是task1、task2、task3,为什么呢?

start_task创建之后开始调度,开始执行,创建task1此时task1的优先级比start高,创建完之后执行task1,task1延时阻塞之后,返回低优先级任务start执行,创建task2,task2优先级高于start,执行task2,task2延时阻塞后,返回低优先级任务start执行,创建task3,task3阻塞之后返回低优先级任务start,start创建完三个task之后自杀。

 taskENTER_CRITICAL();           //进入临界区

这句代码的作用是关闭中断,任务切换是在中断里面进行,这时我们关闭中断,任务切换就不会再进行。

 创建任务其内部实现

1、申请堆栈内存(返回首地址)

2、申请任务控制块内存(返回首地址)

3、把前面申请的堆栈地址,赋值给控制块的堆栈成员

4、调用prvInitialiseNewTask初始化任务控制块里面的成员

5、调用prvAddNewTaskToReadyList添加新创建任务到就绪列表中

动态创建时定义任务句柄指向该任务TCB结构体,在prvInitialiseNewTask中,TCB结构体中存储对应任务的状态、优先级等信息,存储完信息之后就将该TCB任务控制块作为参数传递给prvAddNewTaskToReadyList

剖析 prvInitialiseNewTask

 

 

 然后就初始化任务栈

步骤总结:

 

 剖析prvAddNewTaskToReadyList

私有函数初始化列表prvInitialiseTaskLists()

 接下来的操作:

步骤总结: 

 

 删除任务内部实现

 

 如果要删除的任务是当前正在执行的任务,则其分配的空间不能直接释放,需要在空闲函数执行的时候进行释放,空闲任务的创建在开启调度的函数中可以找到,然后通过任务创建函数可以跳转到空闲任务函数,在函数体中找到下面的函数,就可以看到删除自身函数的具体过程:

步骤总结: 

 

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

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

相关文章

考研代码题:10.10 汉诺塔 爬楼梯 取球 猴子吃桃

汉诺塔 C语言 - 汉诺塔详解&#xff08;最简单的方法&#xff0c;进来看看就懂&#xff09;_汉诺塔c语言程序详解-CSDN博客 #include <stdio.h>void move(char begin,char end){printf("%c->%c\n",begin,end); } //begin开始杆&#xff0c;help辅助杆&am…

BUU刷题-Pwn-axb_2019_mips(MIPS跳转bss段执行shellcode)

解题所涉知识点&#xff1a; 泄露或修改内存数据&#xff1a; 堆地址&#xff1a;栈地址&#xff1a;libc地址&#xff1a;BSS段地址&#xff1a; 劫持程序执行流程&#xff1a;MIPS_ROP 获得shell或flag&#xff1a;[[MIPS_Shellcode]] && [[MIPS劫持RA寄存器]] 题…

开源文件管理工具File Browser本地部署并一键发布公网远程传输文件

文章目录 前言1.下载安装File Browser2.启动访问File Browser3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 File Browser是一个开源的文件管理器和文件共享工具&#xff0c;它可以帮助用户轻…

波轮洗衣机、滚筒洗衣机的清理方法

洗衣机主要分为波轮式、滚筒式这2种&#xff0c;波轮式是水平旋转的&#xff0c;滚筒式是竖直旋转的。波轮式洗衣机一般比较小&#xff0c;用于2至3个人的衣服清理&#xff1b;而滚筒式洗衣机则比较大&#xff0c;用于5至6人的衣服清理。 图(1) 波轮洗衣机 图(2) 滚筒洗衣机 不…

龋齿牙齿病变图像分割系统源码&数据集分享

龋齿牙齿病变图像分割系统源码&#xff06;数据集分享 [yolov8-seg-C2f-DCNV3&#xff06;yolov8-seg-RepHGNetV2等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Glo…

发送邮件和随机码的生成

类视图和方法视图区别&#xff1a; 不需要装饰器&#xff0c;只需要继承MethodView,需要使用什么方式就写对应的方法名称&#xff0c;它就能自动匹配 app.route("/delete/",methods["DELETE"])这些就不用写了 但是不写装饰器并不意味着不写路由了&#xff…

高效美发店运营:SpringBoot管理系统详解

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理美发门店管理系统的相关信息成为必然。开发…

k8s部署学习

8s的架构 一个kubernetes集群主要是由控制节点(master)、工作节点(node)构成&#xff0c;每个节点上都会安装不同的组件 1 master&#xff1a;集群的控制平面&#xff0c;负责集群的决策 ApiServer : 资源操作的唯一入口&#xff0c;接收用户输入的命令&#xff0c;提供认证、…

MediaPlayer视频播放流程

MediaPlayer视频播放流程(基于Android8.0) 1. MediaPlayer源码分析 1.0 public class MediaPlayer extends PlayerBase implements SubtitleController.Listener, VolumeAutomation, AudioRoutingMediaPayer继承自PlayerBase类&#xff0c;分别实现了SubtitleController Volume…

运筹说 第126期 | 存储论经典例题讲解——随机存储模型

通过上一期&#xff0c;我们已经学习了确定型存储论模型在经济管理中的应用&#xff0c;但其忽略了现实中的随机性和不确定性因素&#xff0c;本期小编选择了一些考虑不确定因素的随机存储模型的典型例题&#xff0c;进行详细讲解。 单周期的随机型存储模型 单周期的随机型存储…

基于springboot模式花店网站的设计与实现(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

《Linux从小白到高手》进阶实操篇:详解Linux系统调优之服务器硬件优化

List item 本篇介绍Linux服务器硬件调优。硬件调优主要包括CPU、内存、磁盘、网络等关键硬件组。 1. CPU优化 选择适合的CPU&#xff1a; –根据应用需求选择多核、高频的CPU&#xff0c;以满足高并发和计算密集型任务的需求。CPU缓存优化&#xff1a; –确保CPU缓存&#x…

【onnx模型转kmodel】记录和踩坑——nncase-v1.9使用

最近几天一直在找相关资料&#xff0c;坑太多&#xff0c;也可能我菜的成分更多一点吧&#xff01;记录下来&#xff0c;以观后用&#xff1b; 背景 我手里有一个正点原子的K210的开发板&#xff1b; 刚刚安装了wsl2下的ubuntu22.04 我手里有正点原子的源码&#xff0c;但是…

【Redis入门到精通十一】Redis集群

目录 集群 1.三种分片算法 1.哈希求余算法 2.一致性哈希算法 3.哈希槽分区算法 2.搭建集群环境 3.集群故障处理 4.集群扩容 集群 上篇文章我们了解Redis哨兵的相关操作&#xff0c;使用哨兵只是解决了主节点瘫痪&#xff0c;从节点不能自动变为主节点的问题&#xff0c;…

[ComfyUI]太赞了!阿里妈妈发布升级版 Flux 图像修复模型,更强细节生成,更高融合度以及更大分辨率支持

小伙伴们还记得我们之前介绍的阿里妈妈发布的 Flux 的 ControlNet 图像修复模型不&#xff0c;之前发布的是 Alpha 早期测试版本&#xff0c;说实话和 Flux 原生的重绘其实差距不大&#xff0c;有些方面甚至还是原生的效果更好。 但是现在&#xff0c;Alpha 的升级版本 Beta 版…

基于java的零食销售系统(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

qt小练习

制作简易闹钟 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> //定时器类 #include <QDebug> //信息调试类 #include <QMessageBox> //消息对话框类 #include <QTime> //时间类 #include…

【C语言复习】常见概念(零基础)

【C语言复习】常见概念 1、C语言是什么&#xff1f;2、C语言的历史和辉煌3、 编译器的选择VS20223.1编译和链接3.2编译器的对比3.3 VS2022 的优缺点 4、VS项⽬ 和 源⽂件、头⽂件介绍5、第一个C语言程序6、main函数&#xff08;主函数&#xff09;7、printf和库函数8、关键字介…

基于springboot的大学生体质测试管理系统(含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于springboot的大学生体质测试管理系统1拥有三种角色 管理员&#xff1a;学生管理、教师管理、日常运行管理、运动分析管理、成绩管理、论坛管理、轮播图管理等 教师&#xff1a;登录…

如何在RuoYi-Vue项目中去除`/dev-api`前缀

前言 在使用RuoYi-Vue框架进行Web应用开发时&#xff0c;有时会遇到API路径需要特定前缀的问题。例如&#xff0c;在某些情况下&#xff0c;开发者可能希望移除或更改默认的/dev-api前缀。 问题描述 当使用YApi直接请求后台接口时&#xff0c;无需添加/dev-api前缀。在生成和…