1.任务的挂起
void vTaskSuspend( TaskHandle_t xTaskToSuspend ){TCB_t *pxTCB;/* 进入临界区 */taskENTER_CRITICAL();{/* If null is passed in here then it is the running task that isbeing suspended. *//* 获取任务控制块,若为NULL则挂起自身 */pxTCB = prvGetTCBFromHandle( xTaskToSuspend );traceTASK_SUSPEND( pxTCB );/* Remove task from the ready/delayed list and place in thesuspended list. *//*从就绪/延迟列表中删除任务 */if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 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();}/* 将任务放在挂起链表中 */vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );}taskEXIT_CRITICAL(); /* 退出临界区 */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. *//*没有其他任务准备就绪,因此将pxCurrentTCB设置回NULL*/pxCurrentTCB = NULL;}else{/* 若还有没被挂起的任务,则获取下一个要运行的任务 */vTaskSwitchContext();}}}else{if( xSchedulerRunning != pdFALSE ) /* 调度器正常运行 */{/* A task other than the currently running task was suspended,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();}}}
2.任务的恢复
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. */if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) /* 任务控制块不能为NULL和当前任务 */{taskENTER_CRITICAL();{if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE ) /* 判断任务是否被挂起 */{traceTASK_RESUME( pxTCB );/* As we are in a critical section we can access the readylists even if the scheduler is suspended. */( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); /* 从挂起列表中移除 */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();}}