- μC/OS-III內(nèi)核實現(xiàn)與應(yīng)用開發(fā)實戰(zhàn)指南:基于STM32
- 劉火良 楊森編著
- 1040字
- 2019-08-01 11:36:00
5.2 實現(xiàn)阻塞延時
阻塞延時的阻塞是指任務(wù)調(diào)用該延時函數(shù)后,會被剝奪CPU使用權(quán),然后進(jìn)入阻塞狀態(tài),直到延時結(jié)束,任務(wù)重新獲取CPU使用權(quán)才可以繼續(xù)運行。在任務(wù)阻塞的這段時間,CPU可以執(zhí)行其他任務(wù),如果其他任務(wù)也處于延時狀態(tài),那么CPU就將運行空閑任務(wù)。阻塞延時函數(shù)在os_time.c中定義,具體代碼實現(xiàn)參見代碼清單5-9。
代碼清單5-9 阻塞延時
1 /* 阻塞延時 */ 2 void OSTimeDly(OS_TICK dly) 3 { 4 /* 設(shè)置延時時間 */ 5 OSTCBCurPtr->TaskDelayTicks = dly;(1) 6 7 /* 進(jìn)行任務(wù)調(diào)度 */ 8 OSSched();(2) 9 }
代碼清單5-9(1):TaskDelayTicks是任務(wù)控制塊的一個成員,用于記錄任務(wù)需要延時的時間,單位為SysTick的中斷周期。比如我們設(shè)置的SysTick的中斷周期為10ms,調(diào)用OSTimeDly(2)則完成2*10ms的延時。TaskDelayTicks的定義具體參見代碼清單5-10。
代碼清單5-10 TaskDelayTicks定義
1 struct os_tcb { 2 CPU_STK *StkPtr; 3 CPU_STK_SIZE StkSize; 4 5 /* 任務(wù)延時周期個數(shù) */ 6 OS_TICK TaskDelayTicks; 7 };
代碼清單5-9(2):任務(wù)調(diào)度。這時的任務(wù)調(diào)度與第4章的不一樣,具體參見代碼清單5-11,其中加粗部分為第4章的代碼,現(xiàn)已用條件編譯屏蔽掉。
代碼清單5-11 任務(wù)調(diào)度
1 void OSSched(void) 2 { 3 #if 0/* 非常簡單的任務(wù)調(diào)度:兩個任務(wù)輪流執(zhí)行 */ 4 if ( OSTCBCurPtr == OSRdyList[0].HeadPtr ) { 5 OSTCBHighRdyPtr = OSRdyList[1].HeadPtr; 6 } else { 7 OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; 8 } 9 #endif 10 11 /* 如果當(dāng)前任務(wù)是空閑任務(wù),那么嘗試執(zhí)行任務(wù)1或者任務(wù)2, 12 *看看其延時時間是否結(jié)束,如果任務(wù)的延時時間均沒有到期, 13 *就返回繼續(xù)執(zhí)行空閑任務(wù) */ 14 if ( OSTCBCurPtr == &OSIdleTaskTCB ) {(1) 15 if (OSRdyList[0].HeadPtr->TaskDelayTicks == 0) { 16 OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; 17 } else if (OSRdyList[1].HeadPtr->TaskDelayTicks == 0) { 18 OSTCBHighRdyPtr = OSRdyList[1].HeadPtr; 19 } else { 20 /* 任務(wù)延時均沒有到期則返回,繼續(xù)執(zhí)行空閑任務(wù) */ 21 return; 22 } 23 } else {(2) 24 /*如果是task1或者task2,則檢查另外一個任務(wù), 25 *如果另外的任務(wù)不在延時中,則切換到該任務(wù) 26 *否則,判斷當(dāng)前任務(wù)是否應(yīng)該進(jìn)入延時狀態(tài), 27 *如果是,則切換到空閑任務(wù),否則就不進(jìn)行任何切換 */ 28 if (OSTCBCurPtr == OSRdyList[0].HeadPtr) { 29 if (OSRdyList[1].HeadPtr->TaskDelayTicks == 0) { 30 OSTCBHighRdyPtr = OSRdyList[1].HeadPtr; 31 } else if (OSTCBCurPtr->TaskDelayTicks != 0) { 32 OSTCBHighRdyPtr = &OSIdleTaskTCB; 33 } else { 34 /* 返回,不進(jìn)行切換,因為兩個任務(wù)都處于延時狀態(tài) */ 35 return; 36 } 37 } else if (OSTCBCurPtr == OSRdyList[1].HeadPtr) { 38 if (OSRdyList[0].HeadPtr->TaskDelayTicks == 0) { 39 OSTCBHighRdyPtr = OSRdyList[0].HeadPtr; 40 } else if (OSTCBCurPtr->TaskDelayTicks != 0) { 41 OSTCBHighRdyPtr = &OSIdleTaskTCB; 42 } else { 43 /* 返回,不進(jìn)行切換,因為兩個任務(wù)都處于延時中 */ 44 return; 45 } 46 } 47 } 48 49 /* 任務(wù)切換 */ 50 OS_TASK_SW();(3) 51 }
代碼清單5-11(1):如果當(dāng)前任務(wù)是空閑任務(wù),則嘗試執(zhí)行任務(wù)1或者任務(wù)2,看看其延時時間是否結(jié)束,如果任務(wù)的延時時間均沒有到期,就返回繼續(xù)執(zhí)行空閑任務(wù)。
代碼清單5-11(2):如果當(dāng)前任務(wù)不是空閑任務(wù),則會執(zhí)行到此,那就看看當(dāng)前任務(wù)是哪個任務(wù)。無論是哪個任務(wù),都要檢查另外一個任務(wù)是否處于延時狀態(tài),如果沒有延時,就切換到該任務(wù),如果處于延時狀態(tài),則判斷當(dāng)前任務(wù)是否應(yīng)該進(jìn)入延時狀態(tài),如果是,則切換到空閑任務(wù),否則不進(jìn)行任務(wù)切換。
代碼清單5-11(3):任務(wù)切換,實際就是觸發(fā)PendSV異常。
- 30天自制操作系統(tǒng)
- 操作系統(tǒng)實用教程(Linux版)
- Modern Web Testing with TestCafe
- SOA實踐者說
- 精解Windows 8
- Docker+Kubernetes應(yīng)用開發(fā)與快速上云
- 巧學(xué)活用Windows 7
- Android物聯(lián)網(wǎng)開發(fā)細(xì)致入門與最佳實踐
- 蘋果OS X Mavericks 10.9應(yīng)用大全
- Linux軟件管理平臺設(shè)計與實現(xiàn)
- Windows Server 2008組網(wǎng)技術(shù)與實訓(xùn)(第3版)
- Linux網(wǎng)絡(luò)操作系統(tǒng)項目教程(RHEL 7.4/CentOS 7.4)(第3版)(微課版)
- CSS揭秘
- Unity AR/VR開發(fā):實戰(zhàn)高手訓(xùn)練營
- 用“芯”探核:基于龍芯的Linux內(nèi)核探索解析