【Freertos基础教程】任务管理之基本使用

news2024/12/25 9:35:07

文章目录

  • 前言
  • 一、freertos任务管理是什么?
  • 二、任务管理涉及到的一些概念
    • 1.任务状态
    • 2.优先级
    • 3.栈(Stack)
    • 4.事件驱动
    • 5.协助式调度(Co-operative Scheduling)
  • 二、任务的基本操作
    • 1.创建任务
      • 什么是任务
    • 2.创建任务
    • 3.任务的删除
    • 4.任务的调度
    • 3.简单示例
  • 总结


前言

本freertos是以stm32系列为操作的

任务管理是实时操作系统(RTOS)的核心功能之一,它允许开发者以并发的方式组织和管理多个任务。FreeRTOS 是一个流行的开源RTOS,它提供了强大的任务管理功能,让开发者能够轻松创建和控制任务。本文将介绍 FreeRTOS 的任务管理功能,包括任务的创建、删除、挂起、恢复和优先级控制等方面的内容。


一、freertos任务管理是什么?

当我们编写一个程序时,通常会有多个任务需要同时执行,比如说检测传感器数据、控制执行器、处理用户输入等等。而FreeRTOS就是一个帮助我们管理这些任务的工具。

任务管理就像是一个调度员,它知道每个任务应该在什么时候执行。它可以创建任务,就像给每个人分配一个工作一样。创建一个任务就相当于告诉系统:“嘿,我有一个任务需要完成,它需要做什么事情,有多重要,还有执行的顺序。”

而任务之间可能也会有一些协作和通信的需求,比如一个任务需要等待另一个任务完成某个操作才能继续执行。FreeRTOS也提供了一些机制,让任务之间可以方便地共享数据、同步操作。

任务管理还可以通过设置任务的优先级,告诉系统哪个任务更重要。例如,一个任务负责处理实时的数据,另一个任务负责打印日志,我们可以设置实时数据任务的优先级更高,这样它就会优先执行。同时,我们还可以暂停或恢复任务的执行,例如当不需要某个任务运行时,可以将其暂停,待需要时再恢复。

总而言之,FreeRTOS的任务管理帮助我们组织、调度和控制多个任务的执行,让我们的程序能够并发地运行,提高效率和可靠性。通过合理设置任务的创建、优先级、通信和同步,我们可以构建出更加复杂和功能强大的嵌入式系统。

二、任务管理涉及到的一些概念

以日常生活为例,比如这个母亲要同时做两件事:
喂饭:这是一个任务
回信息:这是另一个任务

1.任务状态

当前正在喂饭,它是running状态;另一个"回信息"的任务就是"not running"状态
"not running"状态还可以细分:
ready:就绪,随时可以运行
blocked:阻塞,卡住了,母亲在等待同事回信息
suspended:挂起,同事废话太多,不管他了

2.优先级

我工作生活兼顾:喂饭、回信息优先级一样,轮流做
我忙里偷闲:还有空闲任务,休息一下
厨房着火了,什么都别说了,先灭火:优先级更高

3.栈(Stack)

喂小孩时,我要记得上一口喂了米饭,这口要喂青菜了
回信息时,我要记得刚才聊的是啥
做不同的任务,这些细节不一样
对于人来说,当然是记在脑子里
对于程序,是记在栈里
每个任务有自己的栈

4.事件驱动

孩子吃饭太慢:先休息一会,等他咽下去了、等他提醒我了,再喂下一口

5.协助式调度(Co-operative Scheduling)

你在给同事回信息
同事说:好了,你先去给小孩喂一口饭吧,你才能离开
同事不放你走,即使孩子哭了你也不能走
你好不容易可以给孩子喂饭了
孩子说:好了,妈妈你去处理一下工作吧,你才能离开
孩子不放你走,即使同事连发信息你也不能走

二、任务的基本操作

1.创建任务

什么是任务

在FreeRTOS中,任务就是一个函数,原型如下:

void ATaskFunction( void *pvParameters );

要注意的是:
这个函数不能返回
同一个函数,可以用来创建多个任务;换句话说,多个任务可以运行同一个函数
函数内部,尽量使用局部变量:
每个任务都有自己的栈
每个任务运行这个函数时
任务A的局部变量放在任务A的栈里、任务B的局部变量放在任务B的栈里
不同任务的局部变量,有自己的副本
函数使用全局变量、静态变量的话
只有一个副本:多个任务使用的是同一个副本
要防止冲突(后续会讲)

下面是一个示例:

void ATaskFunction( void *pvParameters )
{
	/* 对于不同的任务,局部变量放在任务的栈里,有各自的副本 */
	int32_t var = 0;
	/* 任务函数通常实现为一个无限循环 */
	while(1)
	{
	/* 任务的代码 */
	}
	/* 如果程序从循环中退出,一定要使用vTaskDelete删除自己
	* NULL表示删除的是自己
	*/
	vTaskDelete( NULL );
	/* 程序不会执行到这里, 如果执行到这里就出错了 */
}

2.创建任务

