linux內(nèi)核(驅(qū)動(dòng))編程中的延時(shí)函數(shù)都有哪些

摘要:Linux內(nèi)核或驅(qū)動(dòng)程序中經(jīng)常會使用到一些延時(shí)函數(shù),在這段時(shí)間里硬件設(shè)備可以完成相關(guān)的工作。本文主要講述linux中經(jīng)常使用到的納秒級、毫秒級及秒級的延時(shí)函數(shù)及其使用方法和場景。

1、時(shí)間度量

先介紹兩個(gè)有用的全局變量:HZjiffies

  • HZ是Linux內(nèi)核中的一個(gè)重要全局變量,表示系統(tǒng)在1秒鐘的時(shí)間里系統(tǒng)時(shí)鐘中斷(由硬件定時(shí)器產(chǎn)生)發(fā)生的次數(shù)。它一般取值為1000,但不同硬件平臺有不同取值。
  • 系統(tǒng)初始化的時(shí)候,將一個(gè)全局計(jì)數(shù)器jiffies設(shè)置為0,此后每當(dāng)時(shí)鐘中斷發(fā)生一次,系統(tǒng)就將jiffies的值加1,所以這個(gè)值記錄了系統(tǒng)啟動(dòng)以來經(jīng)歷的時(shí)間。
  • 比較jiffies的值可以使用Linux定義的幾個(gè)宏:
/* 當(dāng)a>b時(shí)返回true,否則返回false*/
#define time_after(a,b) ( typecheck(unsigned long,a) &&\
                          typecheck(unsigned long,a) &&\
                          ((long)(b)-(long)(a) < 0) )

/* 當(dāng)a<b時(shí)返回true,否則返回false*/
#define time_before(a,b)    time_after(b,a) 

/* 當(dāng)a>=b時(shí)返回true,否則返回false*/
#define time_after_eq(a,b)  ( typecheck(unsigned long,a) &&\
                          typecheck(unsigned long,a) &&\
                          ((long)(a)-(long)(b) >= 0) )
/* 當(dāng)a<=b時(shí)返回true,否則返回false*/
#define time_before_eq(a,b) time_after_eq(b,a)  

2、時(shí)間延時(shí)

2.1短延時(shí)

  • 在設(shè)備驅(qū)動(dòng)程序處理硬件讀寫時(shí),往往需要延時(shí)一段短時(shí)間以使設(shè)備成功完成某些操作,因?yàn)镃PU指令執(zhí)行速度遠(yuǎn)大于硬件設(shè)備,不延時(shí)的話可能會和CPU速度匹配不上。
  • Linux內(nèi)核提供了2個(gè)函數(shù)來分別完成不同量級的延時(shí)(延時(shí)期間程序忙等待):
static inline void ndelay(unsigned long x);
static inline void udelay(unsigned long x);

這些函數(shù)的實(shí)現(xiàn)依賴于具體的平臺,可能有的平臺硬件上根本實(shí)現(xiàn)不了納秒級的延時(shí),此時(shí)內(nèi)核會使用一個(gè)有限循環(huán)函數(shù)來達(dá)到此目的:

static inline void ndelay(unsigned long x)
{
    ...
    /*根據(jù)CPU頻率及x的值計(jì)算出count的值*/
    while(count)
    {
        count--;
    }
}

2.2中等延時(shí)

一般稱毫秒級的延時(shí)為中等延時(shí),內(nèi)核實(shí)現(xiàn)了3個(gè)函數(shù)(延時(shí)期間程序進(jìn)入睡眠狀態(tài)):

/* 延時(shí)msecs毫秒,程序進(jìn)入睡眠,且不可被打斷 */
void msleep(unsigned int msecs);

/* 延時(shí)msecs毫秒,程序進(jìn)入睡眠,但可以被打斷 */
unsigned long msleep_interruptible(unsigned int msecs);

/* 延時(shí)msecs毫秒,程序進(jìn)入睡眠,且不可被打斷 */
static inline void ssleep(unsigned int secs);

2.3長延時(shí)

長延時(shí)表示驅(qū)動(dòng)程序要延時(shí)相對較長的一段時(shí)間,方法主要使比較當(dāng)前jiffies值和目標(biāo)jiffies值,它是忙等待的。下例實(shí)現(xiàn)了延時(shí)10秒的目的:

unsigned long timeout = jiffies + 10*HZ;
while(time_before(jiffies, timeout));
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言: Linux中如何對時(shí)間進(jìn)行管理?時(shí)鐘節(jié)拍的概念及延時(shí)函數(shù)的用法很多同學(xué)都用不好,下面我給大家總結(jié)一下。 一...
    華清遠(yuǎn)見2閱讀 608評論 0 0
  • 進(jìn)程 創(chuàng)建 創(chuàng)建進(jìn)程用fork()函數(shù)。fork()為子進(jìn)程創(chuàng)建新的地址空間并且拷貝頁表。子進(jìn)程的虛擬地址空間...
    梅花怒閱讀 2,077評論 0 7
  • Linux time system Linux中跟時(shí)間有關(guān)的函數(shù)變量有很多,但是對開發(fā)者來說無非就是用了計(jì)時(shí)/延時(shí)...
    Creator_Ly閱讀 1,855評論 0 5
  • 第六章 高級字符驅(qū)動(dòng)程序操作 ioctl方法: 為了保證ioctl命令的唯一性,對于命令的定義使用了4個(gè)位字段...
    xiaozi63閱讀 727評論 0 0
  • 在為操作系統(tǒng)編寫驅(qū)動(dòng)設(shè)備時(shí),因?yàn)樯婕暗街袛?、多任?wù)和多處理器SMP的處理,所以內(nèi)核提供了諸如原子操作、信號量、完成...
    Leon_Geo閱讀 590評論 0 0

友情鏈接更多精彩內(nèi)容