1. 程式人生 > 其它 >ucos(二)時間管理

ucos(二)時間管理

一、時間管理

UCOSIII提供了一系列的時間管理函式,延時以時鐘節拍(例如1000個節拍,就是進行1000個計數就是1秒時間的到達)為基準。

1.時鐘節拍

  時鐘節拍可謂是實時作業系統的心臟,它若不跳動,整個系統都將會癱瘓。時鐘節拍就是作業系統的時基,作業系統要實現時間上的管理,必須依賴於時基(時間基準)。   時鐘節拍就是系統以固定的頻率產生中斷(時基中斷),並在中斷中處理與時間相關的事件,推動所有任務向前執行。時鐘節拍需要依賴於硬體定時器,在 STM32 裸機程式中經常使用的 SysTick 時鐘作為產生作業系統的時鐘節拍。   使用者需要先在“os_cfg_app.h”中設定時鐘節拍的頻率,該頻率越高,作業系統檢測事件就越頻繁,可以增強任務的實時性,但太頻繁也會增加作業系統核心的負擔加重,所以使用者需要權衡該頻率的設定。
配置標頭檔案:os_cfg_app.h #define OS_CFG_TICK_RATE_HZ 1000u

2.任務睡眠延時n個時鐘節拍【推薦】

void OSTimeDly (OS_TICK dly, OS_OPT opt, OS_ERR *p_err)
引數: dly:睡眠的時鐘節拍數 opt:決定任務的喚醒時刻,預設OS_OPT_TIME_PERIODIC(週期模式);其他模式為OS_OPT_TIME_DLY(相對模式)、OS_OPT_TIME_MATCH(絕對模式)。 p_err:返回錯誤碼,沒有錯誤的就返回OS_ERR_NONE 返回值:無

3、相對模式

(1)一個時鐘節拍中斷來,核心執行相關的中斷服務。
(2)中斷結束後,所有高優先順序的任務得到執行。這些高優先順序任務的執行時間是未知的,而且是變化的。 (3)當高優先順序的任務執行完時,核心切換到相對低優先順序的任務,任務將呼叫OSTimeDly(),實現相對模式延時2個時鐘節拍。 (4)任務呼叫OSTimeDly(),以“相對模式”延時2個時鐘節拍。這時,核心將該任務放入一個等待列表中,它將等待2個時鐘節拍。在等待延時結束的任務並不會佔用CPU的處理時間。 (5)下一個時鐘節拍來到。如果有高優先順序的任務在等待這個時鐘節拍,那麼核心將會在節拍中斷結束後排程它們執行。 (6)高優先順序的任務得到執行。 (7)又一個時鐘節拍到來。這是低優先順序的任務在等待的時鐘節拍,在這個時鐘節拍到來後它將會轉入就緒態。
(8)因為在這個時鐘節拍沒有高優先順序的任務需要執行,核心將切換到這個低優先順序的任務。 (9)因為受高優先順序執行時間的影響,這個低優先順序的任務的延時並不精確地等於預期2個時鐘節拍。 實際上,要想精確地獲得和預期的時鐘節拍是幾乎不可能的。例如,使用者可能需要延時2個節拍,但下一個時鐘節拍有可能在使用者呼叫OSTimeDly()後馬上就到來。如果高優先順序的任務的執行時間更長,那麼(3)和(4)在時間軸上還會進一步右移,這時任務的延時更像是一個節拍,而不是2個。 “相對”這個關鍵字,意思會有參考物件。例如物理學中的相對靜止,該物體的執行速度參考另外一個物體的執行速度是相對靜止的,參考其他物體是運動的。在UCOSIII中,就是低任務優先順序的相對延時的參考物件為高優先順序任務執行的結束開始延時。

4、週期模式

核心將根據指定的週期確定一系列的“匹配值”,當時鍾計數器OSTickCtr達到這些“匹配值”時,任務將被喚醒。 “相對模式”和“週期模式”也許看不出區別,但實際上兩者是不同的。“在相對模式”下,當系統負荷較重時有可能延時會少一個節拍,甚至偶爾差多個節拍。“在週期模式”下,任務仍然可能被延遲執行,但它總會和預期的的“匹配值”同步。因此,推薦使用“週期模式”來實現長時間執行的週期性延時。 最後,絕對模式可以用來在上電後指定的時間執行具體的動作。例如,在產品上電10秒後關閉某盞燈,這時使用OS_OPT_TIME_MATCH選項,而引數dly對應的是預期時刻時鐘節拍計數器OSTickCtr的值。

5.任務延時指定的時間,採用“時:分:秒:毫秒”的方式【少用】

#if OS_CFG_TIME_DLY_HMSM_EN > 0u void OSTimeDlyHMSM (CPU_INT16U hours, CPU_INT16U minutes, CPU_INT16U seconds, CPU_INT32U milli, OS_OPT opt, OS_ERR *p_err)
  儘管UCOSIII允許任務延時很長時間,但實際上並不推薦這種做法。這樣做,沒有任何標識可以獲知是否真正處於“存活”狀態,除非可以監控任務剩餘的等待時間。更好的做法是,讓任務每大約1min喚醒一次,並且告訴該任務處於正常狀態。

6.恢復被延時的任務【少用】

#if OS_CFG_TIME_DLY_RESUME_EN > 0u void OSTimeDlyResume (OS_TCB *p_tcb, OS_ERR *p_err)
  該函式用於恢復呼叫了OSTimeDly或OSTimeDlyHMSM的任務,延時的任務並不知道它是被其他任務恢復的,它會認為是延時結束而得到恢復的。因此,請謹慎使用該函式。

7.獲取當前時鐘節拍計數器

OS_TICK OSTimeGet (OS_ERR *p_err)
利用該函式,程式可以進行粗略的時間測量,並大概地知道上電後已執行的時間。

8.設定時鐘節拍的計數值

void OSTimeSet (OS_TICK ticks, OS_ERR *p_err)
該函式允許使用者改變當前時鐘節拍計數器的值,儘管UCOSIII允許這麼做,但務必要謹慎使用。

9.觸發一次時鐘節拍服務

void OSTimeTick (void)
該函式在SysTick_Handler被呼叫,用於更新任務的延時和超時。