创建任务时使用的函数如下:

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 ); // 任务句柄, 以后使用
它来操作这个任务

void * const pvParameters他会他函数参数里面得到

在这个函数里面,参数void * const pvParametersTaskHandle_t * const pxCreatedTask可以不填

参数具体说明:
pvTaskCode 函数指针,可以简单地认为任务就是一个C函数。
它稍微特殊一点:永远不退出,或者退出时要调用"vTaskDelete(NULL)"

pcName
任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。
长度为:configMAX_TASK_NAME_LEN

usStackDepth
每个任务都有自己的栈,这里指定栈大小。
单位是word,比如传入100,表示栈大小为100 word,也就是400字节。
最大值为uint16_t的最大值。
怎么确定栈的大小,并不容易,很多时候是估计。
精确的办法是看反汇编码。

pvParameters 调用pvTaskCode函数指针时用到:pvTaskCode(pvParameters)
uxPriority
优先级范围:0~(configMAX_PRIORITIES – 1)
数值越小优先级越低,
如果传入过大的值,xTaskCreate会把它调整为(configMAX_PRIORITIES – 1)

pxCreatedTask
用来保存xTaskCreate的输出结果:task handle。
以后如果想操作这个任务,比如修改它的优先级,就需要这个handle。
如果不想使用该handle,可以传入NULL。

返回值
成功:pdPASS;
失败:errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY(失败原因只有内存
不足)
注意:文档里都说失败时返回值是pdFAIL,这不对。
pdFAIL是0,errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY是-1。

3.任务的删除

void vTaskDelete( TaskHandle_t xTaskToDelete )使用这个函数即可删除一个任务。
如果是NULL则删除自己

4.任务的调度

vTaskStartScheduler()使用他开启任务调度:必须要有这个,freertos才知道你创建了任务需要我来调用了

3.简单示例

在任务中,我们需要使用vTaskDelay进行延时
参数可以直接填数字,但我建议填pdMS_TO_TICKS(延时数)比较好,因为他是freertos自带的宏
vTaskStartScheduler()使用他开启任务调度:必须要有这个,freertos才知道你创建了任务需要我来调用了

void Task(void *p)
{
	int32_t *i = (int*)p;
	while(1)
	{
		printf("Count:%d\r\n",*i);
	 (*i)++;
		
		vTaskDelay(pdMS_TO_TICKS(500));
	}
	
	vTaskDelete(NULL);
}
uint32_t count = 0;
TaskHandle_t mytaskHandle;

void TaskTest(void)
{
	xTaskCreate(Task,"MyTask",50,&count,1,&mytaskHandle);
	vTaskStartScheduler();//任务调度,必须要有这个,freertos才知道你创建了任务需要我来调用了
}

调用运行后就会在串口看到打印的消息了,如下:
在这里插入图片描述

除了使用串口来观察,也可以使用HAL_GPIO_TogglePin来观测灯或者其他的一些模块来看到我们的任务效果

总结

任务管理是 FreeRTOS 提供的一个强大功能,它允许开发者以并发的方式组织和管理多个任务。通过任务的创建、删除、挂起、恢复和优先级控制等操作,开发者可以灵活地控制任务的执行顺序和调度策略,从而实现复杂的系统功能。任务通信与同步机制进一步增强了任务的协同工作能力,使任务之间能够高效地共享数据和协调操作。借助 FreeRTOS 提供的任务管理功能,开发者可以更加方便地构建实时嵌入式系统,并具备可靠性和高效性。

需要注意的是,在使用 FreeRTOS 进行任务管理时,开发者需要注意任务的资源管理、优先级设置和调度策略等方面,以确保系统能够稳定地运行,并满足实时性和响应性的要求。

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

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

相关文章

2023.8.12号论文阅读

文章目录 TriFormer: A Multi-modal Transformer Framework For Mild Cognitive Impairment Conversion Prediction摘要本文方法实验结果 SwIPE: Efficient and Robust Medical Image Segmentation with Implicit Patch Embeddings摘要本文方法实验结果 TriFormer: A Multi-mod…

【杨氏矩阵——(详细解法)】

杨氏矩阵💕 题目🕵️ 思路展示🤯 假设在二维数组arr中查找某个数input: 查找思路🧐 利用杨氏矩阵(矩阵的每行从左到右是递增的,矩阵从上到下是递增的)的特性,我们可以&a…

CentOS7连接网络

1.下载centos7镜像文件 2.安装centos7 3.修改网卡,ens33. 注意: 这里使用的是dhcp,设置IPADDR192.168.31.64一方面是为了后面使用crt或者MobaXterm连接,另一方面它和windows电脑的网卡要一致.这样才可以连接到网络.win r,输入cmd,打开命令窗口输入ipconfig.可以看到IPv4: 102…

Pytorch深度学习-----完整神经网络模型训练套路

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…

【mysql】—— 表的约束

目录 序言 (一)空属性 (二)默认值 (三)列描述 (四)zerofill (五)主键 (六)自增长 (七)唯一键 &#…

git命令使用

