1. 程式人生 > >RTAI的使用者空間程式設計(二)—— 實時任務定時器設定

RTAI的使用者空間程式設計(二)—— 實時任務定時器設定

在建立實時任務的過程中,主要通過3個函式對定時器進行設定,它們分別是:rt_set_oneshot_mode,rt_set_periodic_mode和start_rt_timer,下面分別對這3個函式進行分析。

1. rt_set_oneshot_mode
用於將定時器設定為單觸發模式,所謂單觸發模式,就是說,每當定時器產生一次中斷後,系統都要根據目前系統任務對時間精度的要求情況對定時器重新進行程式設計,設定下一次觸發的時間。rt_set_oneshot_mode完成的功能如下:
1.呼叫stop_rt_timer停止定時器的執行;
2.設定全域性變數oneshot_timer的值為1;在時鐘中斷函式中,系統會檢查oneshot_timer的值,判斷定時器的工作模式,然後根據定時器的模式對定時器進行相應的操作。

2. rt_set_periodic_mode
rt_set_periodic_mode的操作與rt_set_oneshot_mode的類似,只不過它將oneshot_timer的值設為0,表示定時器應工作在週期模式;當定時器工作在週期模式下時,系統只要對定時器進行一次初始化,指定定時器產生中斷的週期,以後就不再需要對定時器進行程式設計了。

3. start_rt_timer
根據設定的定時器執行模式對定時器進行初始化,它完成的主要功能如下:
1.呼叫函式rt_request_timer註冊時鐘中斷服務程式rt_timer_handler;
2.初始化系統用於儲存時間資訊的結構rt_smp_times(就是前面所說的rt_times);
3.呼叫rt_request_linux_irq註冊一個Linux下的中斷服務程式recover_jiffies,這個中斷程式和Linux的時鐘中斷服務程式共享時鐘中斷,recover_jiffies用於補償Linux所丟失的時鐘中斷(因為可能由於實時任務的執行,使Linux很長一段時間得不到執行的機會,無法響應時鐘中斷)。

4. 注意

  1. 請注意,如果你不設定模式,預設是週期性的。
  2. 使用stop_rt_timer停止定時器,會設定定時器返回預設的狀態(即週期性的)。如果沒有刪除在使用的RTAI排程程式,你想確定在多模組上是單觸發模式,在每一個start_rt_timer前總要呼叫rt_set_oneshot_mode。
  3. 使用start_rt_timer(0),自動強制進入單觸發模式。 
  4. rt_is_hard_timer_running API可以知道是否已經有個計時器在運行了,該函式應該小心使用,因為它會形成一個“race”情況。
  5. 在使用任何與時間處理相關的函式前呼叫start_rt_timer API很重要,否則所有的值都被認為是錯誤的。
  6. 實時任務(本文所指的實時任務,如果沒有特別說明都是硬實時的)都是以Linux核心模組方式實現的,要實現一個實時任務,在模組初始化的時候要呼叫RTAI的任務建立函式初始化實時任務相關的資料和環境,指定定時器的執行模式(單觸發模式或週期模式),初始化定時器,然後開始執行任務;需要注意的是,當沒有載入任何RTAI的實時任務模組的時候,RTAI的任務排程和時鐘中斷都沒有啟動。

5. 示例程式碼

#define TICK_TIME 1000000
if ((hard_timer_running = rt_is_hard_timer_running()))
{
    printf("Skip hard real_timer setting...\n");
    sampling_interval = nano2count(TICK_TIME);
}
else
{
    printf("Starting real time timer...\n");
    rt_set_oneshot_mode();
    start_rt_timer(0);
}

sampling_interval = nano2count(TICK_TIME);