FreeRTOS(任务管理的创建、删除、挂起、恢复)

2023-10-26

目录

一、任务的基本概念

二、任务状态的概念

1、Running—运行态:

2、Ready—就绪态

3、Blocked—阻塞态

4、Suspended—挂起态

三、任务状态的切换

 四、系统启动

1、vTaskStartScheduler()函数

1.1 作用

1.2 启动函数介绍

 2、空闲任务

2.1 空闲任务的作用

五、任务创建

5.1 创建任务的方式

5.2 动态创建任务函数详解

5.3 使用举例

六、任务删除

6.1 删除任务函数详解

6.2 使用举例

七、任务挂起

7.1 挂起任务函数详解

7.2 使用举例

八、任务恢复(普通方式与中断方式)

8.1 普通方式恢复任务函数详解

8.2 中断方式恢复任务函数详解

九、任务管理编程

9. 1 cube配置

 9.2 手动创建任务

9.3 手动删除、挂起任务

9.4 手动创建、恢复任务

资料来源于硬件家园FreeRTOS实时操作系统第四讲 - 任务管理(创建,删除,挂起,恢复) (qq.com)

一、任务的基本概念

1、从系统的角度看,任务是竞争系统资源的最小运行单元。

2、FreeRTOS是一个支持多任务的操作系统,在FreeRTOS中,任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其他任务运行。

3、每个任务在自己的环境中运行,在任何时刻,只有一个任务得到运行,FreeRTOS调度器决定运行哪个任务。调度器会不断的启动、停止每一个任务,宏观上看,所有的任务都在同时进行。

4、在FreeRTOS中,每个任务都有自己的栈空间(一段连续的内存),用于保存任务运行环境。任务越多,需要的栈空间就越大,而一个系统能运行多少个任务,取决于系统可用的内存。

5、任务通常会运行在一个死循环中,不会退出,如果不需要某个任务,可以调用FreeRTOS中的删除任务API函数将任务删除,释放系统资源。

二、任务状态的概念

FreeRTOS系统中的任务有四种状态:

1、Running—运行态:

当任务处于实际运行时被称之为运行态,即 CPU 的使用权被这个任务占用。

2、Ready—就绪态

处于就绪态的任务是指那些能够运行(没有被阻塞和挂起),但是当前没有运行的任务,因为同优先级或更高优先级的任务正在运行。

3、Blocked—阻塞态

由于等待信号量,消息队列,事件标志组等而处于的状态被称之为阻塞态,另外任务调用延迟函数也会处于阻塞态。

4、Suspended—挂起态

类似阻塞态,通过调用函数 vTaskSuspend()对指定任务进行挂起,挂起后这个任务将不被执行,只有调用函数 xTaskResume()才可以将这个任务从挂起态恢复。

三、任务状态的切换

图片

 四、系统启动

1、vTaskStartScheduler()函数

/*Start scheduler */
osKernelStart();
osStatus osKernelStart (void)l{
vTaskStartScheduler();
return osOK;
}

1.1 作用

启动 FreeRTOS调度

1.2 启动函数介绍

函数原型:void vTaskStartScheduler( void );

函数描述:函数 vTaskStartScheduler 用于启动 FreeRTOS 调度器,即启动 FreeRTOS 的多任务执行。

使用这个函数要注意以下几个问题:

①空闲任务和可选的定时器任务是在调用这个函数后自动创建的。

②正常情况下这个函数是不会返回的。如果有返回,极有可能是用于定时器任务或者空闲任务的内存空间不足造成创建失败,此时需要加大FreeRTOS可管理的内存空间。

图片

 2、空闲任务

空闲任务是FreeRTOS系统中没有其它任务运行时自动进入的系统任务,不需要用户创建,启用调度器时,调度器会自动创建空闲任务。

图片

2.1 空闲任务的作用

① 执行删除任务时,系统并不会立即释放任务的内存空间,只会将任务添加到结束列表中,真正的系统资源回收工作在空闲任务中完成。

②可以在空闲任务中实现低功耗功能。

五、任务创建

5.1 创建任务的方式

① 静态创建任务,xTaskCreateStatic(),需要自行定义任务栈空间与任务控制块,一般不采用,不作介绍。

②动态创建任务,xTaskCreate(),系统动态分配任务栈空间与任务控制块,应用采用此方式。

5.2 动态创建任务函数详解

函数原型:

图片

函数描述:函数 xTaskCreate 用于实现 FreeRTOS 操作系统的任务创建,并且还可以自定义任务栈的大小。

①第 一 个参数填创建任务的函数名

②第 二 个参数是任务名,这个参数主要用于调试的时候方便看是哪个任务

③第 三 个参数是任务栈大小,单位 word,也就是 4 字节

④ 第 四 个参数是创建的任务函数的形参

