FreeRtos中Task函数详解

news2024/11/13 11:41:32

                            前言:本篇笔记参考韦东山老师,B站视频链接放在最后。

Task任务基本概念

        在使用FreeRtos的程序中,可以创建多个Task来完成程序功能,Task是轻量级的独立执行单元,被FreeRtos的调度器管理,每个任务有着自己的执行函数还有堆栈用来存放数据,允许操作系统调度不同的任务来实现并发操作。

        //并发执行在操作系统中指的是,多个任务在同一段时间内交替切换执行。

Task任务创建

        当创建任务的时候,需要确定任务的栈大小,它用来存放切换时的局部变量,返回地址还有程序运行的数据,以保证切换任务过后的正常运行,创建任务分配栈的方式有两种,动态分配静态分配,前者什么时候用什么时候申请,不用就可以吧内存空间释放,后者在编译时或初始化时分配固定大小的内存,任务结束后栈空间空间被固定不能使用函数释放。

动态分配内存函数原型

BaseType_t xTaskCreate(
TaskFunction_t pxTaskCode,  //Task具体执行这个Function
               const char *const pcName, //Task name            
               const configSTACK_DEPTH_TYPE usStackDepth, //分配Stack的大小 单位为word,分配10代表40 Byte
               void * const pvParameters,//调用任务传入的参数
               UBaseType_t uxpriority,//Task优先级
               TaskHandle_t * const pxCreatedTask,//任务句柄用来操作任务,不想使用可以传入NULL
                        );

        函数的最后一个参数 pxCreatedTask 这个位置的参数用来填写Task任务的句柄,如果需要操作这个任务,就需要操作Handle,也就是创建任务填进去的这个句柄。

静态分配内存函数原型

TaskHandle_t xTaskCreateStatic(
    TaskFunction_t pxTaskCode,
    const char *const pcName,
    const uint32_t ulStackDepth,
    void * const pvParameters,
    UBaseType_t uxPriority,
    StackTypet * const puxStackBuffer,
    StaticTask_t * const pxTaskBuffer,
);

        创建静态任务跟动态任务不同的是,需要提前确定Buffer的大小,同时需要创建一个TCB结构体,以及一个任务句柄

动态分配内存调用实例

xTaskCreate(OLED_Test,"Task1",128,NULL,osPriorityAboveNormal5,NULL);

        这里的话,任务执行函数是不需要参数的,所以NULL,没有传参,如果执行任务需要参数还需要多个参数,改怎么办,只能在此封装,同时使用结构体的方式穿进去参数。

struct TaskPrintInfo {
	uint8_t x;
	uint8_t y;
	char name[16];
};

static struct TaskPrintInfo g_Task1Info = {0, 0, "Task1"};
static struct TaskPrintInfo g_Task2Info = {0, 3, "Task2"};
static struct TaskPrintInfo g_Task3Info = {0, 6, "Task3"};
static int g_LCDCanUse = 1;

void LcdPrintTask(void *params)
{
	struct TaskPrintInfo *pInfo = params;
	uint32_t cnt = 0;
	int len;
	
	while (1)
	{
		/* 打印信息 */
		if (g_LCDCanUse)
		{
			g_LCDCanUse = 0;
			len = LCD_PrintString(pInfo->x, pInfo->y, pInfo->name);
			len += LCD_PrintString(len, pInfo->y, ":");
			LCD_PrintSignedVal(len, pInfo->y, cnt++);
			g_LCDCanUse = 1;
		}
		mdelay(500);
	}
}
xTaskCreate(LcdPrintTask, "task3", 128, &g_Task3Info, osPriorityNormal, NULL);

静态分配内存调用实例

static StackType_t g_pucStackofTtaticTask[128]; //定义栈大小
static StaticTask_t g_TCBofStatic_Task;//定义结构体
static TaskHandle_t x_Static_Task;//定义句柄
x_Static_Task = xTaskCreateStatic(OLED_Test,"Static_Task1",128,NULL,osPriorityAboveNormal1,g_pucStackofTtaticTask,&g_TCBofStatic_Task);

        静态任务在使用的时候,需要提前创建栈的大小和定义TCB结构体,同时定义任务返回句柄,动态任务就不用了,定义的话都是使用,匿名结构体关键字去定义的。

