在編寫驅動的過程中,可能會需要定期輪詢某個硬件的狀態或情況,此時可以使用延時工作隊列或定時器,為了方便日后工作,特地去了解定時器的使用方式。
#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");
|