直接上代码

 1     void vTaskDelete( TaskHandle_t xTaskToDelete )2     {3     TCB_t *pxTCB;4 5         taskENTER_CRITICAL();6         {7             /* If null is passed in here then it is the calling task that is8             being deleted. */  如果xTaskToDel为空,删除自己9             pxTCB = prvGetTCBFromHandle( xTaskToDelete );
10
11             /* Remove task from the ready list. */  从就绪表中删除
12             if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )  删除后,列表长度为0
13             {
14                 taskRESET_READY_PRIORITY( pxTCB->uxPriority );  ##1,更新"最高优先级变量",函数实现见后
15             }
16             else
17             {
18                 mtCOVERAGE_TEST_MARKER();
19             }
20
21             /* Is the task waiting on an event also? */               事件、信号量的队列中,里面有两个列表:WaitToSend和WaitToRcv。               而任务控制块当中的两个列表项item,一个是任务状态列表项,它可能属于就绪列表、挂起列表、延时列表等,上边就是在从任务状态的种种列表中删除这个任务。               另一个列表项item,是事件列表项,它可能属于某个信号量、事件的队列中的,WaitToSend或WTRcv列表。
22             if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )  Container其实就是个List表头,这个表头属于WaitToSend或WaitToRev.
23             {
24                 ( void ) uxListRemove( &( pxTCB->xEventListItem ) );  根据Item找到他的管理表头,再将这个Item从列表中删除.
25             }
26             else
27             {
28                 mtCOVERAGE_TEST_MARKER();
29             }
30
31             /* Increment the uxTaskNumber also so kernel aware debuggers can
32             detect that the task lists need re-generating.  This is done before
33             portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will
34             not return. */
35             uxTaskNumber++;
36
37             if( pxTCB == pxCurrentTCB )
38             {
39                 /* A task is deleting itself.  This cannot complete within the
40                 task itself, as a context switch to another task is required.
41                 Place the task in the termination list.  The idle task will
42                 check the termination list and free up any memory allocated by
43                 the scheduler for the TCB and stack of the deleted task. */                   删除自己:空闲任务来释放这个任务申请的TCB和Stack ##2,idle task内容见后
44                 vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );
45
46                 /* Increment the ucTasksDeleted variable so the idle task knows
47                 there is a task that has been deleted and that it should therefore
48                 check the xTasksWaitingTermination list. */
49                 ++uxDeletedTasksWaitingCleanUp;  全局变量,记录有多少个任务需要释放内存。
50
51                 /* The pre-delete hook is primarily for the Windows simulator,
52                 in which Windows specific clean up operations are performed,
53                 after which it is not possible to yield away from this task -
54                 hence xYieldPending is used to latch that a context switch is
55                 required. */
56                 portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );  任务删除钩子函数
57             }
58             else
59             {
60                 --uxCurrentNumberOfTasks;  ##3 当前任务数,全局变量
61                 prvDeleteTCB( pxTCB );     删除TCB方法 ##4
62
63                 /* Reset the next expected unblock time in case it referred to
64                 the task that has just been deleted. */
65                 prvResetNextTaskUnblockTime();   ##5
66             }
67
68             traceTASK_DELETE( pxTCB );
69         }
70         taskEXIT_CRITICAL();
71
72         /* Force a reschedule if it is the currently running task that has just
73         been deleted. */
74         if( xSchedulerRunning != pdFALSE )  调度器在运行
75         {
76             if( pxTCB == pxCurrentTCB )  删除的是当前运行的任务
77             {
78                 configASSERT( uxSchedulerSuspended == 0 );
79                 portYIELD_WITHIN_API();  执行任务切换
80             }
81             else
82             {
83                 mtCOVERAGE_TEST_MARKER();
84             }
85         }
86     }

##1

(1)configUSE_PORT_OPTIMISED_TASK_SELECTION被定义为1的时候:

    /* A port optimised version is provided, call it only if the TCB being resetis being referenced from a ready list.  If it is referenced from a delayedor suspended list then it won't be in a ready list. */#define taskRESET_READY_PRIORITY( uxPriority )                                                        \{                                                                                                    \if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 )    \{                                                                                                \portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) );                            \}                                                                                                \}

如果这个优先级的 任务就绪列表的长度为0,则调用下面的 portRESET_READY_PRIOR

#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1/* Store/clear the ready priorities in a bit map. */#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )/*-----------------------------------------------------------*/#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) )#endif /* taskRECORD_READY_PRIORITY */

