閱讀744 返回首頁    go 阿裏雲 go 技術社區[雲棲]


linux驅動開發--內核定時器

1、內核定時器

時鍾中斷:由係統的定時硬件以周期性的時間間隔發生,這個間隔(也就是頻率)由內核根據常數HZ來確定。
HZ常數:她是一個與體係結構無關的常數,可以配置50-1200之間,可以在內核中配置
tick:她是HZ的倒數,也就是每發生一次硬件定時器中斷的事件間隔。如HZ為200,tick為5毫秒。
jiffies核心變數:它是linux核心變數(32位變數,unsigned long),它被用記錄自開機以來,已經過多少個tick。每發生一次硬件定時器中斷,jiffies變數會被加1。

定時器的作用:
內核定時器由用戶控製某個函數(定時器函數)來特定的在未來某個時刻執行。
內核定時器注冊的處理函數隻執行一次(不是循環執行的)。

內核定時器定義:
在<linux/timer.h>中定義

struct timer_list
{
	struct list_head entry;//內核使用
	unsigned long expires;//超時時間jiffies的值
	void (*function)(unsigned long);//超時處理函數
	unsigned long data;//內核調用超時處理函數時傳遞給它的參數
	struct tvec_base *base;//內核使用
};

內核定時器操作:
靜態初始化
TIMER_INITIALIZER(_function, _expires, _data)
_function:定時器處理函數
_expires:定時器超時jiffies值
_data:傳遞給定時器處理函數的參數

定義定時器
DEFINE_TIMER(_name, _function, _expires, _data);
_name:待定義的內核定時器變量名稱
_function:定時器處理函數
_expires:定時器超時jiffies值
_data:傳遞給定時器處理函數的參數

動態初始化
void init_timer(struct timer_list *timer);
timer:待初始化的內核定時器
添加定時器
void add_timer(struct timer_list *timer);
timer:待初始化的內核定時器
刪除定時器
該函數是在定時器超時前將定時器刪除
實際上,在定時器超時後,係統會自動將其刪除
void del_timer(struct timer_list *timer);
timer:待初始化的內核定時器

修改定時器
該函數實際相當於del_timer(), timer->expires=expires, add_timer()三個步驟
int mod_timer(struct timer_list *timer, unsigned long expires);
timer:待修改的內核定時器
expires:待修改內核定時器的新超時值
返回:返回0表示定時器處於不活動狀態,返回1表示定時器處於活動狀態

2、實例代碼:

/**
*Copyright (c) 2013.TianYuan
*All rights reserved.
*
*文件名稱: kerneltimer.c
*文件標識: 內核定時器 
*
*當前版本:1.0
*作者:wuyq 
*
*取代版本:xxx
*原作者:xxx
*完成日期:2013-11-25
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>

MODULE_LICENSE("GPL");

/*定時器變量*/
struct timer_list bigdog_timer;

#define BARK_TIMER	5/*定時器時間間隔*/
#define BARK_COUNTS	10/*次數*/
void bigdog_timer_handler(unsigned long data)
{
	/*記錄該函數被調用的次數*/
	static int bark_count = 0;
	
	printk("wangwang~~~~~~~~~%ld!\n", data);
	if(bark_count < BARK_COUNTS){
		bigdog_timer.expires = jiffies+HZ*BARK_TIMER;
		bigdog_timer.data++;
		add_timer(&bigdog_timer);
		
		bark_count++;
	}
}

int __init kerneltimer_init(void)
{
	/*初始化定時器變量*/
	init_timer(&bigdog_timer);
	bigdog_timer.expires = jiffies+HZ*BARK_TIMER;//超時時間.安裝模塊時間之後5秒
	bigdog_timer.function = bigdog_timer_handler;//處理函數;函數指針:void (*fun)(unsigned long)
	bigdog_timer.data = 100;
	
	/*添加定時器到內核中去*/
	add_timer(&bigdog_timer);
	printk("add_timer() Done!\n");
	
	return 0;
}

void __exit kerneltimer_exit(void)
{
	/*從內核中刪除指定的定時器*/
	del_timer(&bigdog_timer);
	printk("del_timer() done!\n");
}

module_init(kerneltimer_init);
module_exit(kerneltimer_exit);

KERNELDIR ?=/root/Desktop/work/ldd3/linux-2.6.31_TX2440A
PWD := $(shell pwd)
obj-m += kerneltimer.o

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	@rm -f *.o *.ord* *.sy* *.mod.* *.ko



最後更新:2017-04-03 12:54:00

  上一篇:go 最近分布式係統開發小結
  下一篇:go linux驅動開發--字符設備:動態分配設備號