FreeRTOS之vTaskDelete实现分析

这里写自定义目录标题

  • 1 函数接口
    • 1.1 函数接口
    • 1.2 函数参数简介
  • 2 vTaskDelete的调用关系
    • 2.1 调用关系
    • 2.2 调用关系示意图
  • 3 函数源码分析
    • 3.1 vTaskDelete
    • 3.2 uxListRemove

1 函数接口

1.1 函数接口

void vTaskDelete( TaskHandle_t xTaskToDelete )

1.2 函数参数简介

  • TaskHandle_t xTaskToDelete 要删除任务的句柄,但这个句柄其实就是我们申请任务时创建的TCB,这个参数在传入的时候可以设置为NULL,表示要删除的是自己当前的任务。

2 vTaskDelete的调用关系

2.1 调用关系

|- vTaskDelete|- pxTCB = prvGetTCBFromHandle( xTaskToDelete );|- uxListRemove( &( pxTCB->xStateListItem ) )|- taskRESET_READY_PRIORITY( pxTCB->uxPriority );|- vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );|- taskYIELD_WITHIN_API();

2.2 调用关系示意图

3 函数源码分析

3.1 vTaskDelete

  • pxTCB = prvGetTCBFromHandle( xTaskToDelete ); 获取要删除任务的TCB
  • uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 将当前要删除的任务从pxReadyTasksLists对应优先级的链表里面删除,并判断该优先级的任务数是不是为0了,如果当前该优先级的链表里已经没有任务则需要调用taskRESET_READY_PRIORITY( pxTCB->uxPriority );去做重置将该优先级在uxTopReadyPriority中mask掉。
  • vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); 如果当前的任务处于运行状态,则将当前要删除的任务放入到xTasksWaitingTermination列表,等到idle task执行的时候再去执行删除操作。任务是否处于调度状态的判断依据是xSchedulerRunning是否是pdTRUE,该状态位在执行vTaskStartScheduler函数时被置位,在执行vTaskEndScheduler函数时被置位pdFALSE,因此只要是当前的系统调度没有停就需要将要删除的任务的TCB加入到xTasksWaitingTermination链表中。
  • ++uxDeletedTasksWaitingCleanUp 记录等待清理任务的数量,在idle task或者vTaskEndScheduler执行时,以该全局变量作为清理数量的标准。
  • xDeleteTCBInIdleTask = pdTRUE; 标记当前任务要再idle task里面做删除工作。
  • taskYIELD_WITHIN_API();或者prvYieldCore( pxTCB->xTaskRunState ); 将处理器让出去,调度其他的任务。
