Linux內(nèi)核定時(shí)器
在Linux內(nèi)核中,也可以通過(guò)定時(shí)器來(lái)完成定時(shí)功能。但和單片機(jī)不同的是,Linux內(nèi)核定時(shí)器是一種基于未來(lái)時(shí)間點(diǎn)的計(jì)時(shí)方式,它以當(dāng)前時(shí)刻為啟動(dòng)的時(shí)間點(diǎn),以未來(lái)的某一時(shí)刻為終止點(diǎn),類似于我們的鬧鐘。
當(dāng)內(nèi)核定時(shí)器定時(shí)時(shí)間到達(dá)時(shí),會(huì)進(jìn)入用戶指定的函數(shù),相當(dāng)于軟中斷。內(nèi)核定時(shí)器完成注冊(cè)啟動(dòng)后,僅執(zhí)行一次后就不會(huì)重復(fù)執(zhí)行(即超時(shí)候會(huì)自動(dòng)關(guān)閉),若需要重復(fù)執(zhí)行則需要手動(dòng)再次啟動(dòng)(即修改超時(shí)時(shí)間)。
Linux內(nèi)核定時(shí)器相關(guān)函數(shù)位置:include/linux/timer.h
1.相關(guān)結(jié)構(gòu)體
??在使用內(nèi)核定時(shí)器時(shí),我們需要關(guān)心的相關(guān)結(jié)構(gòu)體及其成員:
struct timer_list {
struct list_head entry;
unsigned long expires; /* 定時(shí)器時(shí)鐘節(jié)拍*/
struct tvec_base *base;
void (*function)(unsigned long); /*定時(shí)器工作函數(shù) */
unsigned long data; /*傳給定時(shí)器工作函數(shù)的參數(shù) */
};
?在Linux內(nèi)核中,有一個(gè)全局變量jiffies用來(lái)記錄時(shí)鐘節(jié)拍,每當(dāng)時(shí)鐘中斷觸發(fā)一次,jiffies就會(huì)+1。因此jiffies變量記錄了系統(tǒng)從啟動(dòng)開始時(shí)鐘中斷觸發(fā)的次數(shù)。我們由此可以利用jiffies來(lái)計(jì)算驅(qū)動(dòng)程序運(yùn)行時(shí)長(zhǎng)。jiffies每秒增加HZ次,因此jiffies+1的時(shí)長(zhǎng)有HZ決定。當(dāng)HZ=100時(shí),jiffies+1的時(shí)長(zhǎng)則為10ms。在Linux3.5的內(nèi)核中HZ值默認(rèn)為200,即jiffies+1的時(shí)長(zhǎng)則為5ms。

