linux驱动开发,定时器hrtimer的使用
#include <linux/hrtimer.h> //需要引用的头文件
static struct work_struct mytimer_work;
static struct workqueue_struct * mytimer_workqueue = NULL;
static struct hrtimer mytimer_timer;
static bool mytimer_isStartHrtimer = false;
static unsigned char count = 0x00;
/* 开启定时器 */
void mytimer_start_timer_func(void)
{
if(mytimer_isStartHrtimer == false)
{
count = 0x00;
//“ktime_set”的第一个参数是秒,第二个参数是纳秒,目前设置是100ms之后触发定时器回调函数
hrtimer_start(&mytimer_timer, ktime_set(0, 100000000), HRTIMER_MODE_REL);
mytimer_isStartHrtimer = true; //更新状态记录为开启
}
}
EXPORT_SYMBOL(mytimer_start_timer_func); //将函数导出,供外部程序调用,用来开启定时器
/* 关闭定时器 */
void mytimer_cancel_timer_func(void)
{
if(mytimer_isStartHrtimer == true)
{
hrtimer_cancel(&mytimer_timer);
mytimer_isStartHrtimer = false; //更新状态记录为关闭
count = 0x00;
}
}
EXPORT_SYMBOL(mytimer_cancel_timer_func); //将函数导出,供外部程序调用,用来关闭定时器
/* 任务回调函数 */
static void mytimer_work_function(void)
{
if(count != 0)
{
if((count % 2) == 1)
printk("奇数[%d],延时1.5s \n", count);
else
printk("偶数[%d],延时0.5s \n", count);
}
}
/* 定时器回调函数 */
static enum hrtimer_restart mytimer_timer_function(struct hrtimer *timer)
{
if(count >= 10)
count = 0x00; //将数值控制在(1 ~ 10)
count++; //定时到一次,计数自加一次
queue_work(mytimer_workqueue, &mytimer_work); //调度任务
if((count % 2) == 1) //遇到奇数,延时1.5s
hrtimer_start(&mytimer_timer, ktime_set(1, 500000000), HRTIMER_MODE_REL);
else //遇到偶数,延时0.5s
hrtimer_start(&mytimer_timer, ktime_set(0, 500000000), HRTIMER_MODE_REL);
//由于这里返回的是“HRTIMER_NORESTART”,所以要让定时器再次运行,需要在上面手动调用“hrtimer_start”
return HRTIMER_NORESTART;
}
/* 初始化工作队列和定时器 */
static int mytimer_init(void)
{
//由于定时器任务只实现单一功能,而且没有并发,所以创建一个单线程工作队列
mytimer_workqueue = create_singlethread_workqueue("mytimer");
if(!mytimer_workqueue) {
printk("Unable to create mytimer_workqueue! \n");
return -1; //如果创建失败,则退出
}
//创建具体任务,并绑定任务回调函数
INIT_WORK(&mytimer_work, mytimer_work_function);
//初始化定时器
hrtimer_init(&mytimer_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
//绑定定时器回调函数
mytimer_timer.function = mytimer_timer_function;
return 0;
}
开启定时器之后,会得到如下打印结果:
奇数[1],延时1.5s
(间隔1.5s)
偶数[2],延时0.5s
(间隔0.5s)
奇数[3],延时1.5s
.
.
.
偶数[10],延时0.5s
(间隔0.5s)
奇数[1],延时1.5s
.
.
.
循环直到关闭定时器!