| 函数 | 描述 |
| vTaskSuspend() | 挂起一个任务,使任务处于挂起态 |
| vTaskSuspendAll() | 调度锁关闭函数,即禁止调度器调用,相当于将所有的任务挂起 |
| vTaskResume() | 释放一个挂起的任务 |
| xTaskResumeAll() | 调度锁开启函数,即恢复调度器调用,同时将列表xPendingReadyList 中的任务插入到对应的就绪表中,可与函数vTaskSuspendAll()配合,使用在一个临界区太长而不适合简单地关中断的代码段 |
| xTaskResumeFromISR() | 在中断函数中使用,释放一个挂起的任务 |
任务挂起中其它重要的API函数(介绍过的函数不列出,请参考前面的文章):
| 函数 | 描述 |
| prvTaskIsTaskSuspended() | 判断任务是否挂起,内部调用函数 |
2. 任务的挂起函数vTaskSuspend()
任务函数挂起功能是将任务插入挂起列表中,此时任务处于挂起态,调度器不能对该任务进行调度。使用此函数必须将INCLUDE_vTaskSuspend设置为1,在FreeRTOSConfig.h中定义,函数原型如下:
/********************************************************
参数:xTaskToSuspend :需要挂起任务的句柄,若为NULL,则挂起任务本身
返回:无
*********************************************************/
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
函数代码如下:
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
{
TCB_t *pxTCB;
taskENTER_CRITICAL(); /* 进入临界状态 */
{
/* 等到挂起任务的TCB,若参数为NULL,则挂起任务为当前正在运行的任务(即自己删除自己) */
pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
traceTASK_SUSPEND( pxTCB );
/*
* 删除任务的状态信息,不让任务的状态列表项挂接到任何一个列表上
* 不同优先级的任务放在不同任务就绪列表,用一个32位变量表示就绪位,相应Bit位为1表示对应就绪表中有任务
* 如返回值为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();
}
/* 将任务的状态列表项插入挂起列表的末尾 */
vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );
}
taskEXIT_CRITICAL(); /* 退出临界状态 */
/* 如果任务调度器正在运行 */
if( xSchedulerRunning != pdFALSE )
{
taskENTER_CRITICAL(); /* 进入临界状态 */
{
/* 重置下一个任务的解锁时间,防止下一个解锁任务为刚刚挂起的任务 */
prvResetNextTaskUnblockTime();
}
taskEXIT_CRITICAL(); /* 退出临界状态 */
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 如果TCB为当前正在运行的任务 */
if( pxTCB == pxCurrentTCB )
{
/* 如果任务调度器正在运行 */
if( xSchedulerRunning != pdFALSE )
{
configASSERT( uxSchedulerSuspended == 0 );
/* 执行一次任务切换,如果需要挂起的任务是正在运行的任务,已经将它放在挂起列表中,就会切换到其它任务 */
portYIELD_WITHIN_API();
}
else /* 如果任务调度器关闭 */
{
/* 如果就绪列表的任务数量等于任务总数量,一般不会执行这里,因为至少会有一个空闲任务 */
if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
{
pxCurrentTCB = NULL; /* 当前运行的任务TCB执行NULL */
}
else
{
vTaskSwitchContext(); /* 获取下一个任务(分析任务切换时具体说明) */
}
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
说明:
-
若函数带入的任务句柄为N


2437

被折叠的 条评论
为什么被折叠?



