




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第5章時間管理15.0任務延時函數,OSTimeDly()15.1按時分秒延時函數 OSTimeDlyHMSM()35.2讓處在延時期的任務結束延時,OSTimeDlyResume()45.3系統(tǒng)時間,OSTimeGet()和OSTimeSet()6第5章 時間管理在3.10節(jié)時鐘節(jié)拍中曾提到,C/OS-(其它內核也一樣)要求用戶提供定時中斷來實現(xiàn)延時與超時控制等功能。這個定時中斷叫做時鐘節(jié)拍,它應該每秒發(fā)生10至100次。時鐘節(jié)拍的實際頻率是由用戶的應用程序決定的。時鐘節(jié)拍的頻率越高,系統(tǒng)的負荷就越重。3.10節(jié)討論了時鐘的中斷服務子程序和節(jié)時鐘節(jié)函數OSTimeTick該函數用于通知C/O
2、S-發(fā)生了時鐘節(jié)拍中斷。本章主要講述五個與時鐘節(jié)拍有關的系統(tǒng)服務:l OSTimeDly()l OSTimeDlyHMSM()l OSTimeDlyResume()l OSTimeGet()l OSTimeSet()本章所提到的函數可以在OS_TIME.C文件中找到。5.0 任務延時函數,OSTimeDly()C/OS-提供了這樣一個系統(tǒng)服務:申請該服務的任務可以延時一段時間,這段時間的長短是用時鐘節(jié)拍的數目來確定的。實現(xiàn)這個系統(tǒng)服務的函數叫做OSTimeDly()。調用該函數會使C/OS-進行一次任務調度,并且執(zhí)行下一個優(yōu)先級最高的就緒態(tài)任務。任務調用OSTimeDly()后,一旦規(guī)定的時間
3、期滿或者有其它的任務通過調用OSTimeDlyResume()取消了延時,它就會馬上進入就緒狀態(tài)。注意,只有當該任務在所有就緒任務中具有最高的優(yōu)先級時,它才會立即運行。程序清單 L5.1所示的是任務延時函數OSTimeDly()的代碼。用戶的應用程序是通過提供延時的時鐘節(jié)拍數一個1 到65535之間的數,來調用該函數的。如果用戶指定0值L5.1(1),則表明用戶不想延時任務,函數會立即返回到調用者。非0值會使得任務延時函數OSTimeDly()將當前任務從就緒表中移除L5.1(2)。接著,這個延時節(jié)拍數會被保存在當前任務的OS_TCB中L5.1(3),并且通過OSTimeTick()每隔一個時
4、鐘節(jié)拍就減少一個延時節(jié)拍數。最后,既然任務已經不再處于就緒狀態(tài),任務調度程序會執(zhí)行下一個優(yōu)先級最高的就緒任務。程序清單 L 5.1OSTimeDly().void OSTimeDly (INT16U ticks) if (ticks 0) (1) OS_ENTER_CRITICAL(); if (OSRdyTblOSTCBCur-OSTCBY &= OSTCBCur-OSTCBBitX) = 0) (2) OSRdyGrp &= OSTCBCur-OSTCBBitY; OSTCBCur-OSTCBDly = ticks; (3) OS_EXIT_CRITICAL(); OSSched(); (
5、4) 清楚地認識0到一個節(jié)拍之間的延時過程是非常重要的。換句話說,如果用戶只想延時一個時鐘節(jié)拍,而實際上是在0到一個節(jié)拍之間結束延時。即使用戶的處理器的負荷不是很重,這種情況依然是存在的。圖F5.1詳細說明了整個過程。系統(tǒng)每隔10ms發(fā)生一次時鐘節(jié)拍中斷F5.1(1)。假如用戶沒有執(zhí)行其它的中斷并且此時的中斷是開著的,時鐘節(jié)拍中斷服務就會發(fā)生F5.1(2)。也許用戶有好幾個高優(yōu)先級的任務(HPT)在等待延時期滿,它們會接著執(zhí)行F5.1(3)。接下來,圖5.1中所示的低優(yōu)先級任務(LPT)會得到執(zhí)行的機會,該任務在執(zhí)行完后馬上調用F5.1(4)所示的OSTimeDly(1)。C/OS-會使該任務
6、處于休眠狀態(tài)直至下一個節(jié)拍的到來。當下一個節(jié)拍到來后,時鐘節(jié)拍中斷服務子程序會執(zhí)行F5.1(5),但是這一次由于沒有高優(yōu)先級的任務被執(zhí)行,C/OS-會立即執(zhí)行申請延時一個時鐘節(jié)拍的任務F5.1(6)。正如用戶所看到的,該任務實際的延時少于一個節(jié)拍!在負荷很重的系統(tǒng)中,任務甚至有可能會在時鐘中斷即將發(fā)生時調用OSTimeDly(1),在這種情況下,任務幾乎就沒有得到任何延時,因為任務馬上又被重新調度了。如果用戶的應用程序至少得延時一個節(jié)拍,必須要調用OSTimeDly(2),指定延時兩個節(jié)拍!Figure 5.1Delay resolution.5.1 按時分秒延時函數 OSTimeDlyHMS
7、M()OSTimeDly()雖然是一個非常有用的函數,但用戶的應用程序需要知道延時時間對應的時鐘節(jié)拍的數目。用戶可以使用定義全局常數OS_TICKS_PER_SEC(參看OS_CFG.H)的方法將時間轉換成時鐘段,但這種方法有時顯得比較愚笨。筆者增加了OSTimeDlyHMSM()函數后,用戶就可以按小時(H)、分(M)、秒(S)和毫秒(m)來定義時間了,這樣會顯得更自然些。與OSTimeDly()一樣,調用OSTimeDlyHMSM()函數也會使C/OS-進行一次任務調度,并且執(zhí)行下一個優(yōu)先級最高的就緒態(tài)任務。任務調用OSTimeDlyHMSM()后,一旦規(guī)定的時間期滿或者有其它的任務通過調
8、用OSTimeDlyResume()取消了延時(參看5.02,恢復延時的任務OSTimeDlyResume(),它就會馬上處于就緒態(tài)。同樣,只有當該任務在所有就緒態(tài)任務中具有最高的優(yōu)先級時,它才會立即運行。程序清單 L5.2所示的是OSTimeDlyHMSM()的代碼。從中可以看出,應用程序是通過用小時、分、秒和毫秒指定延時來調用該函數的。在實際應用中,用戶應避免使任務延時過長的時間,因為從任務中獲得一些反饋行為(如減少計數器,清除LED等等)經常是很不錯的事。但是,如果用戶確實需要延時長時間的話,C/OS-可以將任務延時長達256個小時(接近11天)。OSTimeDlyHMSM()一開始先要
9、檢驗用戶是否為參數定義了有效的值L5.2(1)。與OSTimeDly()一樣,即使用戶沒有定義延時,OSTimeDlyHMSM()也是存在的L5.2(9)。因為C/OS-只知道節(jié)拍,所以節(jié)拍總數是從指定的時間中計算出來的L5.2(3)。很明顯,程序清單 L5.2中的程序并不是十分有效的。筆者只是用這種方法告訴大家一個公式,這樣用戶就可以知道怎樣計算總的節(jié)拍數了。真正有意義的只是OS_TICKS_PER_SEC。L5.2(3)決定了最接近需要延遲的時間的時鐘節(jié)拍總數。500/OS_TICKS_PER_SECOND的值基本上與0.5個節(jié)拍對應的毫秒數相同。例如,若將時鐘頻率(OS_TICKS_PE
10、R_SEC)設置成100Hz(10ms),4ms的延時不會產生任何延時!而5ms的延時就等于延時10ms。C/OS-支持的延時最長為65,535個節(jié)拍。要想支持更長時間的延時,如L5.2(2)所示,OSTimeDlyHMSM()確定了用戶想延時多少次超過65,535個節(jié)拍的數目L5.2(4)和剩下的節(jié)拍數L5.2(5)。例如,若OS_TICKS_PER_SEC的值為100,用戶想延時15分鐘,則OSTimeDlyHMSM()會延時15x60x100=90,000個時鐘。這個延時會被分割成兩次32,768個節(jié)拍的延時(因為用戶只能延時65,535個節(jié)拍而不是65536個節(jié)拍)和一次24,464個
11、節(jié)拍的延時。在這種情況下,OSTimeDlyHMSM()首先考慮剩下的節(jié)拍,然后是超過65,535的節(jié)拍數L5.2(7)和(8)(即兩個32,768個節(jié)拍延時)。程序清單 L 5.2OSTimeDlyHMSM().INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U milli) INT32U ticks; INT16U loops; if (hours 0 | minutes 0 | seconds 0 | milli 0) (1) if (minutes 59) return (OS_TIME_INVA
12、LID_MINUTES); if (seconds 59) return (OS_TIME_INVALID_SECONDS); If (milli 999) return (OS_TIME_INVALID_MILLI); ticks = (INT32U)hours * 3600L * OS_TICKS_PER_SEC (2) + (INT32U)minutes * 60L * OS_TICKS_PER_SEC + (INT32U)seconds * OS_TICKS_PER_SEC + OS_TICKS_PER_SEC * (INT32U)milli + 500L/OS_TICKS_PER_S
13、EC) / 1000L;(3) loops = ticks / 65536L; (4) ticks = ticks % 65536L; (5) OSTimeDly(ticks); (6) while (loops 0) (7) OSTimeDly(32768); (8) OSTimeDly(32768); loops-; return (OS_NO_ERR); else return (OS_TIME_ZERO_DLY); (9) 由于OSTimeDlyHMSM()的具體實現(xiàn)方法,用戶不能結束延時調用OSTimeDlyHMSM()要求延時超過65535個節(jié)拍的任務。換句話說,如果時鐘節(jié)拍的頻率
14、是100Hz,用戶不能讓調用OSTimeDlyHMSM(0,10,55,350)或更長延遲時間的任務結束延時。5.2 讓處在延時期的任務結束延時,OSTimeDlyResume()C/OS-允許用戶結束延時正處于延時期的任務。延時的任務可以不等待延時期滿,而是通過其它任務取消延時來使自己處于就緒態(tài)。這可以通過調用OSTimeDlyResume()和指定要恢復的任務的優(yōu)先級來完成。實際上,OSTimeDlyResume()也可以喚醒正在等待事件(參看第六章任務間的通訊和同步)的任務,雖然這一點并沒有提到過。在這種情況下,等待事件發(fā)生的任務會考慮是否終止等待事件。OSTimeDlyResume()
15、的代碼如程序清單 L5.3所示,它首先要確保指定的任務優(yōu)先級有效 L5.3(1)。接著,OSTimeDlyResume()要確認要結束延時的任務是確實存在的L5.3(2)。如果任務存在,OSTimeDlyResume()會檢驗任務是否在等待延時期滿L5.3(3)。只要OS_TCB域中的OSTCBDly包含非0值就表明任務正在等待延時期滿,因為任務調用了OSTimeDly(),OSTimeDlyHMSM()或其它在第六章中所描述的PEND函數。然后延時就可以通過強制命令OSTCBDly為0來取消L5.3(4)。延時的任務有可能已被掛起了,這樣的話,任務只有在沒有被掛起的情況下才能處于就緒狀態(tài)L5
16、.3(5)。當上面的條件都滿足后,任務就會被放在就緒表中L5.3(6)。這時,OSTimeDlyResume()會調用任務調度程序來看被恢復的任務是否擁有比當前任務更高的優(yōu)先級L5.3(7)。這會導致任務的切換。程序清單 L 5.3恢復正在延時的任務INT8U OSTimeDlyResume (INT8U prio) OS_TCB *ptcb; if (prio = OS_LOWEST_PRIO) (1) return (OS_PRIO_INVALID); OS_ENTER_CRITICAL(); ptcb = (OS_TCB *)OSTCBPrioTblprio; if (ptcb != (
17、OS_TCB *)0) (2) if (ptcb-OSTCBDly != 0) (3) ptcb-OSTCBDly = 0; (4) if (!(ptcb-OSTCBStat & OS_STAT_SUSPEND) (5) OSRdyGrp |= ptcb-OSTCBBitY; (6) OSRdyTblptcb-OSTCBY |= ptcb-OSTCBBitX; OS_EXIT_CRITICAL(); OSSched(); (7) else OS_EXIT_CRITICAL(); return (OS_NO_ERR); else OS_EXIT_CRITICAL(); return (OS_TI
18、ME_NOT_DLY); else OS_EXIT_CRITICAL(); return (OS_TASK_NOT_EXIST); 注意,用戶的任務有可能是通過暫時等待信號量、郵箱或消息隊列來延時自己的(參看第六章)??梢院唵蔚赝ㄟ^控制信號量、郵箱或消息隊列來恢復這樣的任務。這種情況存在的唯一問題是它要求用戶分配事件控制塊(參看6.00),因此用戶的應用程序會多占用一些RAM。5.3 系統(tǒng)時間,OSTimeGet()和OSTimeSet()無論時鐘節(jié)拍何時發(fā)生,C/OS-都會將一個32位的計數器加1。這個計數器在用戶調用OSStart()初始化多任務和4,294,967,295個節(jié)拍執(zhí)行完一遍的時候從0開始計數。在時鐘節(jié)拍的頻率等于100Hz的時候,這個32位的計數器每隔497天就重新開始計數。用戶可以通過調用OSTimeGet()來獲得該計數器的當前值。也可以通過調用OSTimeSet()來改變該計數器的值。OSTimeGet()和OSTimeSet()兩個函數的代碼如程序清單 L5.4所示。注意,在訪問O
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 神經內科設備培訓
- 校園宿舍閑置空地的利用設計
- 車輛借用與租賃車輛保險理賠責任合同范本
- 商業(yè)地產項目場地承包經營合作協(xié)議書
- 餐飲企業(yè)員工勞動合同范本及培訓考核合同
- 特色主題餐廳經營合作協(xié)議
- 黨建聯(lián)學共建項目合作協(xié)議書
- 車輛抵押擔保汽車維修擔保服務合同
- 汽車抵押典當貸款業(yè)務合作協(xié)議
- 車棚租賃與停車誘導系統(tǒng)合作協(xié)議
- 醫(yī)院醫(yī)用耗材SPD服務項目投標方案
- 廈門大學海洋科學導論課件(水文部分)l
- 食品廠衛(wèi)生安全員工培訓
- 質保協(xié)議合同范例
- 手術室神經外科護理進修
- 【MOOC】中西文化鑒賞-鄭州大學 中國大學慕課MOOC答案
- 鼻息肉摘除術手術配合
- 《血管活性藥物靜脈輸注護理》團體標準解讀
- 北師大版七年級上冊數學期末考試試題帶答案
- 高原隧道施工通風方案
- 腹腔鏡下膽囊切除術
評論
0/150
提交評論