在编写驱动的过程中,可能会需要定期轮询某个硬件的状态或情况,此时可以使用延时工作队列或定时器,为了方便日后工作,特地去了解定时器的使用方式。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h> // timer
#include <asm/uaccess.h> // jiffies
#define __ISDEBUG__
#ifdef __ISDEBUG__
#define dprintk(format,...) printk("[debug][%s] "format" <--\n",strrchr(__FILE__,'/') ? strrchr(__FILE__,'/') : __FILE__ ,##__VA_ARGS__)
#else
#define dprintk(format,...)
#endif
#define iprintk(format,...) printk("[info][%s] "format" <--\n",strrchr(__FILE__,'/') ? strrchr(__FILE__,'/') : __FILE__ ,##__VA_ARGS__)
volatile struct timeval time1, time2;
/*
* jiffies的相互转换函数:
* unsigned int jiffies_to_msecs(unsigned long);
* unsigned int jiffies_to_usecs(unsigned long);
* unsigned long msecs_to_jiffies(unsigned int);
* unsigned long usecs_to_jiffies(unsigned int);
*/
/*
* 定时器相关的接口
* init_timer(struct timer_list*):定时器初始化函数;
* add_timer(struct timer_list*):往系统添加定时器;
* mod_timer(struct timer_list *, unsigned long jiffier_timerout):修改定时器的超时时间为jiffies_timerout;
* timer_pending(struct timer_list *):定时器状态查询,如果在系统的定时器列表中则返回1,否则返回0;
* del_timer(struct timer_list*):删除定时器。
*/
/*
* 函数: timer_start
* 参数: msecs:毫秒
function:回调函数(void timer_function(int para)) 若为空则删除定时器
para:传给回调的参数
* 返回: 无
* 说明: 这种定时器方式并不是很精确,只生效一次
* 头文件: #include <linux/timer.h> // timer #include <asm/uaccess.h> // jiffies
*/
void timer_start(int msecs, void *function, int para)
{
static struct timer_list timer;
if(NULL == function)
{
del_timer(&timer); // 删除定时器
return ;
}
init_timer(&timer);
timer.data = para;
// timer.expires = jiffies + ((msecs * 1000) * HZ); // 另外一种方式
timer.expires = jiffies + msecs_to_jiffies(msecs); // 毫秒
timer.function = function;
add_timer(&timer);
return ;
}
void timer_function(int para)
{
do_gettimeofday(&time2);
printk("time.s:%ld time.u:%ld\n", time2.tv_sec - time1.tv_sec, time2.tv_usec - time1.tv_usec);
printk("time1.s:%ld time1.u:%ld\ntime2.s:%ld time2.u:%ld\n\n", time1.tv_sec, time1.tv_usec, time2.tv_sec, time2.tv_usec);
do_gettimeofday(&time1);
timer_start(5000, timer_function, para++);
}
static int __init zhc_drivers_init(void)
{
iprintk("__TIME__ : %s", __TIME__);
do_gettimeofday(&time1);
timer_start(5000, timer_function, 10);
return 0;
}
static void __exit zhc_drivers_exit(void)
{
iprintk();
timer_start(0, NULL, 0);
}
module_init(zhc_drivers_init);
module_exit(zhc_drivers_exit);
MODULE_LICENSE("GPL v2");
|