删除Task函数

        上面有讲到,Task的创建方式有动态方式跟静态方式,二者都可以被函数删除,但是区别在于动态任务被删除之后,会自动释放栈跟TCB所占用的内存,如果是静态任务,由于给静态任务分配的栈是用户定义和分配的,就导致了在删除静态任务的时候这些栈和内存空间不会被释放,在删除之后可以考虑是否重用这些内存空间。

        同时Delete函数还有一个很重要的作用,在Task任务执行完成之后,C语言中是会返回的,但在FreeRtos操作系统的内核中,当任务结束返回的时候,Tick中断会被关闭,同时进入for(;;),死循环,这个时候没有delete这个函数,那么整个系统就会死机,不会切换Task,不会有任何响应。

函数原型        

TaskHandle_t xHandle = xTaskCreateStatic(OLED_Test,"Static_Task1",128,NULL,osPriorityAboveNormal1,g_pucStackofTtaticTask,&g_TCBofStatic_Task);
xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);
void vTaskDelete( TaskHandle_t xTaskToDelete ); 

       在对Task进行删除的时候,需要一个参数就是句柄,这个任务参数,通常用在,任务删除,任务恢复,挂起,都是通过填写这个参数来,操作对应的Task,创建静态任务的函数参数里面,没有句柄,但是在函数定义一面,其实是句柄返回值的,所以我们需要创建一个句柄,来等于这个静态函数的创建。

删除任务演示

TaskHandle_t xHandle = xTaskCreateStatic(OLED_Test,"Static_Task1",128,NULL,osPriorityAboveNormal1,g_pucStackofTtaticTask,&g_TCBofStatic_Task);//创建静态任务

xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);//创建动态任务

vTaskDelete( xSoundTaskHandle); //删除动态任务
vTaskDelete(  xHandle); //删除静态任务

        这里用句柄就能删除了。

挂起函数恢复函数

        在操作系统中Task的状态有四种 Ready(准备)Runing(运行)Block(阻塞)Suspend(挂起)四种状态之间可以相互转换,Suspend函数用来将任务调整为挂起状态,同样的挂起状态的任务使用Resume函数时候进行Ready状态。

       在Task从执行状态转换为Suspend状态的时候,会放弃cpu资源,当从Suspend状态Resume为准备状态的时候,在等待cpu资源才能,继续运行。

函数原型

void vTaskResume(TaskHandle_t xTaskToResume);
void vTaskSuspend(TaskHandle_t xTaskToSuspend);

        这里挂起,恢复任务,和上面的删除函数是一样的,参数只需要任务的句柄,然后就能对指定任务进行操作。

挂起状态和阻滞状态的区别

        这里使用Suspend函数对Task进行挂起,意味着Task被人为停止,只有等到Resume函数才能运行执行,在此期间是不能被调用的,vTaskDelay()这个延时函数会是Task放弃Cpu资源进入阻塞状态,当时间达到之后(满足条件),会自动进入就绪转态。

挂起恢复动态/静态任务

TaskHandle_t xHandle = xTaskCreateStatic(OLED_Test,"Static_Task1",128,NULL,osPriorityAboveNormal1,g_pucStackofTtaticTask,&g_TCBofStatic_Task);//创建静态任务

xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);//创建动态任务

vTaskSuspend( xSoundTaskHandle); //挂起动态任务
vTaskResume(xSoundTaskHandle);//恢复动态任务

vTaskSuspend(  xHandle); //删除静态任务
vTaskResume( xHandle);//恢复动态任务

