linux從內核2.6.16開始引入了高精度定時器,達到ns級別。自此,內核擁有兩套并行計時器,低精度和高精度。如果高精度沒有開啟,即使使用高精度函數,默認使用的仍舊是低精度。
高精度:?
雖然內核已經支持高精度,但是對于不少產品而言,由于內核是裁剪的,配置的時候并沒有加入編譯進去,雖然對應的內核源碼中有相關代碼。如果想支持,那么可以進入內核源碼,執行make menuconfig。去查看當前系統是否支持高精度,(備注:因為里面選項比較多,還可以直接去查看編譯好的.config文件,看里面是否有CONFIG_HIGH_RES_TIMERS,如果有,就通過make menuconfig開啟,沒有的話,就是不支持),是否真正啟用,可以在內核中對相應宏進行打印。
低精度:?
(定時精度和頻率HZ相關,精度為(1000/HZ ) ms)
#include ?
void do_gettimeofday(struct timeval *tv);//獲取精確時間函數?
//內核相關定義
struct timeval {?
time_t tv_sec;? ? ? ?/* seconds */
suseconds_t tv_usec; /* microseconds */?
};
#define TIMER_TOTAL_NUM? 2? ?//定義定時器總數
struct? timeval? ?tv;
struct? timer_list? funTimer[TIMER_TOTAL_NUM ]; //定義定時器相關結構體數組
short int siTimeInitFlag[TIMER_TOTAL_NUM? ]; //定時器初始化標志
short int siTimeoutFlag[TIMER_TOTAL_NUM? ];//定時器啟動標志
typedef void (*pfTimerFunction)(unsigned long ulData);? //定義定時器處理函數指針,方便處理多個定時器
//定時器初始化
void timer_init(int iIndex, int iMs, pfTimerFunction pTimerFunction)?
{
init_timer(&funTimer[iIndex]);//初始化
funTimer[iIndex].function = pTimerFunction;//處理函數
funTimer[iIndex].data = (unsigned long)iMs;//參數傳遞,在處理函數中可以不使用
funTimer[iIndex].expires = jiffies + HZ; //定時時長設置為1s
add_timer(&funTimer[iIndex]);//開啟定時器
siTimeInitFlag[iIndex] = 1;//初始標志置為1
siTimeoutFlag[iIndex] = 1;//定時器啟動標志
}
//定時器處理函數
static void timer_function(unsigned long ulData)
{
/*
這里寫自己需要執行的功能.........
.................
//定時是否準確測試
do_gettimeofday(&tv);//獲取時間
printk("time------%d:%d\n", tv.tv_sec, tv.tv_usec);//查看間隔,看定時時間是否精準
*/
//循環定時器實現,如果不實現循環,可執行自己要實現的,再進行定時器刪除,也可以不刪除,到時后自動刪除
if(1 == siTimeoutFlag[0])
{
del_timer_sync(&funTimer[0]);//用del_timer_sync代替了del_timer
}
funTimer[0].function = timer_function;
funTimer[0].expires = jiffies + HZ;//重新設置定時時間
add_timer(&funTimer[0]);//啟動定時器
siTimeoutFlag[0] = 1;
}
//簡單例子調用
int main(void)
{
timer_init(0, 3, timer_function);
return 0;
}
使用注意:?
1、加入初始化標志siTimeInitFlag[iIndex] 是防止定時器在運行時,再次初始化,這樣會導致內核崩潰;?
2、使用循環定時器時, funTimer[0].expires = jiffies + HZ; funTimer的成員expires 必須重新賦值,且要執行 ,?
add_timer(&funTimer[0]);?
3、定時時長funTimer[iIndex].expires = jiffies + HZ; //宏定義HZ可以查看源碼,或者打印出來,jiffies 為節拍數,系統最高?
精度為(1000/HZ)ms。?
jiffies + HZ————-設置定時時長為1s;?
jiffies + 1—————設置定時時長為(1000/HZ)ms,是系統最高精度?
4、內核添加printk后,由于打印函數耗時,會導致執行時間延長,一個打印延長一般為ms級別
?
評論
查看更多