欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: uC/OS-II學(xué)習(xí)筆記—時(shí)間管理 [打印本頁(yè)]

作者: xueren    時(shí)間: 2013-7-29 11:58
標(biāo)題: uC/OS-II學(xué)習(xí)筆記—時(shí)間管理
時(shí)間管理的內(nèi)容在代碼os_time.c中,包含操作系統(tǒng)時(shí)間的設(shè)置及獲取,對(duì)任務(wù)的延時(shí),任務(wù)按分秒延時(shí),取消任務(wù)的延時(shí)共5個(gè)系統(tǒng)調(diào)用。時(shí)間管理的最主要功能就是對(duì)任務(wù)進(jìn)行延時(shí)。
時(shí)間管理中最重要的數(shù)據(jù)結(jié)構(gòu)就是全局變量OSTime,OSTime的值就是操作系統(tǒng)的時(shí)間,它的定義在uC/OS-II的頭文件ucos_ii.h中,代碼如下所示:

這里首先要知道關(guān)鍵字volatile的含義。volatile總是與優(yōu)化有關(guān),編譯器有一種技術(shù)叫做數(shù)據(jù)流分析,分析程序中的變量在哪里賦值、在哪里使用、在哪里失效,分析結(jié)果可以用于常量合并、常量傳播等優(yōu)化。而關(guān)鍵字volatile卻是禁止做這些優(yōu)化的。因?yàn)镺STime的值是易變的,加了關(guān)鍵字volatile后,不會(huì)被編譯器優(yōu)化,每次取值都會(huì)直接在內(nèi)存中對(duì)該變量的地址取值,從而保證不會(huì)因?yàn)榫幾g器優(yōu)化而產(chǎn)生錯(cuò)誤的結(jié)果。
OSTime在操作系統(tǒng)初始化時(shí)被設(shè)置為0。
時(shí)間管理中使用的另一個(gè)重要的數(shù)據(jù)結(jié)構(gòu)就是任務(wù)控制塊,任務(wù)控制塊有一項(xiàng)是OSTCBDly,標(biāo)志這個(gè)任務(wù)延時(shí)的時(shí)間。這個(gè)時(shí)間是以兩次時(shí)鐘中斷間隔的時(shí)間為單位的。另外,對(duì)任務(wù)的延時(shí)實(shí)際上阻塞了任務(wù),因此要對(duì)就緒表和就緒組等數(shù)據(jù)結(jié)構(gòu)進(jìn)行相關(guān)的操作。
時(shí)間的設(shè)置和獲取都是關(guān)于OSTime的賦值,代碼比較簡(jiǎn)單,如下所示:


時(shí)間獲取函數(shù)OSTimeGet簡(jiǎn)單地返回OSTime的值,需要注意的是,對(duì)OSTime的操作一定要使用臨界區(qū)。時(shí)間設(shè)置函數(shù)將參數(shù)ticks的值賦值給OSTime,這兩個(gè)函數(shù)并不常用。
任務(wù)延時(shí)函數(shù)OSTimeDly用于阻塞任務(wù)一定時(shí)間,這個(gè)時(shí)間以參數(shù)的形式給出。如果這個(gè)參數(shù)的值是N,那么在N個(gè)時(shí)間片(時(shí)鐘滴答)之后,任務(wù)才能回到就緒態(tài)獲得繼續(xù)運(yùn)行的機(jī)會(huì)。如果參數(shù)的值是0,就不會(huì)阻塞任務(wù)。任務(wù)延時(shí)函數(shù)OSTimeDly的代碼如下所示:

本段代碼層次清晰且比較簡(jiǎn)單。OSLockNesting是調(diào)度鎖,也就是說(shuō),如果OSLockNesting>0,那么不允許進(jìn)行任務(wù)調(diào)度。因?yàn)槿蝿?wù)延時(shí)的時(shí)候要中止當(dāng)前任務(wù)的執(zhí)行,所以要進(jìn)行調(diào)度,因此在調(diào)度鎖有效的情況下是不能執(zhí)行任務(wù)延時(shí)的。如果延時(shí)時(shí)間大于0,那么就要進(jìn)行一次任務(wù)調(diào)度,將當(dāng)前的任務(wù)的就緒標(biāo)志取消,也就是對(duì)就緒表和就緒組的相關(guān)操作。之后延時(shí)時(shí)間賦值給任務(wù)塊的OSTCBDly項(xiàng)以對(duì)延時(shí)計(jì)數(shù)。操作系統(tǒng)在每個(gè)時(shí)鐘中斷都要對(duì)每個(gè)OSTCBDly大于0的任務(wù)的OSTCBDly進(jìn)行減1操作和進(jìn)行任務(wù)調(diào)度,那么當(dāng)任務(wù)的延時(shí)時(shí)間到了的時(shí)候(OSTCBDly為0)就可以恢復(fù)到就緒態(tài)。
需要注意的是,如果將任務(wù)延時(shí)1個(gè)時(shí)間片,調(diào)用OSTimeDly(1),會(huì)不會(huì)產(chǎn)生正確的結(jié)果呢?回答是否定的。這是因?yàn)槿蝿?wù)在調(diào)用時(shí)間延時(shí)函數(shù)的時(shí)候可能已經(jīng)馬上就要發(fā)生時(shí)間中斷了,那么設(shè)置OSTCBDly的值為1,想延時(shí)10ms,然后系統(tǒng)切換到一個(gè)新的任務(wù)運(yùn)行。在可能極短的時(shí)間,如0.5ms的時(shí)候就進(jìn)入時(shí)鐘中斷服務(wù)程序,立刻將OSTCBDly的值減到0了。調(diào)度器在調(diào)度的時(shí)候就會(huì)恢復(fù)這個(gè)才延時(shí)了0.5ms的任務(wù)。可見(jiàn),OSTimeDly的誤差最大應(yīng)該是1個(gè)時(shí)間片的長(zhǎng)度,OSTCBDly(1)不會(huì)剛好延時(shí)10ms,如果真的需要延時(shí)一個(gè)時(shí)間片,最好調(diào)用OSTCBDly(2)。
任務(wù)延時(shí)函數(shù)OSTimeDly用于將任務(wù)阻塞一段時(shí)間,這個(gè)時(shí)間是以時(shí)間片為單位的。如果想以時(shí)、分、秒、毫秒為單位進(jìn)行任務(wù)延時(shí),需要調(diào)用以分秒作為單位的任務(wù)延時(shí)函數(shù)OSTimeDlyHMSM。
OSTimeDlyHMSM從功能上來(lái)說(shuō)和OSTimeDly并沒(méi)有多大的差別,只是將時(shí)間單位進(jìn)行了轉(zhuǎn)換,也就是說(shuō),轉(zhuǎn)換了以小時(shí)、分、秒、毫秒為單位的時(shí)間和以時(shí)間片為單位的時(shí)間。OSTimeDlyHMSM的參數(shù)分別是小時(shí)數(shù)(hours)、分鐘數(shù)(minutes)、秒數(shù)(seconds)和毫秒數(shù)(ms)。OSTimeDlyHMSM的代碼如下所示:


