FreeRTOS:任务挂起和恢复

news2024/10/5 13:48:28

目录

  • 一、任务挂起和恢复定义
  • 二、任务挂起
    • 2.1含义
    • 2.2任务挂起内部实现
    • 2.3函数vTaskSuspend()
  • 三、任务恢复
    • 3.1含义
    • 3.2任务恢复内部实现
    • 3.3函数vTaskResume()
  • 四、任务挂起和恢复实验
    • 4.1实验要求
    • 4.2程序代码

一、任务挂起和恢复定义

有时候我们需要暂停某个任务的运行,过一段时间以后在重新运行。这个时候要是使用任务删除和重建的方法的话那么任务中变量保存的值肯定丢失了!FreeRTOS 给我们提供了解决这种问题的方法,那就是任务挂起和恢复,当某个任务要停止运行一段时间的话就将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。FreeRTOS的任务挂起和恢复API函数如下:
在这里插入图片描述

二、任务挂起

2.1含义

任务挂起相当于暂停,把任务挂起了,任务就暂停运行,是可以恢复的。

2.2任务挂起内部实现

1、根据任务句柄获取任务控制块,如果任务句柄为NULL,表示挂起任务自身
2、将要挂起的任务从相应的状态列表和事件列表中移除
3、将待挂起任务的任务状态列表向插入到挂起态任务列表末尾
4、判断任务调度器是否运行,在运行,更新下一次阻塞时间,防止被挂起任务为下一次阻塞超时任务调度器正在运行,强制进行一次任务切换;
5、如果挂起的是任务自身
调度器正在运行,强制进行一次任务切换;
调度器没有运行,判断挂起任务数是否等于任务总数:
是:代表所有任务均被挂起,则当前控制块赋值为NULL,调度器没有运行,判断挂起任务数是否等于任务总数,
否:通过函数vTaskSwitchContext寻找下一个最高优先级任务

2.3函数vTaskSuspend()

此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂起态的唯一方法就是调用任务恢复函数 vTaskResume()或 xTaskResumeFromISR()。函数原型:

void vTaskSuspend( TaskHandle_t xTaskToSuspend)

形参描述:xTaskToSuspend是待挂起任务的任务句柄

使用条件:此函数用于挂起任务,使用时需将宏INCLUDE_ vTaskSuspend 配置为1

使用说明:无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复

注意点:当传入的参数为NULL, )则代表挂起任务自身当前正在运行的任务))

三、任务恢复

3.1含义

恢复被挂起的任务。

3.2任务恢复内部实现

1、恢复任务不能是正在运行任务且不能为NULL
2、判断任务是否被挂起,是:就会将该任务在挂起列表中移除,将该任务添加到就绪列
表中
3、判断恢复的任务优先级是否大于当前正在运行的是的话执行任务切换

3.3函数vTaskResume()

将一个任务从挂起态恢复到就绪, 只有通过函数 vTaskSuspend()设置为挂起态的任务才可以使用 vTaskRexume()。函数原型:

void vTaskResume( TaskHandle_t xTaskToResume)

形参描述:xTaskToResume,待恢复任务的任务句柄

使用条件:宏定义INCLUDE _vTaskSuspend必须定义为1

使用说明:注意:任务无论被yTaskSuspend挂起多少次,只需在任务中调vTakResume()恢复一次, 就可以继续运行。且被恢复的任务会进入就绪态! )

四、任务挂起和恢复实验

4.1实验要求

本实验设计 4个任务: start_task、key_task、task1_task和 task2_task,这四个任务的功 能如下:
start_task:用来创建其他 :用来创建其他 3个
key_task: 按键服务任,检测按键的按下结果,根据不同的按键结果执行不同的操作。
task1_task:应用任务 :应用任务 1。
task2_task: 应用任务 2。
实验需要四个按键, KEY0、KEY1、KEY2和 KEY_UP,这四个按键的 ,这四个按键的 功能如下:
KEY0: 此按键为中断模式,在服务 函数恢复任2的运行。 的运行。
KEY1: 此按键为 输入模式,用于恢复任务 1的运行。
KEY2: 此按键为输入模式,用于挂起任务 2的运行。
KEY_UP: 此按键为输入模式,用于挂起任务 1的运行。

4.2程序代码

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "exti.h"
#include "FreeRTOS.h"
#include "task.h"