⑤第 五 个参数是定义任务优先级

⑥第 六 个参数是任务句柄,用于区分不同的任务

5.3 使用举例

图片

STM32cubeMX创建方法:

图片

方法详解:

① 首先利用宏定义定义任务参数结构体变量

图片

图片

#name:将name转化为字符串,等效于"name"

os_thread_def__name:将name以字符串方式拼接,等效于"os_thread_def_name"

① 调用动态创建函数创建任务,形参为上面的结构体地址

图片

图片

图片

六、任务删除

6.1 删除任务函数详解

函数原型:void vTaskDelete( TaskHandle_t xTask ); /* 任务句柄 */ 

函数描述:函数 vTaskDelete 用于实现 FreeRTOS 操作系统的任务删除。 

①第 1 个参数填要删除任务的句柄

使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_vTaskDelete 1

②  如果用往此函数里面填的任务 ID 是 NULL,即数值 0 的话,那么删除的就是当前正在执行的任务,此任务被删除后,FreeRTOS 会切换到任务就绪列表里面下一个要执行的最高优先级任务。

③ 在 FreeRTOS 中,创建任务所需的内存需要在空闲任务中释放,如果用户在 FreeRTOS 中调用了这个函数的话,一定要让空闲任务有执行的机会,否则这块内存是无法释放的。另外,创建的这个任务在使用中申请了动态内存,这个内存不会因为此任务被删除而删除,这一点要注意,一定要在删除前将此内存释放。

6.2 使用举例

图片

七、任务挂起

7.1 挂起任务函数详解

函数原型:void vTaskSuspend( TaskHandle_t xTaskToSuspend); /* 任务句柄 */ 

函数描述:函数 vTaskSuspend 用于实现 FreeRTOS 操作系统的任务挂起。 

第 1 个参数填要挂起任务的句柄

 使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_vTaskSuspend 1

如果用往此函数里面填的任务 ID 是 NULL,即数值 0 的话,那么挂起的就是当前正在执行的任务,此任务被挂起后,FreeRTOS 会切换到任务就绪列表里面下一个要执行的高优先级任务。

③ 多次调用此函数的话,只需调用一次 vTaskResume 即可将任务从挂起态恢复。

7.2 使用举例

图片

八、任务恢复(普通方式与中断方式)

8.1 普通方式恢复任务函数详解

函数原型:void vTaskResume( TaskHandle_t xTaskToResume); /* 任务句柄 */ 

函数描述:函数 vTaskResume 用于实现 FreeRTOS 操作系统的任务挂起

①第 1 个参数填要恢复任务的句柄

使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_vTaskSuspend  1

② 多次调用函数 vTaskSuspend 的话,只需调用一次 vTaskResume 即可将任务从挂起态恢复。

此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用的xTaskResumeFromISR(),以后缀 FromISR 结尾。

使用举例:

图片

8.2 中断方式恢复任务函数详解

函数原型:BaseType_t  vTaskResumeFromISR( TaskHandle_t xTaskToResume); /* 任务句柄 */ 

函数描述:函数 vTaskResumeFromISR 用于实现 FreeRTOS 操作系统的任务恢复。

①第 1 个参数填要恢复任务的句柄

使用这个函数要注意以下问题:

① 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1#define INCLUDE_xResumeFromISR 1

② 多次调用函数 vTaskSuspend 的话,只需调用一次 vTaskResumeFromISR 即可将任务从挂起态恢复。

③ 如果用户打算采用这个函数实现中断与任务的同步,要注意一种情况,如果此函数的调用优先于函数vTaskSuspend 被调用,那么此次同步会丢失,这种情况下建议使用信号量来实现同步。

④此函数是用于中断服务程序中调用的,故不可以在任务中使用此函数,任务中使用的是 vTaskResume。

使用举例:

图片

九、任务管理编程

9. 1 cube配置

修改FreeRTOS_Debug的配置

修改内存分配方式为动态分配

 9.2 手动创建任务

在freertos.c中进行定义

①定义句柄

/* USER CODE BEGIN Variables */
extern volatile uint32_t CPU_RunTime;
osThreadId KEY1Handle;
/* USER CODE END Variables */

②定义入口函数

/* USER CODE BEGIN FunctionPrototypes */
void KEY1_Task(void const * argument);
/* USER CODE END FunctionPrototypes */

③创建任务

  /* USER CODE BEGIN RTOS_THREADS */
  osThreadDef(KEY1, KEY1_Task, osPriorityIdle, 0, 128);
  KEY1Handle = osThreadCreate(osThread(KEY1), NULL);
  /* USER CODE END RTOS_THREADS */

 ④入口函数实现

/* USER CODE BEGIN Application */
void KEY1_Task(void const * argument)
{
  /* USER CODE BEGIN KEY1_Task */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END KEY1_Task */
}
/* USER CODE END Application */

