第4章中斷處理與時間管理_第1頁
第4章中斷處理與時間管理_第2頁
第4章中斷處理與時間管理_第3頁
第4章中斷處理與時間管理_第4頁
第4章中斷處理與時間管理_第5頁
已閱讀5頁,還剩39頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

第4章 中斷處理與時間管理本章描述μC/OS-II的中斷處理與時間管理,包括:與中斷相關的概念μC/OS-II中斷處理的方法中斷級的任務切換時鐘節(jié)拍器的原理與正確應用方法以及5個時間管理函數(shù)。本章主要內(nèi)容4.1與中斷相關的概念4.1.1中斷一、中斷的定義中斷定義為CPU對系統(tǒng)內(nèi)、外發(fā)生的異步事件的響應。異步事件是指沒有一定時序關系的、隨機發(fā)生的事件。當中斷產(chǎn)生時,由硬件向CPU發(fā)送一個異步事件請求,CPU接收到請求后,中止當前工作,保存當前運行環(huán)境,轉(zhuǎn)去處理相應的異步事件任務,這個過程稱為中斷。事件處理完畢后,程序回到:在前后臺系統(tǒng)中,程序回到后臺程序;在不可剝奪型內(nèi)核中,程序回到被中斷了的任務;在可剝奪型內(nèi)核中,讓進入就緒態(tài)的優(yōu)先級最高的任務開始運行,若沒有高優(yōu)先級任務準備就緒,則回到被中斷了的任務。

二、中斷機制的優(yōu)點使用中斷機制的優(yōu)點在于:CPU無需連續(xù)不斷地查詢是否有新的事件發(fā)生,只需在有事件發(fā)生時才作出響應。三、中斷機制的缺點關中斷會影響中斷延遲時間,時間太長可能會引起中斷丟失。所以在實時環(huán)境中,關中斷的時間應盡量短。四、開關中斷的方法CPU可以通過兩條特殊指令:關中斷(DisableInterrupt)和開中斷(EnableInterrupt)來響應和不響應中斷。五、中斷嵌套在中斷服務期間,CPU一般允許中斷嵌套,如圖4.1所示,允許新的中斷打入,識別中斷優(yōu)先級別更高的事件。圖4.1中斷嵌套

任務

ISR1

ISR3

ISR3

中斷2打入

中斷3打入

中斷1打入

4.1.2中斷延遲

一、中斷延遲的定義

中斷延遲定義為:從硬件中斷發(fā)生到開始執(zhí)行中斷處理程序第一條指令所用的時間。也就是說,中斷延遲是從中斷發(fā)生到中斷跳轉(zhuǎn)指令執(zhí)行完畢之間的這段時間。

由于實時操作系統(tǒng)考慮得更多的是最壞的情況,而不是平均的情況,因此指令執(zhí)行的時間必須按照最長的指令執(zhí)行時間來計算。所以中斷延遲時間,通常是由關中斷的最長時間來決定的。關中斷的時間越長,中斷延遲就越長。中斷延遲是實時內(nèi)核最重要的指標。二、中斷延遲所需時間1、在前后臺系統(tǒng)中中斷延遲=MAX(最長指令,關中斷的最長)時間+中斷向量跳轉(zhuǎn)時間2、在不可剝奪型和不可剝奪內(nèi)核中中斷延遲=MAX(最長指令,用戶關中斷,內(nèi)核關中斷)時間+中斷向量跳轉(zhuǎn)時間

4.1.3中斷響應

中斷響應定義為從中斷發(fā)生起到開始執(zhí)行中斷用戶處理程序的第一條指令所用的時間,換句話說,中斷響應是從中斷發(fā)生到剛剛開始處理異步事件之間的這段時間,它包括開始處理這個中斷前的全部開銷。一般地,執(zhí)行用戶代碼之前要保護現(xiàn)場,將CPU的各個寄存器推入堆棧。這段時間將被稱為中斷響應時間。

一、中斷響應的定義二、中斷響應所需時間

在可剝奪型內(nèi)核中,則要先調(diào)用一個特定的函數(shù),通知內(nèi)核即將進行中斷服務,使得內(nèi)核可以跟蹤中斷的嵌套。對于μC/OS-Ⅱ說來,這個函數(shù)是OSIntEnter(),可剝奪型內(nèi)核的中斷響應時間由下式給出:

