04_FreeRTOS任务挂起和恢复函数

news2025/1/21 2:51:23

目录

任务的挂起与恢复的API函数

任务挂起函数介绍

任务恢复函数介绍

中断中恢复函数

vTaskSuspend()任务挂起函数

vTaskResume()任务中恢复函数

xTaskResumeFromISR()中断中恢复函数


任务的挂起与恢复的API函数

挂起:挂起任务类似暂停,可恢复;删除任务,无法恢复,类似“人死两清” 

恢复:恢复被挂起的任务

FromISR: 带FromISR后缀是在中断函数中专用的API函数

任务挂起函数介绍

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

此函数用于挂起任务,使用时需将宏INCLUDE_vTaskSuspend配置为1。

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

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

任务恢复函数介绍

void vTaskResume(TaskHandle_t xTaskToResume)

使用该函数注意宏:INCLUDE_vTaskSuspend必须定义为1

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

中断中恢复函数

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)

xTaskResumeFromISR返回值描述如下:

使用该函数注意宏: INCLUDE_vTaskSuspend和INCLUDE_xTaskResumeFromISR必须定义为1

该函数专用于中断服务函数中,用于解挂被挂起任务

注意:中断服务程序中要调用freeRTOS的ARI函数则中断优先级不能高于FreeRTOS所管理的最高优先级

vTaskSuspend()任务挂起函数

1.根据任务句柄获取任务控制块,如果任务句柄为NULL,表示挂起任务自身

2.将要挂起的任务从相应的状态列表和事件列表中移除

3.将待挂起任务的任务状态列表向插入到挂起态任务列表末尾

4.判断任务调度器是否运行,在运行,更新下一次阻塞时间,防止被挂起任务为下一次阻塞超时任务

