本文轉載自:http://blog.csdn.net/dosculler/article/details/7932315
一、jiffies定時器,HZ=100,精度只能達到10ms。
注:采用jiffies+msecs_to_jiffies(xx ms);可做到ms級,不過精度不夠
#include <Linux/jiffies.h>//DO-->jiffies調用頭文件
#include <linux/timer.h> //DO-->timer_list結構體
static struct timer_list ms_timer;//DO-->定義timer_list結構體
static void ms_timer_handler(void)//DO-->定義定時器處理函數
{
printk("DO_DEBUG----------->%s\n",__func__);
// ms_timer.expires=jiffies+HZ;
ms_timer.expires=jiffies+msecs_to_jiffies(10);
ms_timer.function=&ms_timer_handler;
add_timer(&ms_timer);
}
static int32_t xxx_init(void)
{
// hrtimer_init_module();
init_timer(&ms_timer); //DO-->初始化定時器
ms_timer.expires=jiffies+msecs_to_jiffies(10); //DO-->定義中斷時間:10ms進入中斷
//ms_timer.expires=jiffies+HZ;
//ms_timer.data=(unsigned long)ms_timer;//區分不同定時器,未驗證
ms_timer.function=&ms_timer_handler; //DO-->定義定時器中斷處理函數
add_timer(&ms_timer); //DO-->增加注冊定時器,使定時器生效
}
二、hrtimer高精度定時器,可做到ns級,此處做到毫秒如下例:
注:實際是為納秒級,由此處ktime_set(const long secs, const unsigned long nsecs)決定的,參數下此處參數即可實現納秒級。
#include <linux/dma-mapping.h> //DO-->hrtimer包含以下三個頭文件 /* DMA APIs */
#include <linux/hrtimer.h>
#include <linux/time.h> /* struct timespec */
#define KER_PRINT(fmt, ...) printk("<ker-driver>"fmt, ##__VA_ARGS__);
static struct hrtimer vibe_timer;
static struct work_struct vibe_work;
static int value = 2000; /*注:以毫秒ms為單位 Time out setting,2 seconds */
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer) //DO-->回調函數,中斷時調用
{
struct timespec uptime;
do_posix_clock_monotonic_gettime(&uptime);
KER_PRINT("Time:%lu.%02lu\n",
(unsigned long) uptime.tv_sec,
(uptime.tv_nsec / (NSEC_PER_SEC / 1000)));
KER_PRINT("vibrator_timer_func\n");
schedule_work(&vibe_work);
return HRTIMER_NORESTART;
}
static void vibe_work_func(struct work_struct *work) //DO-->工作隊列函數
{
KER_PRINT("'vibe_work_func'-->work\n");
// msleep(50); /* CPU sleep */
vibe_timer.function = vibrator_timer_func;
hrtimer_start(&vibe_timer,
ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
}
static void ker_driver_init(void) //DO-->hrtimer高精度定時器初始化函數
{
struct timespec uptime;
KER_PRINT("ker_driver_init\n");
hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); //DO-->hrtimer定時器初始化
vibe_timer.function = vibrator_timer_func; //DO-->hrtimer定時器回調函數
hrtimer_start(&vibe_timer,
ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL); //DO-->hrtimer定時器時間初始化,其中ktime_set(秒,納秒)
do_posix_clock_monotonic_gettime(&uptime); //線程建立時間,用於比較看(定時器)此時時間
KER_PRINT("Time:%lu.%02lu\n",
(unsigned long) uptime.tv_sec,
(uptime.tv_nsec / (NSEC_PER_SEC / 1000)));
INIT_WORK(&vibe_work, vibe_work_func); /* Intialize the work queue */ //初始化工作隊列
}
static int32_t xxxx_init(void)
{
ker_driver_init();
....
}