uxTopReadyPrior的定义:

PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority         = tskIDLE_PRIORITY;  //tskIDLE_PRIOR = 0
typedef unsigned long           UBaseType_t;

uxTopReadyPrior变量的每一位都表示,这一个优先级上边,有没有就绪任务。

如果这个优先级的 任务就绪列表的长度为0,则清零 uxTopReadyPrior变量的某一位,空闲任务优先级是0.

(2)configUSE_PORT_OPTIMISED_TASK_SELECTION被定义为0的时候:

taskRESET_READY_PRIORITY( uxPriority ) 被定义为空,只用变量uxTopReadyPrior来记录最高就绪的优先级。

##2  空闲任务

如果某个任务要调用函数 vTaskDelete()删除自身,那么这个任务的任务控制块 TCB 和任务堆栈等

这些由 FreeRTOS 系统自动分配的内存需要在空闲任务中释放掉 。空闲任务IdleTask的操作参见"低功耗模式 和 空闲任务"章节。

##3  当前任务数

uxCurrentNumOfTasks 在任务抢占的时候,应该会用,先保留。

##4  看看TCB和任务堆栈哪个是动态创建的,把它free掉,如果是静态的那就不用free了...

 1 static void prvDeleteTCB( TCB_t *pxTCB )2     {3         /* This call is required specifically for the TriCore port.  It must be4         above the vPortFree() calls.  The call is also used by ports/demos that5         want to allocate and clean RAM statically. */6         portCLEAN_UP_TCB( pxTCB );  空的7 8         /* Free up the memory allocated by the scheduler for the task.  It is up9         to the task to free any memory allocated at the application level. */
10         #if ( configUSE_NEWLIB_REENTRANT == 1 )   不知道是啥
11         {
12             _reclaim_reent( &( pxTCB->xNewLib_reent ) );
13         }
14         #endif /* configUSE_NEWLIB_REENTRANT */
15
16         #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) )
17         {
18             /* The task can only have been allocated dynamically - free both
19             the stack and TCB. */   这些宏导致TCB和Stack只能是动态创建的,直接free掉
20             vPortFree( pxTCB->pxStack );
21             vPortFree( pxTCB );
22         }
23         #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 )
24         {
25             /* The task could have been allocated statically or dynamically, so
26             check what was statically allocated before trying to free the
27             memory. */
28             if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB )
29             {
30                 /* Both the stack and TCB were allocated dynamically, so both
31                 must be freed. */  TCB和stack都是动态创建的
32                 vPortFree( pxTCB->pxStack );
33                 vPortFree( pxTCB );
34             }
35             else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY )
36             {
37                 /* Only the stack was statically allocated, so the TCB is the
38                 only memory that must be freed. */  只有TCB是动态创建的
39                 vPortFree( pxTCB );
40             }
41             else
42             {
43                 /* Neither the stack nor the TCB were allocated dynamically, so
44                 nothing needs to be freed. */  TCB和stack都不是动态创建的
45                 configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB    )
46                 mtCOVERAGE_TEST_MARKER();
47             }
48         }
49         #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
50     }

##5

重新计算一下还要多长时间执行下一个任务,也就是下一个任务的解锁时间。

如果下个任务的解锁,刚好是被删除的那个任务,那么变量NextTaskUnblockTime就不对了,所以要重新从延时列表中获取一下。

  它是从延时列表的头部来获取的任务TCB,也可以再次验证,延时任务列表是按延时时间排序的。   见“List_t列表”

如果延时列表是空的,直接给默认值MAX_DELAY赋给NextTaskUnblockTime.

 1 static void prvResetNextTaskUnblockTime( void ) 2 {3 TCB_t *pxTCB;4 5     if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )  延时列表是空的6     {7         /* The new current delayed list is empty.  Set xNextTaskUnblockTime to8         the maximum possible value so it is    extremely unlikely that the9         if( xTickCount >= xNextTaskUnblockTime ) test will pass until
10         there is an item in the delayed list. */
11         xNextTaskUnblockTime = portMAX_DELAY;
12     }
13     else
14     {
15         /* The new current delayed list is not empty, get the value of
16         the item at the head of the delayed list.  This is the time at
17         which the task at the head of the delayed list should be removed
18         from the Blocked state. */
19         ( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
20         xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xStateListItem ) );
21     }
22 }

留白

