日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

FreeRTOS调度器挂起与解除

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

通過分析任務(wù)切換,我們知道任務(wù)切換的兩種方法:系統(tǒng)節(jié)拍器中斷、調(diào)用portYIELD產(chǎn)生PendSV中斷。

在系統(tǒng)節(jié)拍器中斷中,如果調(diào)度器被掛起,僅僅將調(diào)度器掛起時間加一(在解除掛起后需要補償這些節(jié)拍),并不會檢查是否有任務(wù)需要切換。

/* 系統(tǒng)節(jié)拍加一 */ BaseType_t xTaskIncrementTick(void) {BaseType_t xSwitchRequired = pdFALSE;/* 調(diào)度器沒有被掛起 */if(uxSchedulerSuspended == (UBaseType_t)pdFALSE){......}/* 調(diào)度器被掛起 */else{/* 掛起時間加一 */++uxPendedTicks;}/* 前面有程序因為各種原因,要求延遲到現(xiàn)在切換 */if(xYieldPending != pdFALSE){/* 請求切換任務(wù),最終進(jìn)入PendSV異常,是否切換上下文還是在于PendSV */xSwitchRequired = pdTRUE;}return xSwitchRequired; }

在PendSV中斷中,如果調(diào)度器被掛起,則不進(jìn)行上下文切換,通過xYieldPending將任務(wù)切換延遲到下一個節(jié)拍。

/* 任務(wù)切換上下文 */ void vTaskSwitchContext(void) {/* 調(diào)度器被掛起 */if(uxSchedulerSuspended != (UBaseType_t)pdFALSE){/* 等到下一次節(jié)拍的時候再切換上下文 */xYieldPending = pdTRUE;}/* 調(diào)度器沒有掛起 */else{......} }

也就是說,只要將調(diào)度器掛起,就肯定不會進(jìn)行任務(wù)切換。

?

?

掛起調(diào)度器非常簡單,只要讓uxSchedulerSuspended不等于pdFALSE(0)即可。調(diào)度器可以多次掛起,但是對應(yīng)的也要進(jìn)行多次解除掛起。

/* 掛起調(diào)度器 */ void vTaskSuspendAll(void) {/* 掛起層數(shù)加一 */++uxSchedulerSuspended; }

當(dāng)完全解除調(diào)度器掛起時,需要進(jìn)行如下工作:

檢查在調(diào)度器掛起期間是否有任務(wù)進(jìn)入就緒態(tài),有則要將其從掛起期間就緒任務(wù)列表中移除,重新掛接到就緒任務(wù)列表

更新下一個需要解除阻塞的任務(wù),的解除時間

要對之前調(diào)度器掛起期間產(chǎn)生的節(jié)拍進(jìn)行補償

對于延遲切換任務(wù)到下一個節(jié)拍的請求,在這里提供一次切換機會

/* 解除調(diào)度器掛起 */ BaseType_t xTaskResumeAll( void ) {TCB_t *pxTCB = NULL;BaseType_t xAlreadyYielded = pdFALSE;configASSERT(uxSchedulerSuspended);/* 進(jìn)入臨界區(qū) */taskENTER_CRITICAL();{/* 調(diào)度器掛起層數(shù)減一 */--uxSchedulerSuspended;/* 調(diào)度器掛起完全解除 */if(uxSchedulerSuspended == (UBaseType_t)pdFALSE){/* 系統(tǒng)當(dāng)前任務(wù)數(shù)大于0 */if(uxCurrentNumberOfTasks > (UBaseType_t)0U){/* 掛起時進(jìn)入就緒的任務(wù)列表不為空 */while(listLIST_IS_EMPTY(&xPendingReadyList) == pdFALSE){/* 從掛起時進(jìn)入就緒的任務(wù)列表中取出一個任務(wù) */pxTCB = listGET_OWNER_OF_HEAD_ENTRY((&xPendingReadyList));/* 將任務(wù)從事件列表中移除 */(void)uxListRemove(&(pxTCB->xEventListItem));/* 將任務(wù)從狀態(tài)列表中移除 */(void)uxListRemove(&(pxTCB->xStateListItem));/* 將任務(wù)加入就緒任務(wù)列表 */prvAddTaskToReadyList(pxTCB);/* 如果任務(wù)優(yōu)先級高于當(dāng)前任務(wù)優(yōu)先級,則請求在下一個節(jié)拍時切換 */if(pxTCB->uxPriority >= pxCurrentTCB->uxPriority){xYieldPending = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}}/* 有任務(wù)在掛起期間就緒 */if(pxTCB != NULL){/* 更新下一個要解除阻塞的時間 */prvResetNextTaskUnblockTime();}{/* 調(diào)度器掛起時間 */UBaseType_t uxPendedCounts = uxPendedTicks;/* 調(diào)度器掛起時間大于1個節(jié)拍 */if(uxPendedCounts > (UBaseType_t)0U){/* 將所有節(jié)拍重新補上 */do{/* 節(jié)拍數(shù)加一,如果需要切換任務(wù),則請求在下一個節(jié)拍時切換 */if(xTaskIncrementTick() != pdFALSE){xYieldPending = pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}--uxPendedCounts;}while(uxPendedCounts > (UBaseType_t)0U);uxPendedTicks = 0;}else{mtCOVERAGE_TEST_MARKER();}}/* 原來請求在下一個節(jié)拍時切換的任務(wù),在這里直接請求切換 */if(xYieldPending != pdFALSE){#if (configUSE_PREEMPTION != 0){/* 已經(jīng)切換過任務(wù) */xAlreadyYielded = pdTRUE;}#endiftaskYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}}else{mtCOVERAGE_TEST_MARKER();}}/* 退出臨界區(qū) */taskEXIT_CRITICAL();/* 返回是否已經(jīng)切換過任務(wù) */return xAlreadyYielded; }

?

總結(jié)

以上是生活随笔為你收集整理的FreeRTOS调度器挂起与解除的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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