//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		2
//任务堆栈大小	
#define KEY_STK_SIZE 		128  
//任务句柄
TaskHandle_t KeyTask_Handler;
//任务函数
void key_task(void *pvParameters);

//任务优先级
#define TASK1_TASK_PRIO		3
//任务堆栈大小	
#define TASK1_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);

//任务优先级
#define TASK2_TASK_PRIO		4
//任务堆栈大小	
#define TASK2_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);


int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	 
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	KEY_Init();							//初始化按键
	EXTIX_Init();						//初始化外部中断
	LCD_Init();							//初始化LCD
	
	
	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
	//创建KEY任务
	xTaskCreate((TaskFunction_t )key_task,             
                (const char*    )"key_task",           
                (uint16_t       )KEY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )KEY_TASK_PRIO,        
                (TaskHandle_t*  )&KeyTask_Handler);  
    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//key任务函数
void key_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{
			case WKUP_PRES:
				vTaskSuspend(Task1Task_Handler);//挂起任务1
				printf("挂起任务1的运行!\r\n");
				break;
			case KEY1_PRES:
				vTaskResume(Task1Task_Handler);	//恢复任务1
				printf("恢复任务1的运行!\r\n");
			case KEY2_PRES:
				vTaskSuspend(Task2Task_Handler);//挂起任务2
				printf("挂起任务2的运行!\r\n");
				break;
		}
		vTaskDelay(10);			//延时10ms 
	}
}