在前后臺系統(tǒng)和不可剝奪型內(nèi)核中,保存寄存器以后立即執(zhí)行用戶代碼,中斷響應時間由下式給出:中斷響應考慮的是系統(tǒng)在最壞情況下的響應中斷時間,而不是平均時間。例如某系統(tǒng)100次中有99次在100μs之內(nèi)響應中斷,只有一次響應中斷的時間是250μs,只能認為中斷響應時間是250μs。4.1.4中斷恢復時間

一、中斷恢復時間的定義

中斷恢復時間定義為:CPU返回到被中斷了的程序代碼所需要的時間。二、中斷恢復所需時間在前后臺系統(tǒng)和不可剝奪型內(nèi)核中,中斷恢復時間只包括恢復CPU內(nèi)部寄存器值的時間和執(zhí)行中斷返回指令的時間。中斷恢復時間由下式給出:對于可剝奪型內(nèi)核,中斷的恢復要復雜一些。一般地,可剝奪型內(nèi)核在中斷服務子程序的末尾,都要調(diào)用一個由實時內(nèi)核提供的中斷脫離函數(shù)。在μC/OS-Ⅱ中,這個函數(shù)叫做OSIntExit(),它首先判斷是否脫離了所有的中斷嵌套,然后再判斷是否有更高優(yōu)先級的任務準備就緒。若還處于中斷嵌套中,那么程序返回到前一級中斷服務子程序繼續(xù)執(zhí)行;若已經(jīng)脫離了所有的中斷嵌套,則檢查當前是否有優(yōu)先級更高的任務準備就緒,若有則返回到這個優(yōu)先級更高的任務,被中斷了的任務只有重新成為優(yōu)先級最高的就緒態(tài)任務時才能恢復運行;如果沒有更高優(yōu)先級任務準備就緒,則返回到被中斷的任務繼續(xù)執(zhí)行。在這種情況下,可剝奪型內(nèi)核的中斷恢復時間由下式給出:4.1.5中斷延遲、響應和恢復比較

4.1.6非屏蔽中斷

在非屏蔽中斷服務子程序中,不能在非屏蔽中斷處理內(nèi)處理臨界區(qū)代碼、不能使用內(nèi)核提供的服務。在非屏蔽中斷處理程序中參數(shù)的傳遞必須用全程變量,且全程變量的字節(jié)長度必須能夠一次讀完。若一定要在非屏蔽中斷產(chǎn)生時使用內(nèi)核服務,則可以通過用非屏蔽中斷產(chǎn)生普通可屏蔽中斷的方法來實現(xiàn)。一、非屏蔽中斷的定義非屏蔽中斷(NMI)是指不能用系統(tǒng)指令來關閉的中斷。非屏蔽中斷的特點是:中斷優(yōu)先級高、延遲時間短、響應快、不能被嵌套,不能忍受內(nèi)核的延遲,一般常應用于緊急事件處理,如掉電保護等。二、非屏蔽中斷的特點三、非屏蔽中斷的應用規(guī)則4.2μC/OS-Ⅱ的中斷處理

4.2.1中斷處理程序圖4.4標準中斷處理程序流程圖

