日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FreeRTOS任务挂起与解除

發(fā)布時間:2025/3/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FreeRTOS任务挂起与解除 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?任務掛起的主要工作包括:

將任務從狀態(tài)列表中移除并掛接到掛起列表中

更新任務喚醒時間

如果掛起當前任務,需要請求切換

/* 掛起任務 */ void vTaskSuspend(TaskHandle_t xTaskToSuspend) {TCB_t *pxTCB;/* 進入臨界區(qū) */taskENTER_CRITICAL();{/* 通過任務句柄獲取任務TCB */pxTCB = prvGetTCBFromHandle(xTaskToSuspend);traceTASK_SUSPEND(pxTCB);/* 將任務從狀態(tài)列表中移除,狀態(tài)列表中沒有任何任務 */if(uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0){/* 檢查該優(yōu)先級就緒列表中是否有任務,如果沒有將該優(yōu)先級從當前任務優(yōu)先級記錄中清除 */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));#if (configUSE_TASK_NOTIFICATIONS == 1){if(pxTCB->ucNotifyState == taskWAITING_NOTIFICATION){pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION;}}#endif}/* 退出臨界區(qū) */taskEXIT_CRITICAL();/* 當前調度器正在運行 */if(xSchedulerRunning != pdFALSE){/* 進入臨界區(qū) */taskENTER_CRITICAL();{/* 更新下一個要解除阻塞的時間,防止該任務就是最近需要喚醒的任務 */prvResetNextTaskUnblockTime();}/* 退出臨界區(qū) */taskEXIT_CRITICAL();}else{mtCOVERAGE_TEST_MARKER();}/* 該任務為當前任務 */if(pxTCB == pxCurrentTCB){/* 調度器正在運行 */if(xSchedulerRunning != pdFALSE){configASSERT(uxSchedulerSuspended == 0);/* 請求切換任務 */portYIELD_WITHIN_API();}/* 調度器沒有正在運行 */else{/* 所有任務都被掛起 */if(listCURRENT_LIST_LENGTH(&xSuspendedTaskList) == uxCurrentNumberOfTasks){/* 沒有當前任務可以運行了 */pxCurrentTCB = NULL;}/* 有部分任務沒有被掛起 */else{/* 任務切換上下文 */vTaskSwitchContext();}}}else{mtCOVERAGE_TEST_MARKER();} }

?

?

解除任務掛起主要工作包括:

將任務從掛起列表重新加入就緒列表

任務優(yōu)先級高于當前任務優(yōu)先級,請求切換

/* 解除任務掛起 */ void vTaskResume(TaskHandle_t xTaskToResume) {TCB_t *const pxTCB = xTaskToResume;configASSERT(xTaskToResume);/* 當前任務不能被解除掛起,因為當前任務肯定正在運行 */if((pxTCB != pxCurrentTCB) && (pxTCB != NULL)){/* 進入臨界區(qū) */taskENTER_CRITICAL();{/* 任務確實被掛起 */if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){traceTASK_RESUME(pxTCB);/* 將任務從掛起列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 將任務重新加入就緒列表 */prvAddTaskToReadyList(pxTCB);/* 任務優(yōu)先級大于當前任務優(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();} }

?

?

帶中斷的任務掛起解除和不帶中斷的任務掛起解除之間的差別,在于任務優(yōu)先級高于當前任務優(yōu)先級的情況下也不可以立即請求切換任務,而是要等到下一節(jié)拍才能切換。

/* 在中斷中解除任務掛起 */ 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();/* 進入臨界區(qū)(意味著不能進入SysTick中斷) */uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();{/* 任務確實被掛起 */if(prvTaskIsTaskSuspended(pxTCB) != pdFALSE){traceTASK_RESUME_FROM_ISR(pxTCB);/* 調度器沒有被掛起 */if(uxSchedulerSuspended == (UBaseType_t)pdFALSE){/* 該任務優(yōu)先級高于當前任務優(yōu)先級 */if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){/* 在下一個節(jié)拍時進行任務切換 */xYieldRequired = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}/* 將任務從掛起列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 將任務重新加入就緒列表 */prvAddTaskToReadyList(pxTCB);}/* 調度器被掛起 */else{/* 將任務加入掛起時就緒列表 */vListInsertEnd(&(xPendingReadyList), &(pxTCB->xEventListItem));}}else{mtCOVERAGE_TEST_MARKER();}}/* 退出臨界區(qū) */portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);return xYieldRequired; }

?

總結

以上是生活随笔為你收集整理的FreeRTOS任务挂起与解除的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。