由代碼可知,OSTimeDlyHMSM在進(jìn)行了參數(shù)檢查之后,將以小時(shí)、分、秒、毫秒為單位時(shí)間轉(zhuǎn)換為時(shí)間片ticks,最終調(diào)用OSTimedly來(lái)解決問(wèn)題。
任務(wù)在延時(shí)之后,進(jìn)入阻塞態(tài)。當(dāng)延時(shí)時(shí)間到了就從阻塞態(tài)恢復(fù)到就緒態(tài),可以被操作系統(tǒng)調(diào)度執(zhí)行。但是,并非回到就緒態(tài)就只有這么一種可能,因?yàn)榧幢闳蝿?wù)的延時(shí)時(shí)間沒(méi)到,還是可以通過(guò)函數(shù)OSTimeDlyResume恢復(fù)該任務(wù)到就緒態(tài)的。
另外,OSTimeDlyResume也不僅僅能恢復(fù)使用OSTimeDly或OSTimeDlyHMSM而延時(shí)的任務(wù)。對(duì)于因等待事件發(fā)生而阻塞的,并且設(shè)置了超時(shí)(timeout)時(shí)間的任務(wù),也可以使用OSTimeDlyResume來(lái)恢復(fù)。對(duì)這些任務(wù)使用了OSTimeDlyResume,就好像已經(jīng)等待超時(shí)了一樣。
但是,對(duì)于,采用OSTaskSuspend掛起的任務(wù),是不允許采用OSTimeDlyResume來(lái)恢復(fù)的。


OSTimeDlyResume由于要處理任務(wù)錯(cuò)綜復(fù)雜的關(guān)系,因此代碼稍顯復(fù)雜。代碼中一個(gè)非常重要的數(shù)據(jù)結(jié)構(gòu)就是任務(wù)塊的OSTCBStat,如下所示:

相關(guān)的宏定義如下所示:

因此,如果一個(gè)任務(wù)只是設(shè)置了延時(shí),那么該任務(wù)塊的OSTCBStat的值應(yīng)該是0,也就是OS_STAT_RDY。被設(shè)置了延時(shí)的任務(wù)和就緒任務(wù)的區(qū)別在于,就緒任務(wù)的控制塊的OSTCBDly的值一定是0,而設(shè)置了延時(shí)的任務(wù)的OSTCBDly的值一定不是0.
如果一個(gè)任務(wù)在等待一個(gè)或多個(gè)事件的發(fā)生,那么該任務(wù)的控制塊的0、1、2、4、5位必然有1位或多位不為0。也就是ptcb->OSTCBStat&OS_STAT_PEND_ANY的值不為0,這是在判斷任務(wù)是不是在等待事件的發(fā)生。等待事件發(fā)生的任務(wù)可能設(shè)置了超時(shí),也可能沒(méi)有設(shè)置超時(shí),如果沒(méi)有設(shè)置超時(shí)那么就會(huì)在下面所示的代碼返回:

所以不會(huì)被恢復(fù)到就緒態(tài)。設(shè)置了超時(shí)的OSTCBDly的值大于0,先將OSTCBDly的值置位為0,然后使用ptcb->OSTCBStat&=~OS_STAT_PEND_ANY,所以的5種事件等待標(biāo)志全部強(qiáng)制清0,不再等待了。
另外,還需要判斷OSTCBStat的位3掛起標(biāo)志。因?yàn)楸粧炱鸬娜蝿?wù)必須用也只能用OSTaskResume來(lái)恢復(fù)。OS_STAT_SUSPEND的值是0x08,ptcb->OSTCBStat&OS_STAT_SUSPEND是將STCBStat的位3掛起標(biāo)志位單獨(dú)取出來(lái)了,判斷它是不是0,如果是0,那么就不是被掛起的任務(wù),否則就是被掛起的任務(wù)。對(duì)于掛起的任務(wù)只能處理到這里,對(duì)于其他的任務(wù)就開(kāi)始對(duì)就緒表和就緒組進(jìn)行處理,恢復(fù)任務(wù)到就緒態(tài),然后執(zhí)行任務(wù)調(diào)度。





歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1