5.如果挂起的是任务自身:

        (1)调度器正在运行,强制进行一次任务切换;

        (2)调度器没有运行,判断挂起任务数是否等于任务总数,是:代表所有任务均被挂起,则当前控制块赋值为NULL,否:通过函数vTaskSwitchContext寻找下一个最高优先级任务

	void vTaskSuspend( TaskHandle_t xTaskToSuspend )
	{
		/*TCB结构体指针*/
		TCB_t *pxTCB;
		/*进入临界区*/
		taskENTER_CRITICAL();
		{
			/* If null is passed in here then it is the running task that is
			being suspended. */
			/*获取要挂起任务TCB控制块*/
			pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
			/*没实现*/
			traceTASK_SUSPEND( pxTCB );

			/* Remove task from the ready/delayed list and place in the
			suspended list. */
			/*移除状态列表项,不管是就绪还是阻塞等状态都移除*/
			if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
			{
				/*检测这个优先级的任务是不是没有了,如果没有了就把32位变量代表此优先级那位置0*/
				taskRESET_READY_PRIORITY( pxTCB->uxPriority );
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}

			/* Is the task waiting on an event also? */
			/*判断是否有等待事件*/
			if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
			{	
				/*移除等待事件列表项*/
				( void ) uxListRemove( &( pxTCB->xEventListItem ) );
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
			/*把TCB的状态列表项重新插入到挂起列表*/
			vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );
		}
		/*退出临界区*/
		taskEXIT_CRITICAL();
		/*调度器是否正在运行*/
		if( xSchedulerRunning != pdFALSE )
		{
			/* Reset the next expected unblock time in case it referred to the
			task that is now in the Suspended state. */
			/*进入临界区*/
			taskENTER_CRITICAL();
			{
				/*更新下一个阻塞超时时间*/
				prvResetNextTaskUnblockTime();
			}
			/*退出临界区*/
			taskEXIT_CRITICAL();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
		/*判断挂起的任务是不是当前任务*/
		if( pxTCB == pxCurrentTCB )
		{	
			/*任务正在运行*/
			if( xSchedulerRunning != pdFALSE )
			{
				/* The current task has just been suspended. */
				/*断言*/
				configASSERT( uxSchedulerSuspended == 0 );
				/*任务切换*/
				portYIELD_WITHIN_API();
			}
			else
			/*不是正在运行的任务*/
			{
				/* The scheduler is not running, but the task that was pointed
				to by pxCurrentTCB has just been suspended and pxCurrentTCB
				must be adjusted to point to a different task. */
				/*判断挂起任务总数等于任务总数*/
				if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
				{
					/* No other tasks are ready, so set pxCurrentTCB back to
					NULL so when the next task is created pxCurrentTCB will
					be set to point to it no matter what its relative priority
					is. */
					/*当前控制块赋值为NULL,代表所有任务都被挂起*/ 
					pxCurrentTCB = NULL;
				}
				else
			    /*判断挂起任务总数不等于任务总数*/
				{
					/*查找下一个最高优先级任务*/
					vTaskSwitchContext();
				}
			}
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}

vTaskResume()任务中恢复函数

1.恢复任务不能是正在运行任务且不能为NULL

2.判断任务是否被挂起,是:就会将该任务在挂起列表中移除,将该任务添加到就绪列表中

3.判断恢复的任务优先级是否大于当前正在运行的 是的话执行任务切换

	void vTaskResume( TaskHandle_t xTaskToResume )
	{
	/*把句柄赋值给任务控制块指针*/
	TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;

		/* It does not make sense to resume the calling task. */
		configASSERT( xTaskToResume );

		/* The parameter cannot be NULL as it is impossible to resume the
		currently executing task. */
		/*带进来的任务块不能是正在运行任务,不能等于NULL,*/
		if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )
		{
			/*进入临界区*/
			taskENTER_CRITICAL();
			{	/*判断这个任务是在挂起列表中*/
				if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE )
				{	
					traceTASK_RESUME( pxTCB );

					/* As we are in a critical section we can access the ready
					lists even if the scheduler is suspended. */
					/*移除状态列表,不管在什么列表都会被移除*/
					( void ) uxListRemove(  &( pxTCB->xStateListItem ) );
					/*添加到就绪列表中*/
					prvAddTaskToReadyList( pxTCB );

					/* We may have just resumed a higher priority task. */
					/*优先级高于当前运行任务优先级*/
					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
					{
						/* This yield may not cause the task just resumed to run,
						but will leave the lists in the correct state for the
						next yield. */
						/*任务切换*/
						taskYIELD_IF_USING_PREEMPTION();
					}
					else
					{
						mtCOVERAGE_TEST_MARKER();
					}
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			/*退出临界区*/
			taskEXIT_CRITICAL();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}

xTaskResumeFromISR()中断中恢复函数

1.函数portASSERT IF INTERRUPT PRIORITY INVALID(),用于检测:调用freertos的API函数的中断优先级是否在管理范围内及是否全部设置为枪占式优先级位

2.关闭freertos可管理中断,防止被其他的中断打断,并返回关闭前basepri奇存器的值

3.判断是否有挂起任务:

        1.有挂起任务,检查调度器是否被挂起

                (1)调度器末挂起

                        ①判断恢复的这个任务优先级是否大于正在执行的任务是的话将xYieldRequired标

                           记为pdTRUE,表示需要进行一次任务切换

                        ②将被恢复的任务从挂起列表中移除

                        ③插入到就绪列表

                (2)调度器挂起如果调度器被挂起了,就将恢复的任务插入等待就绪列表

                  xPendingReadyList,直到调度器被恢复再进行任务的处理

         2.无挂起任务 不需操作

	BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
	{
	/*返回值*/
	BaseType_t xYieldRequired = pdFALSE;
	/*赋值给任务控制块指针*/
	TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
	/*保存中断状态*/
	UBaseType_t uxSavedInterruptStatus;

		configASSERT( xTaskToResume );

		/* RTOS ports that support interrupt nesting have the concept of a
		maximum	system call (or maximum API call) interrupt priority.
		Interrupts that are	above the maximum system call priority are keep
		permanently enabled, even when the RTOS kernel is in a critical section,
		but cannot make any calls to FreeRTOS API functions.  If configASSERT()
		is defined in FreeRTOSConfig.h then
		portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
		failure if a FreeRTOS API function is called from an interrupt that has
		been assigned a priority above the configured maximum system call
		priority.  Only FreeRTOS functions that end in FromISR can be called
		from interrupts	that have been assigned a priority at or (logically)
		below the maximum system call interrupt priority.  FreeRTOS maintains a
		separate interrupt safe API to ensure interrupt entry is as fast and as
		simple as possible.  More information (albeit Cortex-M specific) is
		provided on the following link:
		http://www.freertos.org/RTOS-Cortex-M3-M4.html */
		/*检测中断优先级是否在FreeRTOS管理内,还判断是不是抢占式优先级是否为组4*/
		portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
		/*保存当前中断状态*/
		uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
		{ 	/*判断是在挂起列表中*/
			if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE )
			{	/*未实现*/
				traceTASK_RESUME_FROM_ISR( pxTCB );

				/* Check the ready lists can be accessed. */
				/*调度器没有挂起,正在运行*/
				if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
				{
					/* Ready lists can be accessed so move the task from the
					suspended list to the ready list directly. */
					/*恢复任务的优先级高于正在运行的优先级*/
					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
					{	
						/*赋值为TRUE*/
						xYieldRequired = pdTRUE;
					}
					else
					{
						mtCOVERAGE_TEST_MARKER();
					}
					/*从挂起列表移除*/
					( void ) uxListRemove( &( pxTCB->xStateListItem ) );
					/*添加到就绪列表*/
					prvAddTaskToReadyList( pxTCB );
				}
				else
				/*调度器没挂起,没有运行*/					
				{
					/* The delayed or ready lists cannot be accessed so the task
					is held in the pending ready list until the scheduler is
					unsuspended. */
					/*事件列表插入到等待就绪事件列表里面,直到调度器被恢复,再从等待列表移除到就绪列表*/
					vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );
				}
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		/*设中断状态*/
		portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
		/*返回值,TRUE需要任务切换,FLASH不需要任务切换*/
		return xYieldRequired;
	}

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

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

相关文章

公务员行测常识积累(持续更新中)

公务员行测常识积累政治天文地理人文戏曲历史经济物理生物医学政治 区域协调发展战略:以城市群为主体构建大中小城市和小城镇协调发展的城镇格局;以疏解北京非首都功能为“牛鼻子”推动京津冀协同发展;以共抓大保护、不搞大开发为导向推动长…

个人建议【建议】

以下只是个人的一些看法 本文已在CSDN博客中发布文章 本文已在CSDN建议社区中发布帖子 重点内容已经被蓝色字体标志出来了,希望能对建设优秀的CSDN有所启发 快速浏览看总结 中心思想看最后 1.我的专栏上限问题还没解决 在2022-10-24 20:33:41就发出了这个问题&…

如何突破以往模式的束缚,如何让互联网行业重新开启新的想象空间

在流量和资本的红利已然被出清的大背景下,以平台经济为代表的互联网经济的发展同样被逼退到了进退维谷的境地里。如何突破以往发展模式的束缚,如何让互联网行业的发展重新开启新的想象空间,成为每一个互联网玩家必然需要思考的重要课题。于是…

Java基础学习笔记(十五)—— Sream流

Sream流1 Stream流初体验2 Stream流概述3 生成Stream流4 中间操作方法5 终结操作方法6 收集操作方法7 Stream流案例1 Stream流初体验 案例需求 创建一个集合,存储多个字符串元素把集合中所有以“张”开头的元素存储到一个新的集合把"张"开头的集合中的长…

SpringCloud高级应用-2(Gateway-01)

Gateway介绍: Spring Cloud Gateway 是Spring Cloud团队的一个全新项目,基于Spring 5.0、SpringBoot2.0、Project Reactor 等技术开发的网关。旨在为微服务架构提供一种简单有效统一的API路由管理方式。 Spring Cloud Gateway 作为SpringCloud生态系统…

Acwing---1214.波动数列

波动数列1.题目2.基本思想3.代码实现1.题目 观察这个数列: 1 3 0 2 -1 1 -2 … 这个数列中后一项总是比前一项增加2或者减少3,且每一项都为整数。 栋栋对这种数列很好奇,他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 …

Grafana配置sqlserver,展示数据

Grafana配置sqlserver,展示数据1. 连接数据源2. Visualization2.1 时间表达式2.2 Graph2.2.1 Example with metric column2.2.2 convert null values to be zero instead2.2.3 Using multiple columns3. AwakeningGrafana Document: https://grafana.com/docs/grafa…

java MultipartFile+vue+element 批量上传文件、图片,与普通数据同时提交保存才上传到后端

一.背景 文件上传项目可参考:点击预览 1.最简单也是最普遍的做法是form表单提交,其实前端提交到后端也是难以离开form表单提交, 一般有两种方式来处理文件、图片上传: 先上传,获取返回路径,再整个表单提…

PyTorch实现基本的线性回归

线性回归理论知识参考文章:线性回归 下面我们将从零开始实现整个线性回归方法, 包括数据集生成、模型、损失函数和小批量随机梯度下降优化器。 1.导入 %matplotlib inline import random import torch from d2l import torch as d2l2.生成数据集 我们…

js垃圾回收(引用计数算法、标记清除算法、v8垃圾回收机制、浏览器性能监控、任务管理器、内存分析、JSBench)

目录 垃圾 可达对象 GC算法(垃圾回收机制) 引用计数算法 优点 缺点 标记清除算法 优点 缺点 标记整理算法 优点 缺点 V8 V8垃圾回收 新生代对象回收 晋升条件 老生代对象回收 性能监控Performance 浏览器任务管理器 内存分析 ​编…

Apache Doris 系列: 基础篇-BitMap索引

1. 测试数据准备 本文使用SSB(Star-Schema-Benchmark)的测试数据,读者也可以自行准备测试数据 1.1 编译ssb-dbgen 数据生成工具 ## 拉取Apache Doris源代码 git clone https://github.com/apache/doris.git## 编译ssb-dbgen cd doris/tool…

计算机网络复习之应用层

统一资源定位系统(uniform resource locator;URL)是因特网的万维网服务程序上用于指定信息位置的表示方法。它最初是由蒂姆伯纳斯李发明用来作为万维网的地址。现在它已经被万维网联盟编制为互联网标准RFC1738。邮局协议(Post Office Protoco…

TDemo 备注文本的二种存贮方式

TDemo 备注纯文本的二种存贮方式 数据库使用过程中,对于TDeme控件,对应数据库的分为nvarchar(n)类型字段。 一、通常使用二种格式的文本: (1)单纯文本 (2)带换行符的文本 这二种格式&#xff0c…

Pdf 转换成Word如何在线转换?职场公认好用软件推荐

Pdf 转换成Word如何在线转换?生活中很多时候我们需要接触大量的办公文件,特别是利用office的三种常见的文件格式编辑各类文件,最常见的便是Word文件操作。为了更方便我们进行文件传输,大部分情况下我们会把格式排版完好的Word文档…

UDS诊断系列介绍08-19服务

本文框架1. 系列介绍1.1 19服务概述1.2 DTC故障码定义1.3 DTC状态位2. 19服务常用子服务2.1 19 01服务2.2 19 02服务2.3 19 04服务2.4 19 06服务2.5 19 0A服务2.6 否定响应3. Autosar系列文章快速链接1. 系列介绍 UDS(Unified Diagnostic Services)协议…

Android 深入系统完全讲解(15)

4 权限相关的知识 1 安卓权限 上层 APK 权限获取方式,配置 AndroidManifest.xml,系统会对应的给 gid,在创建进程的时候就带下去,这样子就可以访问对应的设备。 而系统相关的,会限制必须是 uidsystem 这类&#xff0c…

一年融资三轮,一文读懂亿格云这家公司

数字办公时代,网络安全是企业经营的底线工作。如何构建一个安全、稳定、高效的网络安全体系,是企业谋求发展的基础条件之一。近年,倡导“永不信任,始终验证”的零信任网络安全服务理念开始兴起。而国内致力于基于零信任理念构建办…

MySQL 行级锁(行锁、临键锁、间隙锁)

行级锁 行级锁,每次操作锁住对应的行数据。锁定粒度最小,发生锁冲突的概率最低,并发度最高。应用在InnoDB存储引擎中。 InnoDB的数据是基于索引组织的,行锁是通过对索引上的索引项加锁来实现的,而不是对记录加的锁。 1…

类和对象(上)

文章目录引用autoNULL&nullptr&0类和对象类的实例化默认成员函数构造函数析构函数拷贝构造函数运算符的重载赋值运算符的重载拷贝构造次数编译器优化前置后置> < ! - -const成员operator>>&&operator<<再谈构造函数初始化列表初始化expli…

使用Hi3861开发环境搭建

安装ubuntu ​ 文件夹的位置尽量选一个空间比较大的 内存也尽量分配大一点&#xff0c;不要到红色区域就行 固定分配&#xff0c;如果给它100G空间&#xff0c;他就会把这100G空间全部使用掉&#xff0c;动态分配&#xff0c;即使你给他100G内存&#xff0c;但实际使用的空间…