9.3 手动删除、挂起任务

void KEY0_Task(void const * argument)
{
  /* USER CODE BEGIN KEY0_Task */
  /* Infinite loop */
  for(;;)
  {
	int KeyState=0;
	//按键检测
	if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET)
	{
		KeyState=1;
		while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==GPIO_PIN_RESET)
		{
			osDelay(20);//必须用阻塞延时
		}
	}
	if(KeyState)
	{
		vTaskSuspend(LED1Handle);//挂起LED1_Task
		HAL_UART_Transmit(&huart2,(uint8_t*)"KEY0 depress... \r\n", 20, HAL_MAX_DELAY);
		if(LED0Handle != NULL)
		{
			vTaskDelete(LED0Handle);
			LED0Handle=NULL;
			HAL_UART_Transmit(&huart2,(uint8_t*)"delete LED0_Task... \r\n", 20, HAL_MAX_DELAY);
		}
		else
		{
			HAL_UART_Transmit(&huart2,(uint8_t*)"None LED0_Task... \r\n", 20, HAL_MAX_DELAY);
		}
	}
    osDelay(1);
  }
  /* USER CODE END KEY0_Task */
}

9.4 手动创建、恢复任务

void KEY1_Task(void const * argument)
{
  /* USER CODE BEGIN KEY1_Task */
  /* Infinite loop */
  for(;;)
  {
	int KeyState=0;
	//按键检测
	if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_RESET)
	{
		KeyState=1;
		while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)==GPIO_PIN_RESET)
		{
			osDelay(20);//必须用阻塞延时
		}
	}
	if(KeyState)
	{
		vTaskResume(LED1Handle);//恢复LED1_Task
		HAL_UART_Transmit(&huart2,(uint8_t*)"KEY1 depress... \r\n", 20, HAL_MAX_DELAY);
		if(LED0Handle == NULL)
		{
			  osThreadDef(LED0, LED0_Task, osPriorityNormal, 0, 128);
			  LED0Handle = osThreadCreate(osThread(LED0), NULL);
			if(LED0Handle!=NULL)
			HAL_UART_Transmit(&huart2,(uint8_t*)"LED0_Task create success... \r\n", 20, HAL_MAX_DELAY);
		}
		else
		{
			HAL_UART_Transmit(&huart2,(uint8_t*)"exist LED0_Task ... \r\n", 20, HAL_MAX_DELAY);
		}
	}
    osDelay(1);
  }
  /* USER CODE END KEY1_Task */
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS(任务管理的创建、删除、挂起、恢复) 的相关文章

  • getch()、_sleep() 函数的正确用法

    前段时间由于需要 写了一段代码 用到了函数 getch 但是当时出错了 提示该标识符未被定义 一时无解 后来又有一个朋友 问我怎么将一个字符串中的字符以一种动态的方式进行输出 我当时告诉他的是使用 sleep 函数 也没有细想 后来发现 根

