04_FreeRTOS任务挂起和恢复函数

news/2024/12/2 20:34:53/

目录

任务的挂起与恢复的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 isbeing suspended. *//*获取要挂起任务TCB控制块*/pxTCB = prvGetTCBFromHandle( xTaskToSuspend );/*没实现*/traceTASK_SUSPEND( pxTCB );/* Remove task from the ready/delayed list and place in thesuspended 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 thetask 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 pointedto by pxCurrentTCB has just been suspended and pxCurrentTCBmust be adjusted to point to a different task. *//*判断挂起任务总数等于任务总数*/if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ){/* No other tasks are ready, so set pxCurrentTCB back toNULL so when the next task is created pxCurrentTCB willbe set to point to it no matter what its relative priorityis. *//*当前控制块赋值为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 thecurrently 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 readylists 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 thenext 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 amaximum	system call (or maximum API call) interrupt priority.Interrupts that are	above the maximum system call priority are keeppermanently 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 thenportASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertionfailure if a FreeRTOS API function is called from an interrupt that hasbeen assigned a priority above the configured maximum system callpriority.  Only FreeRTOS functions that end in FromISR can be calledfrom interrupts	that have been assigned a priority at or (logically)below the maximum system call interrupt priority.  FreeRTOS maintains aseparate interrupt safe API to ensure interrupt entry is as fast and assimple as possible.  More information (albeit Cortex-M specific) isprovided 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 thesuspended 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 taskis held in the pending ready list until the scheduler isunsuspended. *//*事件列表插入到等待就绪事件列表里面,直到调度器被恢复,再从等待列表移除到就绪列表*/vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) );}}else{mtCOVERAGE_TEST_MARKER();}}/*设中断状态*/portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );/*返回值,TRUE需要任务切换,FLASH不需要任务切换*/return xYieldRequired;}


http://www.ppmy.cn/news/11880.html

相关文章

敏捷是知与行的功夫

敏捷不是“一”种方法 “敏捷是一种用于项目管理和软件开发的迭代方法,可帮助团队更快地向客户交付价值并减少风险。 它不是将一切都押在“大爆炸”发布上,而是以小的增量交付成果。 不断评估需求、计划和结果,因此能够快速地响应变化。” 以…

大数据必学Java基础(一百二十):Maven工程的介绍与创建

文章目录 Maven工程的介绍与创建 一、Maven工程类型 1、POM工程 2、JAR工程 3、WAR工程

【自定义类型】-结构体,枚举,联合

🎇作者:小树苗渴望变成参天大树 💖作者宣言:认真写好每一篇博客 🧨作者gitee:link 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! 🎊自定义类型🎉前言&a…

OOM 机制

OOM 机制 “我们从OOM的角度来帮大家提高一点内存方面的知识,虽然不能说帮助人们来完全解决内存问题,但是也能从一个侧面来提高大家分析内存问题相关的能力。” 这是关于 Linux 内核的学习笔记,重点要了解 OOM 这块的相关知识点。 1 相关概念…

【正点原子FPGA连载】 第十七章 呼吸灯实验 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第十七章 呼吸灯…

【2022年度总结】总结过去,展望未来

文章目录前言回顾过去一、刷题道路两眼黑二、助人为乐本身便是一种快乐展望未来兔年Flag博客文章竞赛目标学习目标志同道合前言 注册CSDN一年了,新年伊始,正好趁着这个时间复盘一下逝去的2022! 很幸运,在对计算机知识懵懂无知的时…

awk练习

1、获取根分区剩余大小 [rootlocalhost test]# df -Th / | awk NR2 {print $5} 16G2、获取当前机器ip地址 [rootlocalhost test]# hostname -I 192.168.6.20 3、统计出apache的access.log中访问量最多的5个IP [rootlocalhost test]# awk {ip[$1]} END {for (a in ip) print …

JAVA---泛型

一、什么是泛型 Java的泛型 (generics) 是在JDK5中推出的新概念,在泛型推出之前,程序员需要构建一个元素为Object的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数…