//task1任务函数
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	while(1)
	{
		task1_num++;	//任务执1行次数加1 注意task1_num1加到255的时候会清零!!
		LED0=!LED0;
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

//task2任务函数
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	while(1)
	{
		task2_num++;	//任务2执行次数加1 注意task1_num2加到255的时候会清零!!
        LED1=!LED1;
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

在这里插入图片描述

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

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

相关文章

代码随想录算法训练营第三十二天 | 利润题、覆盖范围题

122.买卖股票的最佳时机II 文档讲解:代码随想录 (programmercarl.com) 视频讲解:贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机II_哔哩哔哩_bilibili 状态:根本做不出来,思路太巧了。 思路 想获…

浅谈Java、PHP、C++编程的优缺点

Java 、PHP、C 编程语言都是非常流行的编程语言,在开发、Web 开发、移动应用开发等领域都有广泛的应用。本文将从以下几个方面分析 Java、PHP、C 编程语言的优缺点。 一、Java 编程语言的优缺点 优点 (1)具有跨平台特性,能够在不…

Java8中DateTimeFormatter真的是线程安全的吗?

文章目录 [toc] 1.背景2.解决办法2.1办法一:换姿势或者升级JDK的版本2.1办法二:更换文件名称字生成策略 Java8中DateTimeFormatter真的是线程安全的吗? 答案是否定的 1.背景 由于之前写了一个旷世的ocr的服务,接入了旷世的FaceID的人脸比对…

初识WebAssembly

WebAssembly是一种新型的低级字节码格式,它可以在现代的浏览器中运行,同时也支持其它的平台,例如Node.js、Web Worker等。WebAssembly的目标是在Web平台上提供一种高效、安全、可移植的运行时环境,可以被用于执行任意类型的二进制…

ChatGPT实现leetcode 刷题和变型

leetcode 刷题和变型 作为一个程序员,Leetcode 是一个非常重要的网站。它不仅可以帮助程序员提高算法和数据结构的能力,还能帮助我们准备技术面试。但是,刷 Leetcode 也需要花费大量的时间和精力来解决各种难题。那么,有没有什么…

达成事务条件的实现原理

事务存在的意义:保证系统中的数据,都是符合预期的;相互关联的数据之间,不会产生矛盾 达成事务的条件 原子性:一个操作,要么同时成功、要么同时失败 隔离性:各业务,读写相互独立 持…

arm 源码编译kernel 对比image zimage uimage vmlinux

一 源码编译kernel 下载交叉编译工具链 下载cc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz ,这是官网的。使用下面命令下载。 585 wget https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/arm-linux-gnueabihf/gcc-linaro-4.9…

每天一道算法练习题--Day22 第一章 --算法专题 --- ----------最大公约数

关于最大公约数有专门的研究。 而在 LeetCode 中虽然没有直接让你求解最大公约数的题目。但是却有一些间接需要你求解最大公约数的题目。 如何求最大公约数? 定义法 def GCD(a: int, b: int) -> int:smaller min(a, b)while smaller:if a % smaller 0 and b …

一个集团企业,如何从0到1构建信息化系统?

当今时代,信息技术已经成为企业发展不可或缺的一部分,特别是对于一个大型集团公司来说,如何构建一个高效的信息化系统对于其业务发展至关重要。 我们想要构建一个优质高效的信息化系统,首先需要了解现在大的趋势是怎样的。 目前…

【Linux】Linux安装Java环境(OpenJDK)

文章目录 第一步:第二步,选择合适的版本安装:第四步,配置环境变量 linux环境为CentOS7.8 版本。 今天教大家怎么在CentOs环境中安装Java的开发环境。 在安装java之前我们先来了解一下YUM Yum(全称为 Yellow dog Updat…

【JavaEE初阶】简单了解wait和notify方法~

目录 🌟1、wait() 🌟2、notify() 🌟1、wait() (1)wait()方法与notify()方法都是Object类中的方法。 (2)wait()是让线程等待一段时间,死等——>状态WAITING:没有时间限制的等待.…

C++ | 语句的基础知识(夯实基础)

本文概要 本篇文章主要介绍数据结构中C的语句内容,适合有零基础的同学,文中描述和代码示例很详细,干货满满,感兴趣的小伙伴快来一起学习吧! 🌟🌟🌟个人简介🌟&#x1f…

CentOS 7.x 安装 ZooKeeper 并实现集群搭建

0. 集群结构 服务器IPhostname节点说明192.168.31.101master主节点192.168.31.102slave1从节点192.168.31.103 slave2 从节点 下面的安装与配置操作需要在三台服务器上都执行一遍。 1. 安装JDK ZooKeeper要求运行在 JDK 环境上,JDK安装教程可参考 CentOS 7.x 安装…

从点赞到数字货币:揭秘Diem币与Facebook的联系

大家都知道Facebook是一个全球知名的社交媒体平台,但你是否听说过与Facebook有关的数字货币Diem币呢?或许你会想,从点赞到数字货币,这是怎么回事?别着急,让我们一起揭秘Diem币与Facebook的联系。 首先&…

IP一键呼叫语音对讲怎么样?

IP一键呼叫语音对讲怎么样? IP一键呼叫语音对讲,让您的生活更加便利和安全! 无需复杂设置,轻松实现远程通话,随时随地与家人朋友沟通交流。APP端可实时监控家庭动态,保证家庭安全。 一键呼叫语音功能&am…

微信小程序——自定义组件

自定义组件 一、组件的创建二、组件的引用1、全局引用2、局部引用 三、全局引用和局部引用 一、组件的创建 第一步:在项目的根目录下创建文件夹components。 第二步:在components文件夹下创建文件夹card。 第三步:选中文件夹card 右键 选中…

openwrt广告屏蔽大师修复补丁luci-app-adbyby plus + lite

openwrt广告屏蔽大师修复补丁 目前使用方式然而有规则无法下载的通病所以可以手工拷贝随便哪里来的规则最后提示 补丁位置 : 地址 http://pan.ezdial.cn/nasone/a 备用:https://bak.ezdial.cn:8000/bakone/a 因什么值得买,在反复审核本文&…

如何在 AlmaLinux 8 上安装和使用 Docker

Docker 是面向开发人员和系统管理员的强大平台,可简化在软件容器内部署应用程序的过程。 容器允许您将应用程序及其所有部分(代码、运行时、系统工具、系统库——通常位于 /usr/bin 或 /usr/lib 中的任何内容)打包,以便它可以在任何 Linux 机器上一致地运…

Linux性能参数调优

内核的shmall和shmmax参数 SHMMAX配置了最大的内存segment的大小:这个设置的比SGA_MAX_SIZE大比较好。 SHMMIN最小的内存segment的大小 SHMMNI整个系统的内存segment的总个数 SHMSEG每个进程可以使用的内存segment的最大个数 配置信号灯( semphore …

微软 New Bing, Chat AI 绘图火力全开

嗯,今天的主角是, Microsoft New Bing! 在 Edge 里面,访问 www.bing.com,登录 Microsoft 账户,点击 CHAT, 就可以体验 Bing Chatbot. 这次, New Bing 无需加入 waitlist, 即可全面体验 ChatGPT DALL-E 的绘图功能 关键…