自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux驅(qū)動(dòng)技術(shù)(七) _內(nèi)核定時(shí)器與延遲工作

系統(tǒng) Linux 系統(tǒng)運(yùn)維
軟件上的定時(shí)器最終要依靠硬件時(shí)鐘來(lái)實(shí)現(xiàn),簡(jiǎn)單的說(shuō),內(nèi)核會(huì)在時(shí)鐘中斷發(fā)生后檢測(cè)各個(gè)注冊(cè)到內(nèi)核的定時(shí)器是否到期,如果到期,就回調(diào)相應(yīng)的注冊(cè)函數(shù),將其作為中斷底半部來(lái)執(zhí)行。實(shí)際上,時(shí)鐘中斷處理程序會(huì)觸發(fā)TIMER_SOFTIRQ軟中斷,運(yùn)行當(dāng)前處理器上到期的所有定時(shí)器。

[[184387]]

內(nèi)核定時(shí)器

軟件上的定時(shí)器最終要依靠硬件時(shí)鐘來(lái)實(shí)現(xiàn),簡(jiǎn)單的說(shuō),內(nèi)核會(huì)在時(shí)鐘中斷發(fā)生后檢測(cè)各個(gè)注冊(cè)到內(nèi)核的定時(shí)器是否到期,如果到期,就回調(diào)相應(yīng)的注冊(cè)函數(shù),將其作為中斷底半部來(lái)執(zhí)行。實(shí)際上,時(shí)鐘中斷處理程序會(huì)觸發(fā)TIMER_SOFTIRQ軟中斷,運(yùn)行當(dāng)前處理器上到期的所有定時(shí)器。

設(shè)備驅(qū)動(dòng)程序如要獲得時(shí)間信息以及需要定時(shí)服務(wù),都可以使用內(nèi)核定時(shí)器。

jiffies

要說(shuō)內(nèi)核定時(shí)器,首先就得說(shuō)說(shuō)內(nèi)核中關(guān)于時(shí)間的一個(gè)重要的概念:jiffies變量,作為內(nèi)核時(shí)鐘的基礎(chǔ),jiffies每隔一個(gè)固定的時(shí)間就會(huì)增加1,稱為增加一個(gè)節(jié)拍,這個(gè)固定間隔由定時(shí)器中斷來(lái)實(shí)現(xiàn),每秒中產(chǎn)生多少個(gè)定時(shí)器中斷,由在<linux/param.h>中定義的HZ宏來(lái)確定,如此,可以通過(guò)jiffies獲取一段時(shí)間,比如jiffies/HZ表示自系統(tǒng)啟動(dòng)的秒數(shù)。下兩秒就是(jiffies/HZ+2),內(nèi)核中用jiffies來(lái)計(jì)時(shí),秒轉(zhuǎn)換成的jiffies:seconds*HZ,所以以jiffiy為單位,以當(dāng)前時(shí)刻為基準(zhǔn)計(jì)時(shí)2秒:(jiffies/HZ+2)*HZ=jiffies+2*HZ如果要獲取當(dāng)前時(shí)間,可以使用do_gettimeofday(),該函數(shù)填充一個(gè)struct timeval結(jié)構(gòu),有著接近微妙的分辨率。

  1. //kernel/time/timekeeping.c 
  2. /** 
  3. * do_gettimeofday - Returns the time of day in a timeval 
  4. * @tv:         pointer to the timeval to be set 
  5. * NOTE: Users should be converted to using getnstimeofday() 
  6. */ 
  7. void do_gettimeofday(struct timeval *tv)  

驅(qū)動(dòng)程序?yàn)榱俗層布凶銐虻臅r(shí)間完成一些任務(wù),常常需要將特定的代碼延后一段時(shí)間來(lái)執(zhí)行,根據(jù)延時(shí)的長(zhǎng)短,內(nèi)核開發(fā)中使用長(zhǎng)延時(shí)和短延時(shí)兩個(gè)概念。長(zhǎng)延時(shí)的定義為:延時(shí)時(shí)間>多個(gè)jiffies,實(shí)現(xiàn)長(zhǎng)延時(shí)可以用查詢jiffies的方法:

  1. time_before(jiffies, new_jiffies); 
  2. time_after(new_jiffiesmjiffies); 

**短延時(shí)的定義為:延遲事件接近或短于一個(gè)jiffy,實(shí)現(xiàn)短延時(shí)可以調(diào)用

  1. udelay(); 
  2. mdelay(); 

這兩個(gè)函數(shù)都是忙等待函數(shù),大量消耗CPU時(shí)間,前者使用軟件循環(huán)來(lái)延遲指定數(shù)目的微妙數(shù),后者使用前者的嵌套來(lái)實(shí)現(xiàn)毫秒級(jí)的延時(shí)。

定時(shí)器