2.相關(guān)函數(shù)
2.1 定時(shí)器初始化init_timer()
#define init_timer(timer)
函數(shù)功能: 初始化定時(shí)
形參: 定時(shí)器結(jié)構(gòu)體
2.2 啟動(dòng)定時(shí)器add_timer()
void add_timer(struct timer_list *timer)
函數(shù)功能: 啟動(dòng)定時(shí)器
形參: 定時(shí)器結(jié)構(gòu)體
2.3 修改定時(shí)時(shí)間mod_timer()
int mod_timer(struct timer_list *timer, unsigned long expires)
函數(shù)功能: 修改定時(shí)器時(shí)間
形參: timer – 定時(shí)器結(jié)構(gòu)體
???expires --定時(shí)時(shí)間( 以時(shí)鐘節(jié)拍填入)
??注意:expires 填寫是基于jiffies+延時(shí)時(shí)間
2.4毫秒轉(zhuǎn)為時(shí)鐘節(jié)拍 msecs_to_jiffies()
unsigned long msecs_to_jiffies(const unsigned int m)
函數(shù)功能: 將毫秒時(shí)間轉(zhuǎn)換為時(shí)鐘節(jié)拍數(shù)
形參: m – 毫秒時(shí)間
返回值: – 返回節(jié)拍數(shù)
2.5微秒轉(zhuǎn)為時(shí)鐘節(jié)拍 usecs_to_jiffies()
unsigned long usecs_to_jiffies(const unsigned int u)
函數(shù)功能: 將微秒時(shí)間轉(zhuǎn)換為時(shí)鐘節(jié)拍數(shù)
形參: m – 位秒時(shí)間
返回值: – 返回節(jié)拍數(shù)
2.6關(guān)閉定時(shí)器
int del_timer(struct timer_list *timer)
函數(shù)功能:關(guān)閉定時(shí)器(停用一個(gè)定時(shí)器)
define del_timer_sync(t)
函數(shù)功能:關(guān)閉定時(shí)器(停用一個(gè)定時(shí)器),多處理器使用。如果編內(nèi)核時(shí)不支持 SMP(多處理器), del_timer_sync()和 del_timer()等價(jià)
2.7 獲取jiffies時(shí)間
#include
u64 get_jiffies_64(void)
函數(shù)功能: 獲取jiffies時(shí)間
返回值: 返回時(shí)鐘節(jié)拍jiffies
2.8 獲取內(nèi)核高精度時(shí)間
ktime_t ktime_get(void)
函數(shù)功能: 獲取內(nèi)核高精度時(shí)間
返回值: ktime_t – 共用體類型
union ktime {
s64 tv64;
#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
struct
{
# ifdef __BIG_ENDIAN
s32 sec, nsec;
# else
s32 nsec, sec;
# endif
} tv;
#endif
};
2.9 時(shí)間轉(zhuǎn)換函數(shù)
s64 ktime_to_ms(const ktime_t kt) /* 將獲取的系統(tǒng)時(shí)鐘轉(zhuǎn)換為ms單位*/
s64 ktime_to_us(const ktime_t kt) /* 將獲取的系統(tǒng)時(shí)鐘轉(zhuǎn)換為us單位*/
/將獲取的時(shí)間轉(zhuǎn)換為時(shí)鐘結(jié)構(gòu)體/
struct timeval ktime_to_timeval(const ktime_t kt)
struct timespec ktime_to_timespec(const ktime_t kt)
3.內(nèi)核定時(shí)器示例
??內(nèi)核定時(shí)器使用步驟:
- 初始化內(nèi)核定時(shí)器init_timer,設(shè)置超時(shí)時(shí)間,編寫內(nèi)核定時(shí)工作函數(shù);
- 啟動(dòng)定時(shí)器add_timer;
- 若需要重復(fù)定時(shí),則需要在定時(shí)器工作函數(shù)中修改超時(shí)時(shí)間mod_timer
#include
#include
#include
#include
#include
struct timer_list timer;
/*定時(shí)器工作函數(shù)*/
void timer_work(unsigned long data)
{
ktime_t time1;
printk("定時(shí)器時(shí)間到!data=%ld,",data);
time1=ktime_get();
printk("定時(shí)時(shí)間:%llu \n",ktime_to_ms(time1));
mod_timer(&timer,jiffies+msecs_to_jiffies(2000));/*修改定時(shí)時(shí)間*/
}
static int __init wbyq_timer_init(void)
{
timer.expires=jiffies+msecs_to_jiffies(1000);/*定時(shí)時(shí)間*/
timer.function=timer_work;/*定時(shí)器工作函數(shù)*/
timer.data=666;/*傳給定時(shí)器工作函數(shù)參數(shù),選填*/
init_timer(&timer);/*初始化定時(shí)器*/
add_timer(&timer);/*啟動(dòng)定時(shí)器*/
return 0;
}
/*驅(qū)動(dòng)釋放*/
static void __exit wbyq_timer_cleanup(void)
{
del_timer_sync(&timer);//關(guān)閉定時(shí)器
printk("驅(qū)動(dòng)出口,驅(qū)動(dòng)注銷成功\n");
}
module_init(wbyq_timer_init);//驅(qū)動(dòng)入口函數(shù)
module_exit(wbyq_timer_cleanup);//驅(qū)動(dòng)出口函數(shù)
MODULE_LICENSE("GPL");//驅(qū)動(dòng)注冊(cè)協(xié)議
MODULE_AUTHOR("it_ashui");
MODULE_DESCRIPTION("Exynos4 timer Driver");

審核編輯:湯梓紅
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1416瀏覽量
41417 -
Linux
+關(guān)注
關(guān)注
87文章
11509瀏覽量
213726 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3298瀏覽量
118869
發(fā)布評(píng)論請(qǐng)先 登錄
Linux驅(qū)動(dòng)開發(fā)-內(nèi)核定時(shí)器
芯靈思SinlinxA33開發(fā)板Linux內(nèi)核定時(shí)器編程
「正點(diǎn)原子Linux連載」第五十章Linux內(nèi)核定時(shí)器實(shí)驗(yàn)
「正點(diǎn)原子Linux連載」第五十章Linux內(nèi)核定時(shí)器實(shí)驗(yàn)
【正點(diǎn)原子FPGA連載】第三十二章Linux內(nèi)核定時(shí)器實(shí)驗(yàn)-領(lǐng)航者ZYNQ之linux開發(fā)指南
ARM Cortex-M0+內(nèi)核定時(shí)器
Linux內(nèi)核定時(shí)器的相關(guān)資料分享
Linux內(nèi)核定時(shí)器的相關(guān)資料分享
Win32s下內(nèi)核定時(shí)器的使用
LINUX內(nèi)核定時(shí)器(高精度&低精度)
Linux內(nèi)核定時(shí)器的詳細(xì)資料概述

慕課嵌入式開發(fā)及應(yīng)用(第三章.ARM Cortex-M0+內(nèi)核定時(shí)器 (Systic)

Linux內(nèi)核時(shí)鐘系統(tǒng)和定時(shí)器實(shí)現(xiàn)

評(píng)論