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等级