驅(qū)動(dòng)可以注冊(cè)一個(gè)內(nèi)核定時(shí)器,來(lái)指定一個(gè)函數(shù)在未來(lái)某個(gè)時(shí)間來(lái)執(zhí)行。定時(shí)器從注冊(cè)到內(nèi)核開始計(jì)時(shí),達(dá)到指定的時(shí)間后會(huì)執(zhí)行注冊(cè)的函數(shù)。即超時(shí)值是一個(gè)jiffies值,當(dāng)jiffies值大于timer->expires時(shí),timer->function就會(huì)被執(zhí)行。API如下

  1. //定一個(gè)定時(shí)器 
  2.  
  3. struct timer_list my_timer;//初始化定時(shí)器 
  4.  
  5. void init_timer(struct timer_list *timer); 
  6. mytimer.function = my_function; 
  7. mytimer.expires = jiffies +HZ;//增加定時(shí)器 
  8.  
  9. void add_timer(struct timer_list *timer);//刪除定時(shí)器 
  10.  
  11. int del_tiemr(struct timer_list *timer);  

實(shí)例

  1. static struct timer_list tm; 
  2. struct timeval oldtv;void callback(unsigned long arg){ 
  3.     struct timeval tv; 
  4.     char *strp = (char*)arg; 
  5.     do_gettimeofday(&tv); 
  6.     printk("%s: %ld, %ld\n", __func__, 
  7.         tv.tv_sec - oldtv.tv_sec, 
  8.         tv.tv_usec- oldtv.tv_usec); 
  9.     oldtv = tv; 
  10.     tm.expires = jiffies+1*HZ; 
  11.     add_timer(&tm); 
  12. static int __init demo_init(void){ 
  13.     init_timer(&tm); 
  14.     do_gettimeofday(&oldtv); 
  15.     tm.function= callback; 
  16.     tm.data    = (unsigned long)"hello world"
  17.     tm.expires = jiffies+1*HZ; 
  18.     add_timer(&tm); 
  19.     return 0; 
  20.  

延遲工作

除了使用內(nèi)核定時(shí)器完成定時(shí)延遲工作,Linux內(nèi)核還提供了一套封裝好的"快捷方式"-delayed_work,和內(nèi)核定時(shí)器類似,其本質(zhì)也是利用工作隊(duì)列和定時(shí)器實(shí)現(xiàn), 

  1. //include/linux/workqueue.h 
  2.  struct work_struct {            
  3.          atomic_long_t data; 
  4.          struct list_head entry; 
  5.          work_func_t func; 
  6.  #ifdef CONFIG_LOCKDEP 
  7.          struct lockdep_map lockdep_map; 
  8.  #endif 
  9.  }; 
  10.  struct delayed_work {              114         struct work_struct work
  11.          struct timer_list timer; 
  12.  
  13.   /* target workqueue and CPU ->timer uses to queue ->work */ 
  14.          struct workqueue_struct *wq; 
  15.          int cpu; 
  16.  };  

--103-->需要延遲執(zhí)行的函數(shù), typedef void (work_func_t)(struct work_struct work);

至此,我們可以使用一個(gè)delayed_work對(duì)象以及相應(yīng)的調(diào)度API實(shí)現(xiàn)對(duì)指定任務(wù)的延時(shí)執(zhí)行

  1. //注冊(cè)一個(gè)延遲執(zhí)行 
  2.  
  3. 591 static inline bool schedule_delayed_work(struct delayed_work *dwork,unsigned long delay)//注銷一個(gè)延遲執(zhí)行 
  4. 2975 bool cancel_delayed_work(struct delayed_work *dwork)     

和內(nèi)核定時(shí)器一樣,延遲執(zhí)行只會(huì)在超時(shí)的時(shí)候執(zhí)行一次,如果要實(shí)現(xiàn)循環(huán)延遲,只需要在注冊(cè)的函數(shù)中再次注冊(cè)一個(gè)延遲執(zhí)行函數(shù)。

  1. schedule_delayed_work(&work,msecs_to_jiffies(poll_interval)); 
責(zé)任編輯:龐桂玉 來(lái)源: 嵌入式Linux中文站
相關(guān)推薦

2009-11-11 10:14:10

linux定時(shí)器操作系統(tǒng)

2010-01-18 10:05:20

FreeBSD內(nèi)核

2023-08-02 09:26:03

軟件定時(shí)器鴻蒙

2023-01-10 13:53:21

Linux定時(shí)器

2018-11-02 08:10:58

Linuxsystemd定時(shí)器

2021-08-11 10:10:26

Linux定時(shí)器數(shù)組

2021-08-03 14:33:53

cron定時(shí)器Linux命令

2016-12-15 14:55:31

Linux定時(shí)延時(shí)

2023-12-11 09:50:35

Linux定時(shí)器

2021-04-09 16:39:41

鴻蒙HarmonyOS應(yīng)用

2010-07-28 15:56:22

FlexTimer定時(shí)

2021-06-09 09:48:01

鴻蒙HarmonyOS應(yīng)用

2021-05-27 09:43:56

鴻蒙HarmonyOS應(yīng)用

2024-06-03 00:00:20

.NET定時(shí)器

2011-02-23 10:20:45

2009-04-12 08:51:50

Symbian諾基亞移動(dòng)OS

2021-03-31 08:33:17

SysTick定時(shí)器SysTick定時(shí)器

2013-07-29 10:10:40

TCP協(xié)議TCP定時(shí)器TCP

2011-04-21 10:49:28

Linux時(shí)間定時(shí)器

2022-11-02 11:40:16

Flowable定時(shí)器流程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)