天天看點

Linux核心擷取年月日,Linux核心中擷取目前時間

它是非常不可能一個驅動會需要知道牆上時鐘時間, 以月, 天, 和小時來表達的; 這個資訊常常隻對使用者程式需要, 例如 cron

和 syslogd. 處理真實世界的時間常常最好留給使用者空間, 那裡的 C 庫提供了更好的支援; 另外,

這樣的代碼常常太政策相關以至于不屬于核心. 有一個核心函數轉變一個牆上時鐘時間到一個 jiffies 值, 但是:

#include unsigned long mktime (unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec);

重複:直接在驅動中處理牆上時鐘時間往往是一個在實作政策的信号, 并且應當是以而被置疑.

雖然你不會一定處理人可讀的時間表示, 有時你需要甚至在核心空間中處理絕對時間. 為此,

輸出了 do_gettimeofday

函數. 當被調用時, 它填充一個 struct timeval 指針 -- 和在 gettimeofday 系統調用中使用的相同 --

使用類似的秒和毫秒值. do_gettimeofday 的原型是:

#include void do_gettimeofday(struct timeval *tv);

這段源代碼聲明 do_gettimeofday 有" 接近毫秒的精度", 因為它詢問時間硬體目前 jiffy 多大比例已經流失.

這個精度每個體系都不同, 但是, 因為它依賴實際使用中的硬體機制. 例如, 一些 m68knommu 處理器, Sun3 系統,

和其他 m68k 系統不能提供大于 jiffy 的精度. Pentium 系統, 另一方面, 提供了非常快速和精确的小于嘀哒的測量,

通過讀取本章前面描述的時戳計數器.

目前時間也可用( 盡管使用 jiffy 的粒度 )來自 xtime 變量, 一個 struct timespec 值.

不鼓勵這個變量的直接使用, 因為難以原子地同時存取這 2 個字段. 是以, 核心提供了實用函數

current_kernel_time:

#include struct timespec current_kernel_time(void);

用來以各種方式擷取目前時間的代碼, 可以從由 O' Reilly 提供的 FTP 網站上的源碼檔案的 jit ("just in

time") 子產品獲得. jit 建立了一個檔案稱為 /proc/currentime, 當讀取時, 它以 ASCII

碼傳回下列項:

目前的 jiffies 和 jiffies_64 值, 以 16 進制數的形式.

如同 do_gettimeofday 傳回的相同的目前時間.

由 current_kernel_time 傳回的 timespec.

我們選擇使用一個動态的 /proc 檔案來保持樣闆代碼為最小 -- 它不值得建立一整個裝置隻是傳回一點兒文本資訊.

這個檔案連續傳回文本行隻要這個子產品加載着; 每次 read 系統調用收集和傳回一套資料, 為更好閱讀而組織為 2 行.

無論何時你在少于一個時鐘嘀哒内讀多個資料集, 你将看到 do_gettimeofday 之間的差别, 它詢問硬體,

并且其他值僅在時鐘嘀哒時被更新.

phon% head -8 /proc/currentime 0x00bdbc1f 0x0000000100bdbc1f 1062370899.630126 1062370899.629161488 0x00bdbc1f 0x0000000100bdbc1f 1062370899.630150 1062370899.629161488 0x00bdbc20 0x0000000100bdbc20 1062370899.630208 1062370899.630161336 0x00bdbc20 0x0000000100bdbc20 1062370899.630233 1062370899.630161336

在上面的螢幕快照中, 由 2 件有趣的事情要注意. 首先, 這個 current_kernel_time 值,

盡管以納秒來表示, 隻有時鐘嘀哒的粒度; do_gettimeofday 持續報告一個稍晚的時間但是不晚于下一個時鐘嘀哒. 第二,

這個 64-位的 jiffies 計數器有 高 32-位字集合的最低有效位. 這是由于 INITIAL_JIFFIES 的預設值,

在啟動時間用來初始化計數器, 在啟動時間後幾分鐘内強加一個低字溢出來幫助探測與這個剛好溢出相關的問題.

這個在計數器中的初始化偏好沒有效果, 因為 jiffies 與牆上時鐘時間無關. 在 /proc/uptime 中,

這裡核心從計數器中抽取 uptime, 初始化偏好在轉換前被去除.

1、使用rtc裝置,這個時鐘可以用于各種模式

2、借鑒系統調用adjtimex

這裡使用第二種方式

系統調用adjtimex

一直跟下去,會發現最後調用

void do_gettimeofday(struct timeval *tv)

那麼直接使用do_gettimeofday,能夠得到struct timeval

struct timeval {

time_t tv_sec;

suseconds_t tv_usec;

};

那麼就需要将這個tv_sec,即1970年開始至今的秒數轉換為年月日時分秒

其實核心已經有這樣的函數

void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)

唯一的不足是轉換得到的是UTC時間,同中原標準時間差8小時。要想達到使用者态localtime()的效果,必須獲得/etc/localtime

中的時區資訊。

示例代碼:

#include

#include

#include

struct timex txc;

struct rtc_time tm;

do_gettimeofday(&(txc.time));

rtc_time_to_tm(txc.time.tv_sec,&tm);

printk(“UTC time :%d-%d-%d %d:%d:%d /n”,tm.tm_year+1900,tm.tm_mon,

tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);