freeRTOS 删除任务相关推荐

  1. Oracle所有错误类型

    ORA-00001: 违反唯一约束条件 (.)  ORA-00017: 请求会话以设置跟踪事件  ORA-00018: 超出最大会话数  ORA-00019: 超出最大会话许可数  ORA-00020 ...

  2. oracle常用errcode

    ORA-00001: 违反唯一约束条件 (.)     ORA-00017: 请求会话以设置跟踪事件      ORA-00018: 超出最大会话数      ORA-00019: 超出最大会话许可数 ...

  3. 【STM32】FreeRTOS创建和删除任务示例(静态方法)(了解)

    00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 结果验证 06. 附录 07. 参考 01. 概述 FreeRTOS中创建和删除任务A ...

  4. 【STM32】FreeRTOS创建和删除任务示例(动态方法)

    00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 结果验证 06. 附录 07. 参考 01. 概述 FreeRTOS中创建和删除任务A ...

  5. FreeRTOS任务创建和删除

    任务创建和删除的API函数 xTaskCreate():使用动态方法创建一个任务 xTaskCreateStatic():使用静态方法创建一个任务 xTaskCreateRestricated():创 ...

  6. FreeRTOS笔记(四):任务创建/删除,挂起/解挂详解

    FreeRTOS笔记(四):任务创建/删除,挂起/解挂详解 在第二篇笔记中介绍了任务创建的API,并且简单使用了相关API,本文将详细介绍任务创建的过程. 一.任务创建 任务创建步骤为: 1.创建任务 ...

  7. freeRTOSConfig.h文件对FreeRTOS进行系统配置

    FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制.每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核.这个配置文件是针 ...

  8. freertos zynq 移植_Zynq-7000 FreeRTOS(一)系统移植配置

    软件版本:VIvado HLx 2018.2 从FreeRTOS的官网中下载源代码: https://www.freertos.org/a00104.html 图:FreeRTOS的官网 上图中,点击 ...

  9. FreeRTOS初步认识

    源:FreeRTOS初步认识 用了半天时间对FreeRTOS有了一个初步的认识,大概总结一下,其中混杂了系统实现和实际应用方面的问题. 现只是以应用为目的,实现方面待以后进一步研究. 1.FreeRT ...

最新文章

  1. python求5_python5
  2. @autowired注解_SpringBoot常用注解大全
  3. 数据分析:主成分分析(PCA)1
  4. 5.Hadoop的学习(Hadoop的配置(伪分布式的搭建)-1)
  5. Android 学习Kotlin吗?
  6. Flex 3 metadata tags 标签
  7. 中img拉伸_8个拉伸动作,帮你调动全身肌肉,提高柔韧性,缓解疲劳放松心情...
  8. Python 2 结束支持,Ubuntu 20.04 LTS 继续进行将其移除的工作
  9. Element-UI中el-input输入值不显示
  10. virtualenv -- python虚拟沙盒
  11. 掌握用 STL 中的 SET 动态维护 “各类型凸壳” / “凸包”
  12. “2021年度全球十大人工智能治理事件”:数据、算法、伦理受关注,AI发展需治理同行
  13. unity开发下的C#学习笔记——第四章:鼠标匀速跟随
  14. OpenCV实现人脸对齐
  15. 鹏业安装算量软件8.0.0.41 升级内容
  16. 用于视觉问答的相互注意融合模型《Reciprocal Attention Fusion for Visual Question Answering》
  17. MySQl 表基本查询操作
  18. 无线射频专题《射频合规,2.4GHz WIFI频谱模板》
  19. C# 关于dgv中DataGridViewComboBoxCell触发事件
  20. nacos注册服务的时候报错server is DOWN now, please try again later!

热门文章

  1. Mac上unity的汉化
  2. vb实验第四版答案_Visual Basic程序设计教程(第4版)实验答案.doc
  3. 淘系面向业务价值的精细化流量管控实战
  4. 三种常见的卷积概述(线性卷积周期卷积圆周卷积)
  5. HTML5+CSS3+JavaScript 阶段性实践小案例——京东购物车
  6. (转)浅谈风力发电机组齿轮箱
  7. 耐看娱乐冲刺上市:所持部分股权遭冻结,张栗坤、钟山为实控人
  8. mysql8.0 新特性 sql_mode(mysql 报错1055)
  9. 免费开源的php源码加密--screw plus
  10. AlertDialog的六种创建方式