君子拙于不知己,而信于知己。——司马迁 清屏:clear 查看当前面板的路径:pwd 查看当前面板的文件:ls 创建文件夹:mkdir 文件夹名 创建文件:touch 文件名 删除文件夹:rm -rf 文件夹名 删除文件:r…

【双指针_盛最多水的容器_C++】

题目解析 盛最多水的容器 算法原理 向内枚举: weight一定会减小 height不是不变就是减小要求的是盛水最多的容器,那么这些枚举情况就不需要。 拿比较小的数去向内枚举,v一直在减小,所以说直接排除 编写代码 class Soluti…

【rust/egui】(一)从编译运行template开始

说在前面 rust新手,egui没啥找到啥教程,这里自己记录下学习过程环境:windows11 22H2rust版本:rustc 1.71.1egui版本:rust windows安装参考:这里本文默认读者已安装相关环境(git、vscode等) 关于egui egui …

[数据集][目标检测]钢材表面缺陷目标检测数据集VOC格式2279张10类别

数据集格式:Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):2279 标注数量(xml文件个数):2279 标注类别数:10 标注类别名称:["yueyawan",&…

【变形金刚02】注意机制以及BERT 和 GPT

一、说明 我已经解释了什么是注意力机制,以及与转换器相关的一些重要关键字和块,例如自我注意、查询、键和值以及多头注意力。在这一部分中,我将解释这些注意力块如何帮助创建转换器网络,注意、自我注意、多头注意、蒙面多头注意力…

Mysql中如果建立了索引,索引所占的空间随着数据量增长而变大,这样无论写入还是查询,性能都会有所下降,怎么处理?

索引所占空间的增长确实会对MySQL数据库的写入性能和查询性能造成影响,这主要是由于索引数据过多时会导致磁盘I/O操作变得非常频繁,从而使性能下降。为此,可以采取以下几种方式来减缓这种影响: 1. 限制索引的大小:可以…

【已成功解决】使用vpn/代理后无法正常上网/无法正常访问网站

文章目录 一、问题描述二、解决步骤三、原因分析 一、问题描述 很多同学在学习访问学校提供的资源时或者一些小伙伴在公司办公时需要使用VPN。但是当我们关闭VPN后,却发现没有办法正常连接到互联网了。 可以尝试以下方法解决,至于导致这种情况发生的原可…

SpringBoot携带Jdk绿色部署项目

文章目录 SpringBoot携带Jdk绿色部署运行项目1. 实现步骤2. 自测项目文件目录及bat文件内容,截图如下:2-1 项目文件夹列表:2-2. bat内容 SpringBoot携带Jdk绿色部署运行项目 说明: 实际应用的不方便场景:1. 实际项目…

Vue.js2+Cesium1.103.0 十、加载 Three.js

Vue.js2Cesium1.103.0 十、加载 Three.js Demo ThreeModel.vue <template><divid"three_container"class"three_container"/> </template><script> /* eslint-disable eqeqeq */ /* eslint-disable no-unused-vars */ /* eslint…

Python爬虫-抓取的目标数据为#x开头,怎么解决?

前言 本文是该专栏的第4篇,后面会持续分享python爬虫案例干货,记得关注。 在做爬虫项目的时候,有时候抓取的平台目标数据为&#x开头,如下图所示: 浏览器显示的正常数据,但通过爬虫协议获取到的网页源码数据却是以&#x开头的隐藏数据,遇到这种情况,爬虫需要怎么处…

基于扩频的数字视频水印嵌入和检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................. for j 1:length(attens…

Google FixMatch:SOTA 在半监督学习基准测试中的性能

作为当前计算机视觉应用的首选&#xff0c;深度网络通常通过监督学习&#xff08;一种需要标记数据集的方法&#xff09;来实现其强大的性能。尽管人工智能多年来取得了许多成就和进步&#xff0c;但标记数据的关键任务仍然落在人类专家身上。他们很难满足那些数据饥渴的深度网…

智慧工地管理平台源码,Spring Cloud +Vue+UniApp框架开发

智慧工地源码 智慧工地云平台源码 智慧建筑源码 互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度的收集人员、安全、环境、材料等关键业务数据&#xff0c;依托物联网、互联网&#xff0c;建立云端大数据管…

【C++】透过STL源码深度剖析及模拟实现vector

鉴于读者的响应&#xff0c;打算将文章拆分一下&#xff0c;方便观看&#xff0c;基本接口可看 深入浅出STL之vector类 一、源码引入 以下我所介绍的都是基于【SGI】版本的STL&#xff0c;对源码有兴趣的同学可以去看看 侯捷老师的《STL源码剖析》 然后呢我们就去调出【vector…

引用.so库,JNI使用方法

1、先将.so库放在libs下&#xff1a; 2、在工程模块下 的build.gradle配置&#xff1a; android的defaultConfig配置 不同的系统平台看项目需要 3、生成与so库中c文件的jni方法的一样包名的实体类以及方法 如C文件暴露的方法&#xff1a; 生成的类和包名对应为&#xff1a; …