1. 程式人生 > 其它 >【STM32F429】第15章 ThreadX系統時鐘節拍和時間管理(絕對延遲和相對延遲)

【STM32F429】第15章 ThreadX系統時鐘節拍和時間管理(絕對延遲和相對延遲)

論壇原始地址(持續更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514

第15章 ThreadX系統時鐘節拍和時間管理(絕對延遲和相對延遲)

本章節為大家講解ThreadX作業系統的系統時鐘節拍和時間管理函式,其中時間管理函式是ThreadX的基本函式,初學者務必要掌握。

15.1 ThreadX的時鐘節拍

15.2 ThreadX的時間管理

15.3 實驗例程說明

15.4 總結

15.1 ThreadX的時鐘節拍

任何作業系統都需要提供一個時鐘節拍,以供系統處理諸如延時、超時等與時間相關的事件。

時鐘節拍是特定的週期性中斷,這個中斷可以看做是系統心跳。中斷之間的時間間隔取決於不同的應用,一般是1ms – 100ms。時鐘的節拍中斷使得核心可以將任務延遲若干個時鐘節拍,以及當任務等待事件發生時,提供等待超時等依據。時鐘節拍率越快,系統的額外開銷就越大。

對於Cortex-M3核心的STM32F103和,Cortex-M4核心的STM32F407以及F429和Cortex-M核心的STM32H7,做的例子都是用滴答定時器來實現系統時鐘節拍的。

  • 滴答定時器Systick

SysTick定時器被捆綁在NVIC中,用於產生SysTick異常(異常號:15),滴答定時器是一個24位的遞減計數器,支援中斷。使用比較簡單,專門用於給作業系統提供時鐘節拍。

ThreadX的系統時鐘節拍可以在配置檔案tx_initialize_low_level.s裡面設定:

SYSTEM_CLOCK EQU 400000000

SYSTICK_CYCLES EQU ((SYSTEM_CLOCK / 1000) -1)

如上所示的配置表示系統時鐘節拍是1KHz,即1ms。

15.2 ThreadX的時間管理

時間管理功能是ThreadX作業系統裡面最基本的功能,同時也是必須要掌握好的。

15.2.1 時間延遲介紹

ThreadX中的時間延遲函式主要有以下兩個作用:

  • 為週期性執行的任務提供延遲。
  • 對於搶佔式排程器,讓高優先順序任務可以通過時間延遲函式釋放CPU使用權,從而讓低優先順序任務可以得到執行。

下面我們通過如下的框圖來說明一下延遲函式對任務執行狀態的影響,讓大家有一個形象的認識。

執行條件:

  • 僅對任務Task1的執行狀態做說明。
  • 排程器支援時間片排程和搶佔式排程。

執行過程描述如下:

  • 起初任務Task1處於執行態,呼叫tx_thread_sleep函式後進入到阻塞狀態,也就是blocked狀態。
  • tx_thread_sleep函式設定的延遲時間到,由於任務Task1不是當前就緒的最高優先順序任務,所以不能進入到執行狀態,只能進入到就緒狀態,也就是ready狀態。
  • 一段時間後,排程器發現任務Task1是當前就緒的最高優先順序任務,從而任務從就緒態切換到執行態。
  • 由於時間片排程,任務Task1由執行態切換到就緒態。

上面就是一個簡單的任務執行狀態的切換過程。

15.2.2 函式tx_thread_sleep

函式原型:

UINT tx_thread_sleep(ULONG timer_ticks)

函式描述:

函式tx_thread_sleep用於任務的延遲。

1、 引數timer_ticks用於設定延遲的時鐘節拍個數,範圍1- 0xFFFFFFFF。

2、 返回值:

  • TX_SUCCESS (0x00) ,呼叫成功。
  • TX_WAIT_ABORTED (0x1A) ,被其它中斷,定時器組或者任務終止執行。
  • TX_CALLER_ERROR (0x13) ,不是在任務中呼叫。

注意事項:

  • 不允許在中斷中呼叫,僅可以在任務中呼叫。

使用舉例:

/*
*********************************************************************************************************
*    函 數 名: AppTaskCom
*    功能說明: 這裡用作LED閃爍
*    形    參: thread_input 建立該任務時傳遞的形參
*    返 回 值: 無
    優 先 級: 5
*********************************************************************************************************
*/
static void AppTaskCOM(ULONG thread_input)
{    
    (void)thread_input;
    
    while(1)
    {
        bsp_LedToggle(2);
        tx_thread_sleep(100);
    }                                                                              
}

15.2.3 函式tx_time_get

函式原型:

ULONG tx_time_get(VOID);

函式描述:

函式tx_time_get用於獲取系統當前執行的時鐘節拍數。

注意事項:

  • 可以在任務,定時器組合中斷服務程式裡面呼叫。

使用舉例:

ULONG current_time;

current_time = tx_time_get();

15.2.4 絕對延遲函式實現方法

注:這裡絕對延遲和週期性延遲是一個意思。

ThreadX核心只有相對延遲函式tx_thread_sleep,沒有絕對延遲函式,這裡簡單實現一個tx_thread_sleepuntil。

條件:

1、有一個bsp_KeyScan函式,這個函式處理時間大概耗時2ms。

2、有兩個任務,一個任務Task1是用的tx_thread_sleep延遲,延遲10ms,另一個任務Task2是用的tx_thread_sleepuntil(ThreadX沒有這個函式,要自己封裝)延遲,延遲10ms。不考慮任務被搶佔而造成的影響。

相對性的含義:

bsp_KeyScan+ tx_thread_sleep(10) ---> bsp_KeyScan + tx_thread_sleep (10)

|----2ms + 10ms 為一個週期------| |----2ms + 10ms 為一個週期----|

週期性延遲含義:

bsp_KeyScan + tx_thread_sleepunti ------> bsp_KeyScan + tx_thread_sleepunti

|----10ms為一個週期(2ms包含在10ms內)---| |------10ms 為一個週期---------------|

這裡我們通過tx_thread_sleep來實現一個tx_thread_sleepuntil

static void AppTaskMsgPro(ULONG thread_input)
{
    UINT Delay, NextTime;
    const UINT Frequency = 200;
        
    /* 獲取Frequency個時鐘節拍後的時間 */
    NextTime = tx_time_get() + Frequency;
        
    while(1)
    {
                bsp_LedToggle(3);
               
                Delay = NextTime - tx_time_get();
                NextTime += Frequency;
               
                if(Delay <= Frequency)
                {
                        tx_thread_sleep(Delay);
                }
        }
}

15.3 實驗例程

配套例子:

V6-3010_ThreadX Sleep Until

實驗目的:

  1. 學習ThreadX絕對延遲和相對延遲的實現。

實驗內容:

1、共建立瞭如下幾個任務,通過按下按鍵K1可以通過串列埠或者RTT列印任務堆疊使用情況

========================================================

OS CPU Usage = 1.05%

========================================================

任務優先順序 任務棧大小 當前使用棧 最大棧使用 任務名

Prio StackSize CurStack MaxStack Taskname

2 4092 303 459 App Task Start

30 1020 303 303 App Task STAT

31 1020 87 71 App Task IDLE

5 4092 167 167 App Msp Pro

4 4092 167 167 App Task UserIF

5 4092 167 167 App Task COM

0 1020 191 191 System Timer Thread

串列埠軟體可以使用SecureCRT或者H7-TOOL RTT檢視列印資訊。

App Task Start任務 :啟動任務,這裡用作BSP驅動包處理。

App Task MspPro任務 :訊息處理,這裡用作LED閃爍。

App Task UserIF任務 :按鍵訊息處理。

App Task COM任務 :這裡用作LED閃爍。

App Task STAT任務 :統計任務

App Task IDLE任務 :空閒任務

System Timer Thread任務:系統定時器任務

2、 (1) 凡是用到printf函式的全部通過函式App_Printf實現。

(2) App_Printf函式做了訊號量的互斥操作,解決資源共享問題。

3、預設上電是通過串列埠列印資訊,如果使用RTT列印資訊

(1) MDK AC5,MDK AC6或IAR通過使能bsp.h檔案中的巨集定義為1即可

#define Enable_RTTViewer 1

(2) Embedded Studio繼續使用此巨集定義為0, 因為Embedded Studio僅製作了除錯狀態RTT方式檢視。

串列埠列印資訊方式(AC5,AC6和IAR):

波特率 115200,資料位 8,奇偶校驗位無,停止位 1

RTT列印資訊方式(AC5,AC6和IAR):

Embedded Studio僅支援除錯狀態RTT列印:

由於Embedded Studio不支援中文,所以中文部分顯示亂碼,不用管。

程式執行框圖:

15.4 結

本章節主要為大家講解了ThreadX節拍和時間管理函式,其中時間管理函式是ThreadX學者務必要掌握。