void vTaskDelete( TaskHandle_t xTaskToDelete )
{TCB_t * pxTCB;BaseType_t xDeleteTCBInIdleTask = pdFALSE;BaseType_t xTaskIsRunningOrYielding;traceENTER_vTaskDelete( xTaskToDelete );taskENTER_CRITICAL();{获取当前要删除任务的TCB,如果xTaskToDelete 为空则表示要删除当前正在运行的任务,否则就找到对应任务的TCB。pxTCB = prvGetTCBFromHandle( xTaskToDelete );configASSERT( pxTCB != NULL );把当前要删除的任务从ready/delayed 链表中删除,并判断任务优先级的链表任务数是否为0if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ){如果当前要删除的任务优先级所对应的链表任务数为0,则将该优先级在uxTopReadyPriority中mask掉。taskRESET_READY_PRIORITY( pxTCB->uxPriority );}else{mtCOVERAGE_TEST_MARKER();}判断当前的任务是否在一个event的链表,如果是则通过uxListRemove将其移除if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ){( void ) uxListRemove( &( pxTCB->xEventListItem ) );}else{mtCOVERAGE_TEST_MARKER();}/* Increment the uxTaskNumber also so kernel aware debuggers can* detect that the task lists need re-generating.  This is done before* portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will* not return. */uxTaskNumber++;通过taskTASK_IS_RUNNING_OR_SCHEDULED_TO_YIELD来判断当前的任务是否在运行状态,如果其xTaskRunState被设置为-1则表明其不处于运行状态,正常运行的任务其xTaskRunState值会被设置为所运行的core的id。xTaskIsRunningOrYielding = taskTASK_IS_RUNNING_OR_SCHEDULED_TO_YIELD( pxTCB );根据xSchedulerRunning 来判断当前的是否还处于正常的调度状态,该全局变量在vTaskStartScheduler函数被执行时设置为pdTRUE,在vTaskEndScheduler时被设置为pdFALSEif( ( xSchedulerRunning != pdFALSE ) && ( xTaskIsRunningOrYielding != pdFALSE ) ){为了防止该任务在其他core上还有运行的,所以将该任务添加到xTasksWaitingTermination链表上,等idle task运行时再做清理工作。vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );标记当前需要做清理的任务数++uxDeletedTasksWaitingCleanUp;/* Call the delete hook before portPRE_TASK_DELETE_HOOK() as* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port. */traceTASK_DELETE( pxTCB );用以标记有任务需要删除,如果需要设置为pdTRUE,则在后面会调用prvDeleteTCB( pxTCB );释放掉这块内存空间。xDeleteTCBInIdleTask = pdTRUE;/* The pre-delete hook is primarily for the Windows simulator,* in which Windows specific clean up operations are performed,* after which it is not possible to yield away from this task -* hence xYieldPending is used to latch that a context switch is* required. */#if ( configNUMBER_OF_CORES == 1 )portPRE_TASK_DELETE_HOOK( pxTCB, &( xYieldPendings[ 0 ] ) );#elseportPRE_TASK_DELETE_HOOK( pxTCB, &( xYieldPendings[ pxTCB->xTaskRunState ] ) );#endif在SMP系统给按任务让出CPU,让其他任务去运行#if ( configNUMBER_OF_CORES > 1 ){if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ){if( pxTCB->xTaskRunState == ( BaseType_t ) portGET_CORE_ID() ){configASSERT( uxSchedulerSuspended == 0 );taskYIELD_WITHIN_API();}else{prvYieldCore( pxTCB->xTaskRunState );}}}#endif /* #if ( configNUMBER_OF_CORES > 1 ) */}else{--uxCurrentNumberOfTasks;traceTASK_DELETE( pxTCB );/* Reset the next expected unblock time in case it referred to* the task that has just been deleted. */prvResetNextTaskUnblockTime();}}taskEXIT_CRITICAL();/* If the task is not deleting itself, call prvDeleteTCB from outside of* critical section. If a task deletes itself, prvDeleteTCB is called* from prvCheckTasksWaitingTermination which is called from Idle task. */if( xDeleteTCBInIdleTask != pdTRUE ){prvDeleteTCB( pxTCB );}/* Force a reschedule if it is the currently running task that has just* been deleted. */#if ( configNUMBER_OF_CORES == 1 ){if( xSchedulerRunning != pdFALSE ){if( pxTCB == pxCurrentTCB ){configASSERT( uxSchedulerSuspended == 0 );taskYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}}#endif /* #if ( configNUMBER_OF_CORES == 1 ) */traceRETURN_vTaskDelete();
}