Task延时函数

       在FreeRtos里面有三种延时函数 Delay( ) vTaskDelay()   vTaskDelayUntil() 前者是不同延时,当Task使用 Delay( )的时候,Task会拿着cpu资源等待时间到来,等的时候cpu资源不会分配出去,当Task使用 vTaskDelay() 的时候,执行这个语句的时候,Task会进入阻塞状态,交出CPU资源,等在时间结束,进入就绪状态,按照优先级在此分配CPU资源,当Task使用 vTaskDelayUntil()  的时候,这个延时叫做绝对延时,区别在于,带上Task执行时间一共延时多长时间,当Task执行时间短,vTaskDelayUntil()会多延时,达到固定时间,如果长,vTaskDelayUntil()会短延时,从而达到延时绝对时间的目的。

函数原型

void vTaskDelay( const TickType_t xTicksToDelay );
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );

[5-3]_删除任务_用遥控器控制音乐_哔哩哔哩_bilibili

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

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

相关文章

从零开始手搓Transformer#Datawhale组队学习Task1#

从零开始手搓Transformer 目录 缩放点积注意力DotProductAttention 多头注意力Multi-Head Attention 位置编码Position Encoder 前馈神经网络FFN 残差连接和层归一化(Add&Norm) 编码器Encoder 解码器Decoder 编码器-解码器Encoder-Decoder …

pg入门3—详解tablespaces2

pg默认的tablespace的location为空,那么如果表设置了默认的tablespace,数据实际上是存哪个目录的呢? 在 PostgreSQL 中,如果你创建了一个表并且没有显式指定表空间(tablespace),或者表空间的 location 为…

ISSTA 2024盛大开幕:中国学者的录取数和投稿量均位列第一

随着夏日的尾声,全球软件测试领域的专家和学者齐聚在奥地利维也纳。共同参与这场科技盛宴——ISSTA 2024。这场国际会议正如火如荼地进行中,吸引了来自世界各地的专业人士参与。 会议实况: 9月16日与17日,大会安排了丰富的社交活…

Qt:懒汉单例(附带单例使用和内存管理)

