1. 程式人生 > >liteos實時作業系統之時間管理

liteos實時作業系統之時間管理

概述

基本概念

時間管理以系統時鐘為基礎。時間管理提供給應用程式所有和時間有關的服務。

系統時鐘是由定時/計數器產生的輸出脈衝觸發中斷而產生的,一般定義為整數或長整數。輸出脈衝的週期叫做一個“時鐘滴答”。系統時鐘也稱為時標或者Tick。一個Tick的時長可以靜態配置。

使用者是以秒、毫秒為單位計時,而晶片CPU的計時是以Tick為單位的,當用戶需要對系統操作時,例如任務掛起、延時等,輸入秒為單位的數值,此時需要時間管理模組對二者進行轉換。

Tick與秒之間的對應關係可以配置。

Huawei LiteOS的時間管理模組提供時間轉換、統計、延遲功能以滿足使用者對時間相關需求的實現。

相關概念

  • Cycle

系統最小的計時單位。Cycle的時長由系統主頻決定,系統主頻就是每秒鐘的Cycle數。

  • Tick

Tick是作業系統的基本時間單位,對應的時長由系統主頻及每秒Tick數決定,由使用者配置。

開發指導

使用場景

使用者需要了解當前系統執行的時間以及Tick與秒、毫秒之間的轉換關係等。

功能

Huawei LiteOS系統中的時間管理主要提供以下兩種功能:

  • 時間轉換:根據主頻實現CPU Tick數到毫秒、微秒的轉換。
  • 時間統計:獲取系統Tick數。

功能分類

介面名

描述

時間轉換

LOS_MS2Tick

毫秒轉換成Tick(預留介面)

LOS_Tick2MS

Tick轉化為毫秒(預留介面)

時間統計

LOS_CyclePerTickGet

每個Tick多少Cycle數

LOS_TickCountGet

獲取當前的Tick數

開發流程

時間管理的典型開發流程:

  1. 確認配置項LOSCFG_BASE_CORE_TICK_HW_TIME為YES開啟狀態。
    • 在los_config.h中配置每秒的Tick數LOSCFG_BASE_CORE_TICK_PER_SECOND;
  2. 呼叫時鐘轉換介面。
  3. 獲取系統Tick數完成時間統計。
    • 通過LOS_TickCountGet獲取全域性g_ullTickCount。

注意事項

  • 獲取系統Tick數需要在系統時鐘使能之後。
  • 時間管理不是單獨的功能模組,依賴於los_config.h中的OS_SYS_CLOCK和LOSCFG_BASE_CORE_TICK_PER_SECOND兩個配置選項。
  • 系統的Tick數在關中斷的情況下不進行計數,故系統Tick數不能作為準確時間計算。

程式設計例項

例項描述

在下面的例子中,介紹了時間管理的基本方法,包括:

  1. 時間轉換:將毫秒數轉換為Tick數,或將Tick數轉換為毫秒數。
  2. 時間統計和時間延遲:統計每秒的Cycle數、Tick數和延遲後的Tick數。

程式設計示例

前提條件:

  • 配好LOSCFG_BASE_CORE_TICK_PER_SECOND每秒的Tick數。
  • 配好OS_SYS_CLOCK 系統時鐘,單位: Hz。

時間轉換:

VOID Example_TransformTime(VOID)
{  
    UINT32 uwMs;
    UINT32 uwTick;

    uwTick = LOS_MS2Tick(10000);//10000 ms數轉換為Tick數
     printf("uwTick = %d \n",uwTick);
    uwMs= LOS_Tick2MS(100);//100 Tick數轉換為ms數
        printf("uwMs = %d \n",uwMs);
}

時間統計和時間延遲:

UINT32 Example_GetTick(VOID)
{
    UINT32 uwRet = LOS_OK;
    UINT32 uwcyclePerTick;
    UINT64 uwTickCount1,uwTickCount2;

    uwcyclePerTick  = LOS_CyclePerTickGet();//每個Tick多少Cycle數
    if(0 != uwcyclePerTick)
    {
        dprintf("LOS_CyclePerTickGet = %d \n", uwcyclePerTick);
    }

    uwTickCount1 = LOS_TickCountGet();//獲取Tick數
    if(0 != uwTickCount1)
    {
        dprintf("LOS_TickCountGet = %d \n", (UINT32)uwTickCount1);
    }
    LOS_TaskDelay(200);//延遲200 Tick
    uwTickCount2 = LOS_TickCountGet();
    if(0 != uwTickCount2)
    {
        dprintf("LOS_TickCountGet after delay = %d \n", (UINT32)uwTickCount2);
    }
        
    if((uwTickCount2 - uwTickCount1) >= 200)
    {
        uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SYSTIC,LOS_INSPECT_STU_SUCCESS);
        if (LOS_OK != uwRet)  
        {
            dprintf("Set Inspect Status Err\n");
        }
        return LOS_OK;   
    }
    else
    {
        uwRet = LOS_InspectStatusSetByID(LOS_INSPECT_SYSTIC,LOS_INSPECT_STU_ERROR);
        if (LOS_OK != uwRet)  
        {
            dprintf("Set Inspect Status Err\n");
        }
        return LOS_NOK; 
    }
}