登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
每日签到
每天签到奖励2圆-6圆
发帖说明
VIP申请
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
VIP申请
VIP网盘
网盘
联系我们
每日签到
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
安全
›
Free-RTOS任务删除函数vTaskDelete()解析
Free-RTOS任务删除函数vTaskDelete()解析
[ 复制链接 ]
葛雅隽
2025-6-8 12:46:15
目录
函数 vTaskDelete()
函数prvDeleteTCB()
总结
函数 vTaskDelete()
此函数用于删除已被创建的任务,被删除的任务将从
就绪态任务列表
、
阻塞态任务列表
、
挂起态任务列表
和
事件列表中移除
,要注意的是,空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存,则需要由用户在任务被删除前提前释放,否则将导致内存泄露。若使用此函数,需要在FreeRTOSConfig.h文件中将宏INCLUDE_vTaskDelete配置为 1。
使用vTaskDelete函数删除任务时,
如果参数给的是NULL,代表删除的是任务本身
,任务的
任务控制块内存和任务堆栈内存是由空闲任务释放的
,而若参数不是NULL,是其他任务的任务句柄时,其他任务的控制块内存和任务堆栈内存是由该任务删除函数进行释放的。vTaskDelete()函数如下:
void vTaskDelete(TaskHandle_t xTaskToDelete)
{
TCB_t *pxTCB;
taskENTER_CRITICAL();
{
/* 得到要删除的任务句柄(任务控制块)
该函数实际上是一个宏定义,并使用三目运算符,如果传入NULL则返回的是自身的任务控制块*/
pxTCB = prvGetTCBFromHandle(xTaskToDelete);
/* 将任务从任务所在任务状态列表(就绪态任务列表或阻塞态任务列表)中移除
如果移除后列表中的列表项数量为 0,那么就需要更新任务优先级记录,
因为此时系统中可能已经没有和被删除任务相同优先级的任务了 */
if (uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0)
{
taskRESET_READY_PRIORITY(pxTCB->uxPriority);
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 任务是否在等待事件 */
if (listLIST_ITEM_CONTAINER(&(pxTCB->xEventListItem)) != NULL)
{
/* 将被删除任务的事件列表项,从所在事件列表中移除 */
(void)uxListRemove(&(pxTCB->xEventListItem));
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 递增 uxTaskNumber 变量以通知内核调试器重新生成任务列表。
这些操作有助于维护任务管理和调试的一致性和准确性 */
uxTaskNumber++;
/* 如果是删除自身 */
if (pxTCB == pxCurrentTCB)
{
/* 任务是无法删除任务本身的,因为需要将上下文切换到另一个任务,
于是需要将任务添加到任务待删除列表中,空闲任务将检查待删除列表,
有空闲任务释放调度器为待删除任务分配的TCB和堆栈内存空间 */
vListInsertEnd(&xTasksWaitingTermination, &(pxTCB->xStateListItem));
/* 等待删除列表+1,它用来告诉空闲任务有多少个待删除任务需要被删除 */
++uxDeletedTasksWaitingCleanUp;
/* 调试用的 */
portPRE_TASK_DELETE_HOOK(pxTCB, &xYieldPending);
}
else
{
/* 任务总数减一 */
--uxCurrentNumberOfTasks;
/* 删除给定的任务控制块 */
prvDeleteTCB(pxTCB);
/* 更新下一个任务的阻塞超时时间,因为被删除任务的阻塞超时时间已经无效
需要更新下个任务的阻塞时间 */
prvResetNextTaskUnblockTime();
}
traceTASK_DELETE(pxTCB);
}
/* 退出临界区 */
taskEXIT_CRITICAL();
/* 如果当前正在运行的任务被删除,则需要进行任务调度切换 */
if (xSchedulerRunning != pdFALSE)
{
/* 删除的是自身 */
if (pxTCB == pxCurrentTCB)
{
/* 此时任务调度器不能处于挂起状态 */
configASSERT(uxSchedulerSuspended == 0);
/* 进行任务切换,不会马上删除自身,而是会在空闲任务的时候删除 */
portYIELD_WITHIN_API();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
复制代码
1.该函数会先获取待删除任务的任务句柄,并将任务从所处的状态列表中移除。若该任务正在等待事件,将其从事件列表中移除。
2.判断删除的是否是任务本身,如果是任务本身需要进行一些动作,因为任务本身是无法删除任务本身的,需要将任务添加到待删除任务列表中,空闲任务会检查待删除任务列表并释放由调度器分配给待删除任务的内存。
3.如果删除的不是任务本身,调用 prvDeleteTCB() 函数删除对应的任务,该函数内部会对待删除的任务内存进行释放。
4.如果删除的是当前正在运行的任务,那么调度器就需要进行任务切换,且此时调度器不能处于挂起状态。
注意
:空闲任务负责释放由 RTOS 内核分配给已删除任务的内存。因此,如果应用程序调用了 vTaskDelete()删除自身,
请务必确保空闲任务获得足够的微控制器处理时间
。
函数prvDeleteTCB()
static void prvDeleteTCB(TCB_t *pxTCB)
{
portCLEAN_UP_TCB(pxTCB);
#if (configUSE_NEWLIB_REENTRANT == 1)
{
_reclaim_reent(&(pxTCB->xNewLib_reent));
}
#endif /* configUSE_NEWLIB_REENTRANT */
/* 当系统只支持动态内存管理时, 待删除任务所占用的内存空间是通过动态内存管理分配的,
因此只需要将内存空间通过动态内存管理释放掉即可,当系统支持静态内存管理和动态内存管理时,
则需要分情况讨论 */
#if ((configSUPPORT_DYNAMIC_ALLOCATION == 1) && (configSUPPORT_STATIC_ALLOCATION == 0) && (portUSING_MPU_WRAPPERS == 0))
{
/* 该任务是被动态分配,所以直接释放堆栈和TCB */
vPortFree(pxTCB->pxStack);
vPortFree(pxTCB);
}
/* 任务可以静态分配,也可以动态分配,所以在尝试释放内存之前,需要检查静态分配的内容 */
#elif (tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1)
{
/* 待删除任务的任务控制块和任务栈都是由动态内存管理分配的 */
if (pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB)
{
/* 堆栈和任务控制块是动态分配的,所以直接释放 */
vPortFree(pxTCB->pxStack);
vPortFree(pxTCB);
}
/* 待删除任务的任务控制块是由动态内存管理分配的 */
else if (pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY)
{
/* 只需要释放TCB的内存 */
vPortFree(pxTCB);
}
/* 任务栈和控制块内存都不是动态分配的,这种情况下,
待删除任务的任务控制块和任务栈空间所占用的内存 由用户管理 */
else
{
configASSERT(pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB)
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
}
复制代码
该函数比较简单,就是判断任务是以何种方式创建的,如果是以动态方式创建的就直接释放掉相应内存,如果是以静态方式创建的那么内存的释放应由用户自行管控。
总结
可以看到其实删除任务函数的逻辑并不复杂,当传入其他任务的句柄时将会将其从状态列表中移除,并交由prvDeleteTCB()函数进行释放内存。如果传入的是NULL时即代表删除任务本身,此时将由空闲任务负责释放被删除的任务内存,所以需要确保空闲任务能够有足够的时间去执行删除任务的内存资源释放,并且空闲任务的优先级通常设置为最低的,如果空闲任务一直得不到执行那么被删除的任务的内存也就无法得到释放了。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
Free
RTOS
任务
删除
函数
相关帖子
C# 定时任务 Quartz.NET 的使用
美丽的函数图像之隐函数
美丽的函数图像之隐函数
P5574 [CmdOI2019] 任务分配问题
百度域名批量删除
C语言之文件流常用标准库函数
宝塔终端怎么删除SSH登录日志
01-右键菜单添加删除工具
求前缀函数的线性算法(KMP)
Flink和StreamPark自定义UDF函数的使用
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
C# 定时任务 Quartz.NET 的使用
0
847
滤冽
2025-08-24
业界
美丽的函数图像之隐函数
0
57
辖瑁地
2025-08-25
业界
美丽的函数图像之隐函数
0
986
沦嘻亟
2025-08-25
业界
P5574 [CmdOI2019] 任务分配问题
0
588
屠焘
2025-08-30
软件
百度域名批量删除
0
38
新程序
2025-09-03
业界
C语言之文件流常用标准库函数
0
129
辜酗徇
2025-09-04
问答
宝塔终端怎么删除SSH登录日志
0
28
新程序
2025-09-04
业界
01-右键菜单添加删除工具
0
283
支智敏
2025-09-07
安全
求前缀函数的线性算法(KMP)
0
535
映各
2025-09-07
安全
Flink和StreamPark自定义UDF函数的使用
0
197
汤昕昕
2025-09-08
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
程序
签约作者
程序园优秀签约作者
发帖
葛雅隽
2025-6-8 12:46:15
关注
0
粉丝关注
10
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9984
杭环
9988
凶契帽
9988
4
氛疵
9988
5
黎瑞芝
9988
6
猷咎
9986
7
里豳朝
9986
8
肿圬后
9986
9
蝓俟佐
9984
10
虽裘侪
9984
查看更多