随机推荐

  • 反汇编 之thiscall约定

    thiscall是C 中的非静态类成员函数的默认调用约定 对象的每个函数隐含接收this参数 采用thiscall约定时 函数的参数按照从右到左的顺序入栈 被调用的函数在返回前清理传送参数的栈 include
  • jetson orin+livox mid-70+imu+云台相机联合标定和数据采集

    将之前无人机上的x86多源数据采集和联合标定算法重建在新板子jetson orin上 解决之前多传感器采集数据时间戳没对齐的问题 1 准备工作 安装ros环境 推荐小鱼 http fishros com fish home 大佬的包避免了自
  • 王昊奋:大规模知识图谱技术

    主讲嘉宾 王昊奋 主持人 阮彤 承办 中关村大数据产业联盟 嘉宾简介 王昊奋 华东理工大学讲师 上海交通大学计算机应用专业博士 对语义搜索 图数据库以及Web挖掘与信息抽取有浓厚的兴趣 在博士就读期间发表了30余篇国际顶级会议和期刊论文 长
  • TCP&UDP测试工具的使用

    一 TCP服务测试 1 在电脑上打开测试工具 2 该测试工具分为客户端和服务器两类 首先创建一个服务端 3 默认端口号点击确定 4 点击启动服务器 此时我们可以通过外部客户端与该服务器相连 5 在此 我们重新打开一次软件 模拟客户端并与服务
  • pandas基础入门之数据修改与基本运算

    1 数据复制 直接赋值 直接赋值的话 只是复制的元数据 行列索引 但是元素还是存储在相同内存位置 对元素进行修改会影响另外一个 import pandas as pd import numpy as np df pd DataFrame n
  • 偏微分方程 基础知识(线性偏微分方程+常系数线性偏微分方程)

    偏微分方程 指含有多元未知函数 u u x x
  • python爬虫connection error报错time read out

    TOC python 爬虫 ConnectionError HTTPConnectionPool host port 80 Read timed out python 爬虫 ConnectionError HTTPConnectionPoo
  • RocketMQ 安装和启动

    一 前言 系统环境 CentOS Linux release 7 9 2009 Core RocketMQ版本 4 7 1 我们会部署一套 RocketMQ 最小化的单机环境 包括一个 RocketMQ Namesrv 和 Broker 服
  • 【Transformer系列(1)】encoder(编码器)和decoder(解码器)

    前言 这个专栏我们开始学习transformer 自推出以来transformer在深度学习中占有重要地位 不仅在NLP领域 在CV领域中也被广泛应用 尤其是2021年 transformer在CV领域可谓大杀四方 在论文的学习之前 我们先
  • 第二章:25+ Python 数据操作教程(第十四节PYTHON 中的循环通过示例进行解释)持续更新中

    本教程通过几个实际示例介绍了在 python 中执行循环的各种方法 阅读本教程后 您将熟悉循环的概念 并将能够在现实世界的数据整理任务中应用循环 目录 什么是循环 现实世界中的循环示例 For 循环 Python 语法和示例 带 else
  • user-cf的理解-初衷

    使用user cf的初衷 以前的推荐算法 往往是基于内容标签的推荐 比如 用户喜欢了 数据挖掘导论 这本书 而这本书有 数据挖掘 这个标签 那么就给这个用户推荐 其他的 数据挖掘 类的图书 标签就像媒介一样 即是物品 即item 的属性 又
  • 互联网晚报

    今日看点 哪吒汽车第10万台量产车下线 仅用42个月 2022年首家银行理财子公司 浦银理财正式开业 京东成全国首批支持第三方商家接入数字人民币的企业 亚虹医药在科创板挂牌上市 A股迎来 泌尿生殖肿瘤第一股 刘慈欣 三体 英文版权以125万
  • 骚操作-CSDN浏览器助手已上线(就是个Chrome插件...)

    目录 概述 一 插件安装 1 进入csdn插件官网 2 本地下载csdn插件测试包 3 安装csdn插件测试包 4 解压csdn插件测试包并上传 5 开启csdn插件 6 查看插件信息 7 在新标签页中打开插件 二 功能测试 2 1 功能测
  • 图解!2023年国家社科基金年度项目

    9月4日 全国哲学社会科学工作办公室公示了2023年国家社科基金年度项目 其中重点项目有397项 一般项目有3185项 学术点滴 将重点项目和一般项目合并 利用DIKW软件统计和可视化 在国家社科基金年度项目中华东师范大学 中国人民大学 四
  • TCP/IP详解 卷1:协议 学习笔记 第二十三章 TCP的保活定时器

    一个TCP连接建立 然后经过任意时间 且中间路由器可以崩溃和重启 电话线可以挂断再接通 而连接依然保持 只要两端主机没有被重启 这意味着两端不交换任何信息 然而许多时候一个服务器希望知道客户主机是否崩溃 许多实现提供的保活定时器可提供这种能
  • Arthas监控java程序

    安装 1 解压缩arthas的压缩包 unzip arthas packaging bin zip 2 安装Arthas cd arthas install local sh 启动 以脚本的方式启动as sh 如图为启动成功 监控命令使用
  • 01. Windows基础:Dos命令

    文章目录 本文中的命令示例统一使用 来代表可以替换的内容 在使用时请不要真的输入 谢谢 0 Dos简介 1 目录相关 1 1 进入目录 1 2 进入另一个磁盘分区 1 3 列出当前目录下所有文件及文件夹 2 文件操作 2 1 浏览文件 2
  • 华为OD机试 - 相对开音节(Java)

    题目描述 相对开音节构成的结构为 辅音 元音 aeiou 辅音 r除外 e 常见的单词有bike cake等 给定一个字符串 以空格为分隔符 反转每个单词中的字母 若单词中包含如数字等其他非字母时不进行反转 反转后计算其中含有相对开音节结构
  • 【自然语言处理】潜在语义分析【下】概率潜在语义分析

    有任何的书写错误 排版错误 概念错误等 希望大家包含指正 由于字数限制 分成两篇博客 自然语言处理 潜在语义分析 上 潜在语义分析 自然语言处理 潜在语义分析 下 概率潜在语义分析 2 概率潜在语义分析 概率潜在语义分析 probabili
  • FreeRTOS(任务管理的创建、删除、挂起、恢复)

    目录 一 任务的基本概念 二 任务状态的概念 1 Running 运行态 2 Ready 就绪态 3 Blocked 阻塞态 4 Suspended 挂起态 三 任务状态的切换 四 系统启动 1 vTaskStartScheduler 函数