前言 本文主要写懒汉单例以及单例的释放,网上很多教程只有单例的创建,但是并没有告诉我们单例的内存管理,这就很头疼。 正文 以下是两种懒汉单例的写法 1. 懒汉式单例(多线程不安全,但是在单线程里面是安全的&…

【828华为云征文|华为云Flexus X实例部署指南:轻松搭建可道云KODBOX项目】

文章目录 华为云 Flexus X 实例:引领高效云服务的新时代部署【可道云KODBOX】项目准备工作具体操作指南服务器环境确认宝塔软件商店操作域名解析可道云KODBOX登录页效果验证 总结 华为云 Flexus X 实例:引领高效云服务的新时代 在云计算领域&#xff0c…

【UE5】使用2DFlipbook图作为体积纹理,实现实时绘制体积纹理【第一篇】

这是一篇对“Creating a Volumetric Ray Marcher-Shader Bits”的学习心得 文章时间很早,因此这里针对UE5对原文做出兼容性修正(为避免累赘不做出注明。链接如上,有需要自行学习) 以及最后对Custom做可能的蓝图移植,做…

虚拟机与物理机的文件共享

之前往虚拟机里传文件都是直接拖拽或者借助工具上传,都不太方便,倘若物理机的文件直接能在虚拟机里读取使用,那多好啊~ 1 虚拟机设置 注意文件夹名称不要中文/空格 2 验证Kali下分享文件夹功能是否启用 vmware-hgfsclient 3 创建挂载目录…

【踩坑】utools黑框和chrome白屏

记录一下bug,后面找到解决方案再同步 刚开机会黑框,但是输入wx能正常打开,功能一切正常 过一段时间会恢复正常 chrome会白屏 过一段时间恢复正常,大概是utools恢复正常时间的三倍 猜测是前两天关机时提示xx应用阻止关机&#…

旷视轻量化网络shufflenet算法解读

目录 预备知识 1. 回顾MobileNet V1的核心思想---深度可分离卷积 2.ShuffleNet主要有两个创新点 2.1 分组卷积与11分组卷积 2.2 channel Shuffle(通道重排) 2.3 通道重排过程 3. ShuffleNet网络结构 3.1 ShuffleNet unit 3.2 不同分组数的Shu…

Mamba YOLO World

论文地址:https://arxiv.org/pdf/2409.08513v1 代码地址: GitHub - Xuan-World/Mamba-YOLO-World: Mamba-YOLO-World: Marrying YOLO-World with Mamba for Open-Vocabulary Detection 开集检测(OVD)旨在检测预定义类别之外的物体…

上海做网站公司发展分析报告

上海网站公司发展分析报告 一、行业概况 上海作为中国的经济、金融和科技中心,其网站开发行业在近年来迅速发展。根据统计数据,当地的网站公司数量逐年增加,涵盖了企业网站、电子商务平台、移动应用开发等多个领域。随着互联网技术不断演进&…

维钧团队与广东能源集团携手共创未来

2024 年 9 月 19日,能源与投资领域传出一则令人振奋的消息——多元化投资团队维钧团队与广东能源集团正式达成合作,如同璀璨星辰交汇,开启了双方共同发展的壮丽新篇章。 维钧团队,以其敏锐专业的投资眼光、灵活多元的投资策略和卓…

大牛直播SDK核心音视频模块探究

技术背景 视沃科技旗下”大牛直播SDK”,始于2015年,致力于传统行业极致体验的音视频直播技术解决方案,产品涵盖跨平台的实时RTMP推流、RTMP/RTSP直播播放(支持RTSP|RTMP H.265,Enhanced RTMP H.265)、GB28181设备接入、推送端播放…

redis为什么不使用一致性hash

Redis节点间通信时,心跳包会携带节点的所有槽信息,它能以幂等方式来更新配置。如果采用 16384 个插槽,占空间 2KB (16384/8);如果采用 65536 个插槽,占空间 8KB (65536/8)。 今天我们聊个知识点为什么Redis使用哈希槽而不是一致性…

Llama 3.1 Omni:颠覆性的文本与语音双输出模型

你可能听说过不少关于语言模型的进展,但如果告诉你,有一种模型不仅能生成文本,还能同时生成语音,你会不会觉得特别酷?今天咱们就来聊聊一个相当前沿的项目——Llama 3.1 Omni模型。这个模型打破了传统的文字生成边界,直接让文本和语音同时输出,实现了真正的"多模态…

【mac】MacOS无法打开XXX文件,因为无法验证开发者的问题解决

博主介绍: 大家好,我是想成为Super的Yuperman,互联网宇宙厂经验,17年医疗健康行业的码拉松奔跑者,曾担任技术专家、架构师、研发总监负责和主导多个应用架构。 技术范围: 目前专注java体系,以及…

OpenCv(一)

计算机视觉和机器视觉的区别 计算机视觉(Computer Vision)和机器视觉(Machine Vision)是两个密切相关但又有区别的领域。两者在应用、技术和目标上都有所不同。 **计算机视觉:**主要是研究如何使计算机能够理解和处理…

单细胞代谢组学数据分析利器---SCMeTA

今天继续进行新的分享,为了支持单细胞代谢研究的严谨性和可重复性 ,今天分享基于时间序列的单细胞代谢数据分析处理工作流程,名为 SCMeTA。它保留了可扩展的接口和插件系统,以适应来自各种仪器的数据。对从 QE-Orbitrap MS 获取的…

2024最新的软件测试面试八股文(答案+文档)

一、软件测试基础面试题 1、阐述软件生命周期都有哪些阶段? 常见的软件生命周期模型有哪些? 软件生命周期是指一个计算机软件从功能确定设计,到开发成功投入使用,并在使用中不断地修改、增补和完善,直到停止该软件的使用的全过程(从酝酿到…

黑马头条APP手工测试项目

1.app有关概念 APP测试范围: 业务功能测试 专项测试:兼容性测试 、安装/卸载/升级测试、交叉事件测试 、push消息推送测试、性能测试、其他测试(用户体验、权限/边界、权限) 功能测试测试对象: 功能点(单…