前言
- 今天我們來評測linux內核的高精度定時器。順便利用通過Tektronix示波器 和 DS100 Mini 數字示波器進行交叉測試。
- 因項目需要用到精準的時間周期,所以要評估它的可行性,并驗證正點原子的示波器能不能支撐嵌入式開發流程。
Linux高精度定時器說明
- 其實傳統的低分辨率定時器隨著技術的演進,已經無法滿足開發需求。而且硬件的不斷發展,硬件定時器的精度也越來越高,這也給高精度定時器創建了有利條件。
- 低分辨率的定時大部分時間復雜度可以實現O(1),當有進位發生時,不可預測的O(N)定時器級聯遷移時間,影響定時器的精度。
- 低分率的定時器可以說在超時應用場景上更加合適,以超時為目的,期望在超時到來之前獲得正確的結果的場景,應用低分辨率的定時器適合不過。
- 為了滿足技術的演進及定時器的精度要求,Linux內核為高精度定時器重新設計了一套軟件架構,它可以為我們提供納秒級的定時器精度,以滿足我們開發需求。精度如何實測才知道。。。。
Linux高精度定時器驅動編寫
-
為了驗證高精度定時器的分辨率,我們寫一個簡單的內核驅動(功能:在設定的周期內反轉IO,然后通過示波器測量精度)。
-
高精度定時器使用步驟:
- 初始化定時器工作模式:hrtimer_init(&kthread_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- 設置定時器的回調函數:kthread_timer.function = hrtimer_cb_func;
- 啟動定時器:hrtimer_start(&kthread_timer, ktime_set(HRTIMER_TEST_CYCLE), HRTIMER_MODE_REL);
- 在定時器回調函數中,增加定時到期時間:hrtimer_forward(timer, timer->base->get_time(), ktime_set(HRTIMER_TEST_CYCLE));
- 內核驅動模塊代碼模塊實現:
#include"hrtimer_test.h"
#defineHRTIMER_TEST_PIN7
#defineHRTIMER_TEST_CYCLE0,(100000/2)
#defineDEVICE_NAME"HRTIMER_TEST"
#defineCLASS_NAME"HRTIMER_TEST"
intmajor_number;
structdevice*device;
structclass*class;
staticstructhrtimerkthread_timer;
intvalue=0;
enumhrtimer_restarthrtimer_cb_func(structhrtimer*timer){
ChipBspGpio_ExportSet(ULTRASONIC_TEST_PIN,value);
value=!value;
hrtimer_forward(timer,timer->base->get_time(),ktime_set(HRTIMER_TEST_CYCLE));
returnHRTIMER_RESTART;
}
voidkthread_hrtimer_init(void){
hrtimer_init(&kthread_timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
kthread_timer.function=hrtimer_cb_func;
hrtimer_start(&kthread_timer,ktime_set(HRTIMER_TEST_CYCLE),HRTIMER_MODE_REL);
}
staticint__inithrtimer_test_init(void){
printk(KERN_ALERT"hrtimer_test:Init!!\n");
major_number=register_chrdev(0,DEVICE_NAME,NULL);
if(major_number0){
printk(KERN_ALERT"hrtimer_test:Registerfail!\n");
returnmajor_number;
}
printk(KERN_ALERT"Registesuccess,majornumberis%d\n",major_number);
class=class_create(THIS_MODULE,CLASS_NAME);
if(IS_ERR(class)){
unregister_chrdev(major_number,DEVICE_NAME);
returnPTR_ERR(class);
}
device=device_create(class,NULL,MKDEV(major_number,0),NULL,DEVICE_NAME);
if(IS_ERR(device)){
class_destroy(class);
unregister_chrdev(major_number,DEVICE_NAME);
returnPTR_ERR(device);
}
printk(KERN_ALERT"hrtimer_test:initsuccess!!\n");
kthread_hrtimer_init();
return0;
}
staticvoid__exithrtimer_test_exit(void){
hrtimer_cancel(&kthread_timer);
device_destroy(class,MKDEV(major_number,0));
class_unregister(class);
class_destroy(class);
unregister_chrdev(major_number,DEVICE_NAME);
printk(KERN_ALERT"hrtimer_test:exitsuccess!!\n");
}
module_init(hrtimer_test_init);
module_exit(hrtimer_test_exit);
MODULE_AUTHOR("RieChen");
MODULE_LICENSE("GPL");
- 該驅動模塊主要功能:在定時器回調函數中,周期性反轉GPIO,然后查看其定時器精度。其中宏定義(HRTIMER_TEST_CYCLE)為定時的周期。
Linux高精度定時器的評測
- 周期1ms評測:
- 修改宏定義:HRTIMER_TEST_CYCL設置周期為1ms. 修改如下
#defineHRTIMER_TEST_CYCLE0,(1000000/2)
- 通過Tektronix示波器測量:

- 通過DS100 Mini 數字示波器測量:

- 結論:Tektronix示波器和DS100 Mini 數字示波器數據相符,波形穩定。統計出的頻率與周期跟軟件設置一致
- 周期100us評測:
- 修改宏定義:HRTIMER_TEST_CYCL設置周期為100us. 修改如下
#defineHRTIMER_TEST_CYCLE0,(100000/2)
- 通過Tektronix示波器測量:

- 通過DS100 Mini 數字示波器測量:

- 結論:Tektronix示波器和DS100 Mini 數字示波器數據相符,波形穩定。統計出的頻率與周期跟軟件設置一致
- 周期10us評測:
- 修改宏定義:HRTIMER_TEST_CYCL設置周期為10us. 修改如下
#defineHRTIMER_TEST_CYCLE0,(10000/2)
- 通過Tektronix示波器測量:

- 通過DS100 Mini 數字示波器測量:

- 結論:Tektronix示波器和DS100 Mini 數字示波器數據都無法精確測量,波形不清晰。
- 周期1us評測:
- 修改宏定義:HRTIMER_TEST_CYCL設置周期為1us. 修改如下:
#defineHRTIMER_TEST_CYCLE0,(1000/2)
- 通過Tektronix示波器測量:

- 通過DS100 Mini 數字示波器測量:

- 結論:Tektronix示波器和DS100 Mini 數字示波器數據都無法精確測量,波形不清晰。
總結
- 高精度定時器總結
- Linux提供的高精度定時器可以滿足我們大部分需求的,要注意的的,定時器回調函數不能做太多任務,并需要快速執行,否則無法保證其周期性。(作者認為高精度定時器可以看作一個外部中斷的思想進行處理)
- 通過此次評估,Linux提供的高精度定時器可以滿足我的項目需求,而且建議幾十納秒級的需求使用比較合適,如果幾納秒的需求不適合。
- 示波器總結
- 通過評估數據上看,DS100 Mini 數字示波器可以替代一般的臺式示波器。
- DS100 Mini 數字示波器可以在大部分場景上使用,可以滿足項目需求
審核編輯 黃昊宇
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
驅動
+關注
關注
12文章
1901瀏覽量
86539 -
Linux
+關注
關注
87文章
11465瀏覽量
212822 -
定時器
+關注
關注
23文章
3288瀏覽量
117256
發布評論請先 登錄
相關推薦
熱點推薦



詳解高精度定時器與高級控制定時器
在高精度定時器中,可以使用外部事件來對 PWM 輸出進行封鎖,并可自動恢復;在高級控制定時器中,可以使用 Break 或是 Clr_input 來對 PWM 輸出進行封鎖, 然后也可以自動恢復,其中 Break 必須結合 AOE
Linux高精度定時器hrtimer使用示例
要使用高精度定時器hrtimer。 使用示例 單次定時 加載驅動一秒后輸出“ hrtimer handler ”: # include # include # include # in
評論