二、中斷進入函數(shù)的實現(xiàn)代碼在μC/OS-Ⅱ中,中斷處理程序可用匯編語言編寫,也可以用C語言編寫。一、標準的μC/OS-Ⅱ中斷服務子程序一個標準的μC/OS-Ⅱ中斷服務子程序應該按圖4.4所示流程圖進行編寫。程序清單4.1OSIntEnter()voidOSIntEnter(void)reentrant{if(OSRunning==TRUE){//多任務啟動后,方可通知 //內(nèi)核。否則,直接退出。

if(OSIntNesting<255)OSIntNesting++;//中斷嵌套 //計數(shù)器加1。}}圖4.5,OSIntExit()函數(shù)程序流程

OSIntExit()函數(shù)主要完成4個工作:給中斷嵌套層數(shù)計數(shù)器減1;找出準備就緒的最高優(yōu)先級任務;檢查準備就緒的最高優(yōu)先級任務是否為被當前服務所中斷的任務,若是則返回到被中斷的任務;若不是,則進行任務控制塊指針切換,將即將運行的任務的任務控制塊的指針指向當前準備就緒的優(yōu)先級最高的任務的任務控制塊;調(diào)用中斷級任務切換函數(shù)OSIntCtxSw(),進行任務切換。

三、中斷退出函數(shù)程序清單4.2OSIntExit()voidOSIntExit(void)reentrant{#ifOS_CRITICAL_METHOD==3 OS_CPU_SRcpu_sr;#endif OS_ENTER_CRITICAL(); if(OSRunning==TRUE){ if(OSIntNesting>0)OSIntNesting--; (1) if((OSIntNesting|OSLockNesting)==0){ (2) OSIntExitY=OSUnMapTbl[OSRdyGrp];

OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+ OSUnMapTbl[OSRdyTbl[OSIntExitY]]);

if(OSPrioHighRdy!=OSPrioCur){ OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];(3) OSCtxSwCtr++; //任務切換計數(shù)器加1 OSIntCtxSw(); (4) }}} OS_EXIT_CRITICAL();}OSIntExit()看起來很像任務調(diào)度函數(shù)OS_Sched(),不同之處有三點:OSIntExit()使中斷嵌套層數(shù)減1,切換任務的條件是中斷嵌套層數(shù)計數(shù)器(OSIntNesting)和調(diào)度鎖定嵌套計數(shù)器(OSLockNesting)二者必須同時為零;OS_Sched()切換任務的條件僅僅是OSLockNesting為零。OSIntExit()中OSRdyTbl[]所需的檢索值Y是保存在全局變量OSIntExitY中的,這樣做是為了避免在任務棧中安排局部變量;OS_Sched()中OSRdyTbl[]所需的檢索值Y是個局部變量。如果需要做任務切換,OSIntExit()將調(diào)用中斷級任務切換函數(shù)OSIntCtxSw(),而OS_Sched()調(diào)用任務級任務切換函數(shù)OS_TASK_SW()。三、中斷退出函數(shù)與調(diào)度函數(shù)比較4.2.2中斷處理過程

圖4.6μC/OS-II的中斷處理過程示意圖4.3μC/OS-Ⅱ的時鐘節(jié)拍

時鐘節(jié)拍是特定的周期性中斷(時鐘中斷),可以看作是系統(tǒng)心臟的脈動。時鐘節(jié)拍是內(nèi)核的最小計時單位,它完成兩個功能:累計時間,μC/OS-Ⅱ定義了32位無符號整數(shù)OSTime來記錄系統(tǒng)啟動后時鐘節(jié)拍滴答的數(shù)目;通過時鐘中斷來確定時間間隔,實現(xiàn)任務的延時及確定任務超時。4.3.1時鐘節(jié)拍一、時鐘節(jié)拍的概念二、時鐘節(jié)拍頻率及其產(chǎn)生方法μC/OS-II中的時鐘節(jié)拍服務是通過在中斷服務子程序OSTickISR()中調(diào)用時鐘節(jié)拍子程序OSTimeTick()實現(xiàn)的;時鐘節(jié)拍頻率取決于不同的應用,一般以10~100Hz為宜。時鐘節(jié)拍頻率越快,系統(tǒng)的額外開銷就越大,實際頻率取決于用戶程序的精度;時鐘節(jié)拍計時的單位是1個時鐘節(jié)拍,由于時鐘節(jié)拍計時存在抖動問題,所以計時的精度可能并不是一個時鐘節(jié)拍,只是在每個時鐘節(jié)拍中斷到來的時候作一次裁決而已。那么抖動對計時精度是如何影響的呢?下面將分三種情況討論說明。例:假設時鐘節(jié)拍每20ms發(fā)生一次,要求將任務A延時一個時鐘節(jié)拍即20ms。那么,抖動會對延時精度造成什么影響呢?解:如圖4.7、4.8、4.9所示,分三種情況討論。圖中陰影部分表示各個任務的運行時間,由于程序中可能存在循環(huán)和條件語句,所以同一任務在不同時期的運行時間的長短可能不同,時鐘節(jié)拍中斷服務子程序的運行時間也不同。為了更方便地說明問題,圖中的延時畫得有所夸大。三、時鐘節(jié)拍抖動的影響圖4.7將任務延遲一個時鐘節(jié)拍(第一種情況)第一種情況,如圖4.7所示,所有中斷和高優(yōu)先級的任務都超前于要求延時一個時鐘節(jié)拍的任務A運行圖4.8將任務延遲一個時鐘節(jié)拍(第二種情況)

第二種情況,如圖4.8所示,所有高優(yōu)先級的任務和中斷服務的執(zhí)行時間都小于1個時鐘節(jié)拍。

圖4.9將任務延遲一個時鐘節(jié)拍(第三種情況)

第三種情況,如圖4.9所示,中斷和所有高優(yōu)先級的運行時間的總和大于1個時鐘節(jié)拍。清楚地認識0到一個節(jié)拍之間的延時過程是非常重要的,如果用戶只想延時一個時鐘節(jié)拍,而實際上得到的往往不是一個時鐘節(jié)拍。即使用戶的處理器的負荷不是很重,這種情況依然是存在的。為了保證足夠的精度,延時設計時最好多加一個時鐘節(jié)拍,例如要將任務延時5個時鐘節(jié)拍,則應該在程序中延時6個。

四、說明 延時的抖動在所有的實時操作系統(tǒng)中都會存在,根本原因可能在于:CPU負荷太重;系統(tǒng)設計可能不正確。五、抖動的原因六、解決的方法一般解決此類問題的方法主要有:提高時鐘節(jié)拍的頻率;提高CPU微處理器的時鐘頻率;重新安排任務的優(yōu)先級;避免使用浮點運算(如果非使用不可,盡量用單精度數(shù));使用能較好地優(yōu)化程序代碼的編譯器;時間要求苛刻的代碼用匯編語言寫;選擇處理速率更快的CPU。4.3.2時鐘節(jié)拍程序

μC/OS-Ⅱ中的時鐘節(jié)拍服務是通過在時鐘節(jié)拍中斷服務子程序OSTickISR()中調(diào)用節(jié)拍服務子程序OSTimeTick()實現(xiàn)的。在OSTimeTick()中還會調(diào)用OSTimeTickHook()函數(shù),即時鐘節(jié)拍用戶擴展函數(shù),該函數(shù)保留為用戶自己編寫,可以擴展應用。

一、時鐘節(jié)拍服務的實現(xiàn)方法4.3.2.1時鐘節(jié)拍中斷服務子程序

每個時鐘中斷一次,由它調(diào)用節(jié)拍服務函數(shù)OSTimeTick();時鐘節(jié)拍中斷服從μC/OS-Ⅱ所描述的全部規(guī)則;這段代碼必須用匯編語言編寫,因為在C語言里不能直接處理CPU的寄存器。voidOSTickISR(void){

關中斷; 保存處理器寄存器的值; //處理臨界段代碼 調(diào)用OSIntEnter()或是將OSIntNesting加1;//通知內(nèi)核進入中斷 開中斷

調(diào)用OSTimeTick(); //調(diào)節(jié)拍服務程序 調(diào)用OSIntExit(); //通知內(nèi)核退出中斷 關中斷; 恢復處理器寄存器的值; //處理臨界段代碼 開中斷; 執(zhí)行中斷返回指令;}一、時鐘節(jié)拍中斷服務子程序示意性代碼二、時鐘節(jié)拍中斷服務子程序的特點4.3.2.2節(jié)拍服務子程序

節(jié)拍服務子程序OSTimeTick()的主要工作二、節(jié)拍服務子程序代碼給每個用戶任務控制塊OS_TCB中的時間延時項OSTCBDly減1,直到等于零。執(zhí)行時間直接與任務個數(shù)成正比。4.3.3時鐘節(jié)拍器的正確用法

應該在多任務系統(tǒng)啟動以后再開啟時鐘節(jié)拍器,也即調(diào)用OSStart()后的第一件事就是開放時鐘節(jié)拍中斷,這段代碼可以由用戶嵌入到OSStart()函數(shù)內(nèi)。反之,若在OSInit()與OSStart()之間開放時鐘節(jié)拍器中斷,時鐘節(jié)拍中斷就有可能在μC/OS-Ⅱ啟動第一個任務之前發(fā)生,此時μC/OS-Ⅱ處在一種不確定的狀態(tài)之中。因此,用戶應用程序有可能會崩潰。一、時鐘節(jié)拍器的正確用法下面是一個錯誤用法的示意性程序清單,它在多任務調(diào)度前就開放了時鐘中斷。二、錯誤用法示例4.4μC/OS-Ⅱ的時間管理

μC/OS-Ⅱ有5個與時鐘節(jié)拍有關的系統(tǒng)服務,它們分別是:OSTimeDly(),任務延時函數(shù);OSTimeDlyHMSM(),按時分秒毫秒延時函數(shù);OSTimeDlyResume(),讓處在延時期的任務結(jié)束延時;OSTimeGet(),獲得系統(tǒng)時間;OSTimeSet(),設置系統(tǒng)時間。這些函數(shù)屬于OS_TIME.C文件。要調(diào)用這些函數(shù),必須首先在OS_CFG.H文件中設置配置常量。

一、與時鐘節(jié)拍有關的系統(tǒng)服務二、配置常量表4.1OS_CFG.H中與時間管理相關的配置常量一覽表時間管理函數(shù)在OS_CFG.H中,置1允許相應函數(shù)OSTimeDly()

OSTimeDlyHMSM()OS_TIME_DLY_HMSM_ENOSTimeDlyResume()OS_TIME_DLY_RESUME_ENOSTimeGet()OS_TIME_GET_SET_ENOSTimeSet()OS_TIME_GET_SET_EN4.4.1任務延時函數(shù),OSTimeDly()

C/OS-Ⅱ的任務是一個無限循環(huán),由于μC/OS-Ⅱ是可剝奪型內(nèi)核,如果高優(yōu)先級任務不主動掛起,低優(yōu)先級任務就永遠無法取得運行權(quán),最高優(yōu)先級任務將獨占CPU的使用權(quán)。因此,μC/OS-Ⅱ規(guī)定:除了永不掛起的空閑任務外,其它所有的任務都要在合適的時候調(diào)用系統(tǒng)服務函數(shù),自我掛起,暫時放棄CPU使用權(quán),使低優(yōu)先權(quán)任務能夠得以運行。這種系統(tǒng)服務函數(shù)就包括這一小節(jié)將要介紹的任務延時函數(shù)OSTimeDly()和下一小節(jié)將要介紹的按時分秒毫秒延時函數(shù)OSTimeDlyHMSM()。4.4.1.1函數(shù)原型

OSTimeDly()函數(shù)申請一個系統(tǒng)提供的延時,延時的單位是一個時鐘節(jié)拍,最大可延時65535個時鐘節(jié)拍。調(diào)用該函數(shù)后,若延時時間不為0,則立即掛起當前任務,μC/OS-Ⅱ進行一次任務調(diào)度,并且執(zhí)行下一個優(yōu)先級最高的就緒態(tài)任務。任務調(diào)用OSTimeDly()后,一旦規(guī)定的時間期滿或者有其它的任務通過調(diào)用OSTimeDlyResume()取消了延時,它就會馬上進入就緒狀態(tài)。當然,只有當該任務在所有就緒任務中具有最高的優(yōu)先級時,它才會立即運行。由于中斷不能延時,所以它的調(diào)用者一定是任務。一、函數(shù)原型voidOSTimeDly(INT16Uticks)reentrant二、功能函數(shù)只有一個參數(shù):ticks,要延時的時鐘節(jié)拍數(shù),無返回值。三、函數(shù)參數(shù)與返回值

4.4.1.2原理與實現(xiàn)

程序清單4.7OSTimeDly()voidOSTimeDly(INT16Uticks)reentrant{#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;

#endifINT8Uy;if(ticks>0){ //若參數(shù)為0,則表示不想對

//任務延時,函數(shù)立即返回OS_ENTER_CRITICAL(); //關中斷y=OSTCBCur->OSTCBY;OSRdyTbl[y]&=~OSTCBCur->OSTCBBitX;//從就緒表中移出當前任務if((OSRdyTbl[y]&=~OSTCBCur->OSTCBBitX)==0){

OSRdyGrp&=~OSTCBCur->OSTCBBitY;}OSTCBCur->OSTCBDly=ticks; //保存節(jié)拍數(shù),每隔一個

//時鐘節(jié)拍,這個變量數(shù)減1OS_EXIT_CRITICAL(); //關中斷OS_Sched(); //當前任務已經(jīng)掛起,執(zhí)行 //下一個優(yōu)先級最高就緒任務}}4.4.1.3應用要點

在調(diào)用OSTimeDly()函數(shù)時必須注意以下事項:時間的長短是用時鐘節(jié)拍的數(shù)目來確定的;可提供的時鐘節(jié)拍數(shù)范圍是:1~65,535;參數(shù)為0,表明不進行延時操作,而立即返回調(diào)用者;為了確保設定的延時時間,建議設定的時鐘節(jié)拍數(shù)加1;只能在任務中調(diào)用,無配置常量。4.4.2按時分秒毫秒延時函數(shù),OSTimeDlyHMSM()

INT8UOSTimeDlyHMSM( INT8Uhour,INT8Uminutes,

INT8Useconds,INT16Umilli)reentrant

4.4.2.1函數(shù)原型

功能:這是一個十分有用的函數(shù),它是以時、分、秒、毫秒為單位進行延時。調(diào)用者:只能是任務。調(diào)用后,如果延時時間不為0,系統(tǒng)將立即掛起當前任務,并進行任務調(diào)度。最長延時:長達256個小時(接近11天)。函數(shù)參數(shù):hours 延時小時數(shù), 取值范圍0~255;mintues

延時分鐘數(shù), 取值范圍0~59;seconds 延時秒數(shù), 取值范圍0~59;milli

延時毫秒數(shù), 取值范圍0~9994.4.2.2返回值OS_ON_ERR 調(diào)用成功;OS_TIME_INVALID_MINUTES 參數(shù)錯誤,分鐘數(shù)大于59;OS_TIME_INVALID_SECONDS 參數(shù)錯誤,秒數(shù)大于59;OS_TIME_INVALID_MILLI 參數(shù)錯誤,毫秒數(shù)大于999;OS_TIME_ZERO_DLY 4個參數(shù)全為0,不操作而直接返回OSTimeDlyHMSM()函數(shù)的返回值有如下幾種:程序清單4.8 OSTimeDlyHMSM()#ifOS_TIME_DLY_HMSM_EN>0INT8UOSTimeDlyHMSM(INT8Uhours,INT8Uminutes,INT8Useconds,NT16Umilli)reentrant{ INT32Uticks;

INT16Uloops;

if(hours>0||minutes>0||seconds>0||milli>0){//條件檢查,全為0,則返回

return(OS_TIME_ZERO_DLY); } if(minutes>59) return(OS_TIME_INVALID_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 +(INT32U)minutes*60L*OS_TICKS_PER_SEC +(INT32U)seconds*OS_TICKS_PER_SEC +OS_TICKS_PER_SEC*((INT32U)milli +500L/OS_TICKS_PER_SEC)/1000L; //換算為時鐘節(jié)拍,精度0.5個節(jié)拍

loops=ticks/65536L; ticks=ticks%65536L;

OSTimeDly(ticks);

while(loops>0){ OSTimeDly(32768);

OSTimeDly(32768);

loops--;} return(OS_NO_ERR);}#endif4.4.2.3原理與實現(xiàn)

4.4.2.4應用要點要使用該函數(shù),首先要用OS_CPU.H文件中定義的全局常數(shù)OS_TICKS_PER_SEC將時間轉(zhuǎn)換為時鐘節(jié)拍數(shù),這個全局常數(shù)表示的是每秒鐘時鐘節(jié)拍器產(chǎn)生的節(jié)拍數(shù)量,稱為時鐘節(jié)拍頻率,取值一般設置在10~100Hz之間;4個參數(shù)全為0,表示不進行任何操作,直接返回;當時鐘周期≧1ms時,計時最小單位是一個時鐘節(jié)拍,精度是0.5個節(jié)拍。

例如:若將時鐘節(jié)拍頻率(OS_TICKS_PER_SEC)設置成100Hz(10ms),4ms的延時不會產(chǎn)生任何延時!而5ms的延時就等于延時10ms;當時鐘周期<1ms時,最小計數(shù)值=OS_TICKS_PER_SEC/1000個時鐘節(jié)拍,分辨率=500L/OS_TICKS_PER_SEC/1000L。

例如:OS_TICKS_PER_SEC=1000,最小計數(shù)單位是1ms,精度=0.5(個最小計算單位)。μC/OS-Ⅱ支持的延時最長為65,535個節(jié)拍。要想支持更長時間的延時,需采用一定的算法,一般的做法是將延時時鐘數(shù)分割為兩部分:一部分是65,536個節(jié)拍的整數(shù)倍,另一部分是總數(shù)減去這個整數(shù)倍節(jié)拍后剩下的節(jié)拍數(shù),然后先算剩下的節(jié)拍數(shù),再算這個整數(shù)倍節(jié)拍數(shù)。

例如:若OS_TICKS_PER_SEC的值為100,用戶想延時15分鐘,則OSTimeDlyHMSM()會延時15×60×100=90,000個時鐘。這個延時會被分割成兩次32,768個節(jié)拍的延時(因為用戶只能延時65,535個節(jié)拍而不是65536個節(jié)拍)和一次24,464個節(jié)拍的延時。在這種情況下,OSTimeDlyHMSM()首先計算24,464個節(jié)拍,然后計算2次32,768個節(jié)拍。由于受到OSTimeDlyHMSM()具體實現(xiàn)方法的限制,用戶不能用函數(shù)OSTimeDlyResume()結(jié)束延時調(diào)用OSTimeDlyHMSM()要求延時超過65,535個節(jié)拍的任務。

假如:時鐘節(jié)拍的頻率是100Hz,用戶就不能調(diào)用OSTimeDlyHMSM(0,10,55,350)或更長延遲時間的任務;只能在任務中調(diào)用,配置常量是OS_TIME_DLY_HMSM_EN。4.4.2.5應用范例

程序清單4.9OSTimeDlyHMSM()應用范例viodtask(void*ppdata)reentrant{ ppdata=ppdata;

for(;;){

應用程序;

OSTimeDlyHMSM(0,0,5,0); //延時5秒

}}OSTimeDlyHMSM()函數(shù)應用范例如程序清單4.9所示,必須注意的是:必須在OS_CFG.H文件中設置OS_TICKS_PER_SEC。4.4.3結(jié)束任務延時,OSTimeDlyResume()

4.4.3.1函數(shù)原型

INT8U OSTimeDlyResume(INT8Uprio)reentran

功能:OSTimeDlyResume()函數(shù)用于喚醒一個用OSTimeDly()或OSTimeDlyHMSM()函數(shù)延時的任務。正在延時的任務可以通過其它任務調(diào)用該函數(shù)取消延時來使自己處于就緒態(tài),而不必等待延時期滿。該函數(shù)還可以喚醒正在等待事件的任務,但不推薦使用這種方法。另外,如果任務是通過等待信號量、郵箱或消息隊列來延時自己的,那么可以簡單地通過控制信號量、郵箱或消息隊列來恢復任務。這種情況存在的唯一問題是可能會多占用一些內(nèi)存,因為它要求用戶分配事件控制塊。限制:不能喚醒一個用OSTimeDlyHMSM()延時且總延時時間超過65,535個時鐘節(jié)拍的任務。調(diào)用者:只能在任務中調(diào)用配置常量:OS_TIME_DLY_RESUME_EN。函數(shù)參數(shù):prio,即指定要喚醒(恢復)任務的優(yōu)先級。4.4.3.2返回值OS_ON_ERR

調(diào)用成功;OS_PRIO_INVALID

參數(shù)指定的優(yōu)先級大于OS_LOWEST_PRIO;OS_TASK_NOT_DLY

要喚醒的任務不在掛起狀態(tài);OS_TASK_NOT_EXIST

指定的任務不存在。4.4.3.4應用范例程序清單4.11OSTimeDlyResume()應用范例voidtask(void*ppdata)reentrant{ INT8Uerr; ppdata=ppdata; for(;;){ 應用程序; err=OSTimeD

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論