FreeRTOS任务挂起与解除
生活随笔
收集整理的這篇文章主要介紹了
FreeRTOS任务挂起与解除
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?任務(wù)掛起的主要工作包括:
將任務(wù)從狀態(tài)列表中移除并掛接到掛起列表中
更新任務(wù)喚醒時間
如果掛起當(dāng)前任務(wù),需要請求切換
/* 掛起任務(wù) */ void vTaskSuspend(TaskHandle_t xTaskToSuspend) {TCB_t *pxTCB;/* 進(jìn)入臨界區(qū) */taskENTER_CRITICAL();{/* 通過任務(wù)句柄獲取任務(wù)TCB */pxTCB = prvGetTCBFromHandle(xTaskToSuspend);traceTASK_SUSPEND(pxTCB);/* 將任務(wù)從狀態(tài)列表中移除,狀態(tài)列表中沒有任何任務(wù) */if(uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0){/* 檢查該優(yōu)先級就緒列表中是否有任務(wù),如果沒有將該優(yōu)先級從當(dāng)前任務(wù)優(yōu)先級記錄中清除 */taskRESET_READY_PRIORITY(pxTCB->uxPriority);}else{mtCOVERAGE_TEST_MARKER();}/* 任務(wù)被掛接在事件列表中 */if(listLIST_ITEM_CONTAINER(&(pxTCB->xEventListItem)) != NULL){/* 將任務(wù)從事件列表中移除 */(void)uxListRemove(&(pxTCB->xEventListItem));}else{mtCOVERAGE_TEST_MARKER();}/* 將任務(wù)掛接到掛起列表中 */vListInsertEnd(&xSuspendedTaskList, &(pxTCB->xStateListItem));#if (configUSE_TASK_NOTIFICATIONS == 1){if(pxTCB->ucNotifyState == taskWAITING_NOTIFICATION){pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;}}#endif}/* 退出臨界區(qū) */taskEXIT_CRITICAL();/* 當(dāng)前調(diào)度器正在運行 */if(xSchedulerRunning != pdFALSE){/* 進(jìn)入臨界區(qū) */taskENTER_CRITICAL();{/* 更新下一個要解除阻塞的時間,防止該任務(wù)就是最近需要喚醒的任務(wù) */prvResetNextTaskUnblockTime();}/* 退出臨界區(qū) */taskEXIT_CRITICAL();}else{mtCOVERAGE_TEST_MARKER();}/* 該任務(wù)為當(dāng)前任務(wù) */if(pxTCB == pxCurrentTCB){/* 調(diào)度器正在運行 */if(xSchedulerRunning != pdFALSE){configASSERT(uxSchedulerSuspended == 0);/* 請求切換任務(wù) */portYIELD_WITHIN_API();}/* 調(diào)度器沒有正在運行 */else{/* 所有任務(wù)都被掛起 */if(listCURRENT_LIST_LENGTH(&xSuspendedTaskList) == uxCurrentNumberOfTasks){/* 沒有當(dāng)前任務(wù)可以運行了 */pxCurrentTCB = NULL;}/* 有部分任務(wù)沒有被掛起 */else{/* 任務(wù)切換上下文 */vTaskSwitchContext();}}}else{mtCOVERAGE_TEST_MARKER();} }?
?
解除任務(wù)掛起主要工作包括:
將任務(wù)從掛起列表重新加入就緒列表
任務(wù)優(yōu)先級高于當(dāng)前任務(wù)優(yōu)先級,請求切換
/* 解除任務(wù)掛起 */ void vTaskResume(TaskHandle_t xTaskToResume) {TCB_t *const pxTCB = xTaskToResume;configASSERT(xTaskToResume);/* 當(dāng)前任務(wù)不能被解除掛起,因為當(dāng)前任務(wù)肯定正在運行 */if((pxTCB != pxCurrentTCB) && (pxTCB != NULL)){/* 進(jìn)入臨界區(qū) */taskENTER_CRITICAL();{/* 任務(wù)確實被掛起 */if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){traceTASK_RESUME(pxTCB);/* 將任務(wù)從掛起列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 將任務(wù)重新加入就緒列表 */prvAddTaskToReadyList(pxTCB);/* 任務(wù)優(yōu)先級大于當(dāng)前任務(wù)優(yōu)先級 */if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){/* 請求切換 */taskYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}}taskEXIT_CRITICAL();}else{mtCOVERAGE_TEST_MARKER();} }?
?
帶中斷的任務(wù)掛起解除和不帶中斷的任務(wù)掛起解除之間的差別,在于任務(wù)優(yōu)先級高于當(dāng)前任務(wù)優(yōu)先級的情況下也不可以立即請求切換任務(wù),而是要等到下一節(jié)拍才能切換。
/* 在中斷中解除任務(wù)掛起 */ BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume) {BaseType_t xYieldRequired = pdFALSE;TCB_t * const pxTCB = xTaskToResume;UBaseType_t uxSavedInterruptStatus;configASSERT(xTaskToResume);portASSERT_IF_INTERRUPT_PRIORITY_INVALID();/* 進(jìn)入臨界區(qū)(意味著不能進(jìn)入SysTick中斷) */uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();{/* 任務(wù)確實被掛起 */if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){traceTASK_RESUME_FROM_ISR(pxTCB);/* 調(diào)度器沒有被掛起 */if(uxSchedulerSuspended == (UBaseType_t)pdFALSE){/* 該任務(wù)優(yōu)先級高于當(dāng)前任務(wù)優(yōu)先級 */if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){/* 在下一個節(jié)拍時進(jìn)行任務(wù)切換 */xYieldRequired = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}/* 將任務(wù)從掛起列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 將任務(wù)重新加入就緒列表 */prvAddTaskToReadyList(pxTCB);}/* 調(diào)度器被掛起 */else{/* 將任務(wù)加入掛起時就緒列表 */vListInsertEnd(&(xPendingReadyList), &(pxTCB->xEventListItem));}}else{mtCOVERAGE_TEST_MARKER();}}/* 退出臨界區(qū) */portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);return xYieldRequired; }?
總結(jié)
以上是生活随笔為你收集整理的FreeRTOS任务挂起与解除的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu搭建nfs服务器
- 下一篇: STM32之定时器原理