3.2 uxListRemove

  • pxList = pxItemToRemove->pxContainer; 通过pxContainer找到当前任务优先级所对应链表的链表头
  • pxList->uxNumberOfItems 返回当前任务优先级链表还剩余的任务数,一般用于判断链表所挂任务是否为0,用以来确定当前任务的优先级是否需要mask掉。
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{/* The list item knows which list it is in.  Obtain the list from the list* item. */List_t * const pxList = pxItemToRemove->pxContainer;traceENTER_uxListRemove( pxItemToRemove );pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* Only used during decision coverage testing. */mtCOVERAGE_TEST_DELAY();/* Make sure the index is left pointing to a valid item. */if( pxList->pxIndex == pxItemToRemove ){pxList->pxIndex = pxItemToRemove->pxPrevious;}else{mtCOVERAGE_TEST_MARKER();}pxItemToRemove->pxContainer = NULL;( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems - 1U );traceRETURN_uxListRemove( pxList->uxNumberOfItems );return pxList->uxNumberOfItems;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python oa服务器巡检报告脚本的重构和修改(适应数盾OTP)有空再去改

Two-Step Vertification required: Please enter the mobile app OTPverification code: 01.因为巡检的服务器要双因子认证登录,也就是登录堡垒机时还要输入验证码。这对我的巡检查服务器的工作带来了不便。它的机制是每一次登录,算一次会话…

Unreal从入门到精通之如何绘制用于VR的3DUI交互的手柄射线

文章目录 前言实现方式MenuLaser实现步骤1.Laser和Cursor2.移植函数3.启动逻辑4.检测射线和UI的碰撞5.激活手柄射线6.更新手柄射线位置7.隐藏手柄射线8.添加手柄的Trigger监听完整节点如下:效果图前言 之前我写过一篇文章《Unreal5从入门到精通之如何在VR中使用3DUI》,其中讲…

Win11 22H2/23H2系统11月可选更新KB5046732发布!

系统之家11月22日报道,微软针对Win11 22H2/23H2版本推送了2024年11月最新可选更新补丁KB5046732,更新后,系统版本号升至22621.4541和22631.4541。本次更新后系统托盘能够显示缩短的日期和时间,文件资源管理器窗口很小时搜索框被切…

【数据结构】【线性表】【练习】反转链表

申明 该题源自力扣题库19&#xff0c;文章内容&#xff08;代码&#xff0c;图表等&#xff09;均原创&#xff0c;侵删&#xff01; 题目 给你单链表的头指针head以及两个整数left和right&#xff0c;其中left<right&#xff0c;请你反转从位置left到right的链表节点&…

【赵渝强老师】MySQL的慢查询日志

MySQL的慢查询日志可以把超过参数long_query_time时间的所有SQL语句记录进来&#xff0c;帮助DBA人员优化所有有问题的SQL语句。通过mysqldumpslow工具可以查看慢查询日志。 视频讲解如下&#xff1a; MySQL的慢查询日志 【赵渝强老师】MySQL的慢查询日志 下面通过具体的演示…

基于docker进行任意项目灵活发布

引言 不管是java还是python程序等&#xff0c;使用docker发布的优势有以下几点&#xff1a; 易于维护。直接docker命令进行管理&#xff0c;如docker stop、docker start等&#xff0c;快速方便无需各种进程查询关闭。环境隔离。项目代码任何依赖或设置都可以基本独立&#x…

Android 分区相关介绍

目录 一、MTK平台 1、MTK平台分区表配置 2、MTK平台刷机配置表 3、MTK平台分区表配置不生效 4、Super分区的研究 1&#xff09;Super partition layout 2&#xff09;Block device table 二、高通平台 三、展锐平台 四、相关案例 1、Super分区不够导致编译报错 经验…

数据库类型介绍

1. 关系型数据库&#xff08;Relational Database, RDBMS&#xff09;&#xff1a; • 定义&#xff1a;基于关系模型&#xff08;即表格&#xff09;存储数据&#xff0c;数据之间通过外键等关系相互关联。 • 特点&#xff1a;支持复杂的SQL查询&#xff0c;数据一致性和完整…

当产业经济插上“数字羽翼”,魔珐有言AIGC“3D视频创作大赛”成功举办

随着AI技术的飞速发展&#xff0c;3D数字人技术已成为驱动各行各业转型升级的重要力量。在这一背景下&#xff0c;2024山东3D数字人视频创作大赛应运而生&#xff0c;并在一番激烈的角逐后圆满落幕&#xff0c;为科技与创意的交融写下浓墨重彩的一笔。 11月20日&#xff0c;一…

经济增长初步

1.人均产出 人均产出&#xff0c;通常指的是一个国家、地区或组织在一定时期内&#xff0c;每个劳动人口平均创造的生产总值。它是衡量一个地区或国家经济效率和劳动生产率的重要指标。具体来说&#xff0c;人均产出可以通过以下公式计算&#xff1a; 人均产出总产出/劳动人口…

图像增强夜视仪行业全面而深入的分析

图像增强夜视设备&#xff08;I2ND 或 INVD&#xff09;是一种增强监视、安全和军事应用的微光可见度的技术。 它允许用户在非常弱的光线甚至完全黑暗的条件下看到东西。 一、市场研究 1. 市场规模与增长趋势 据QYResearch调研团队最新报告&#xff0c;预计2029年全球图像增强…

002 MATLAB语言基础

01 变量命名规则 变量名只能由字母、数字和下划线组成&#xff0c;且必须以字母开头&#xff1b; 变量名区分字母的大小写&#xff1b; 变量名不能超过最大长度限制&#xff1b; 关键字不能作为变量名&#xff0c;如for、end和if等&#xff1b; 注意&#xff1a;存变量命名时…

greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用

简略图 greater<>()(a, b) a > b 返回true&#xff0c;反之返回false less<>()(a, b) a < b 返回true&#xff0c;反之返回false 在cmp中使用&#xff08;正着理解&#xff09; 规则返回true时a在前&#xff0c;反之b在前 在priority_queue中使用 &#xff…

冲破AI 浪潮冲击下的 迷茫与焦虑

在这个科技日新月异的时代&#xff0c;人工智能如汹涌浪潮般席卷而来&#xff0c;不断改变我们的生活。你是否对 AI 充满好奇&#xff0c;却不知它将如何改变你的工作与生活&#xff1f;又是否会在 AI 浪潮的冲击下陷入迷茫与焦虑&#xff1f;《AI 时代&#xff1a;弯道超车新思…

嵌入式LVGL自定义纯数字键盘

嵌入式LVGL自定义纯数字键盘 一、前言二、设置自定义数字键盘三、使用一、前言 嵌入式UI项目中有时候会使用到纯数字密码的需求,所以打算使用LVGL构建自定义的纯数字键盘。 二、设置自定义数字键盘 参考这个文章,以LV_KEYBOARD_MODE_USER_1为例,增加一个数字键盘,如下图所…

第6篇 寻找最大数___ARM C语言程序<二>

Q&#xff1a;如何创建基于ARM处理器的C语言程序寻找一组数据列表中的最大数呢&#xff1f; A&#xff1a;和基于Nios II处理器的C语言程序一样&#xff0c;在ARM处理器C语言中也使用printf库函数显示程序的运行结果&#xff0c;若要调用printf函数&#xff0c;必须在C程序中包…

【11.22更新】Win11 24H2正式版:26100.2454镜像一键获取!

今日&#xff0c;系统之家小编就给大家带来2024年11月最新推出的Windows11 24H2正式版系统&#xff0c;该版本系统包含最新可选更新补丁KB5046740&#xff0c;用户安装后版本号升至26100.2454。更新此系统后&#xff0c;用户就能通过文件资源管理器和桌面上的右键菜单将内容分享…

python小课堂(一)

基础语法 1 常量和表达式2 变量和类型2.1 变量是什么2.2 变量语法 3 变量的类型3.1 动态类型特性 4 注释4.1注释是什么 5 输入输出5.1 print的介绍5.2 input 6 运算符6.1 算术运算符在这里插入图片描述6.2 关系运算符6.3 逻辑运算符6.4赋值运算符 1 常量和表达式 在print()中可…

区块链网络示意图;Aura共识和Grandpa共识(BFT共识)

目录 区块链网络示意图 Aura共识和Grandpa共识(BFT共识) Aura共识 Grandpa共识(BFT共识) Aura与Grandpa的结合 区块链网络示意图 CP Blockchain:这是中央处理区块链(或可能指某种特定的处理单元区块链)的缩写。它可能代表了该区块链网络的主要处理或存储单元。在这…

springboot整合hive

springboot整合hive pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…