Linuxカーネルで現在の時刻を取得
7.2.現在の時刻を知る
カーネルコードはjifiesの値を表示することによって、現在の時間の表現を常に取得することができる.しばしば、この値は、最後の起動からの時間のみを表すが、この事実は、システムのuptimeに制限されているため、駆動には関係ない.図示するように、ドライバはjiffiesの現在の値を使用してイベント間の時間間隔を計算することができる(例えば、入力ドライバでクリックからダブルクリックまたは計算タイムアウトを区別する).簡単に言えば、jiffiesを見るのはほとんど十分で、時間間隔を測定する必要がある場合は十分です.短時間で失われる非常に正確な測定が必要な場合は、プロセッサ固有のレジスタが役立ちます(移植性の問題は深刻ですが).
それは非常に不可能な駆動で、壁の時計の時間を知る必要があります.月、日、時間で表現されています.この情報はcronやsyslogdなどのユーザプログラムにのみ必要とされることが多い.実際の世界を処理する時間は常にユーザー空間に残したほうがいい.そこのCライブラリはより良いサポートを提供している.また、このようなコードは、カーネルに属すほどポリシーに関連しすぎることが多い.カーネル関数が壁クロック時間をjiffies値に変換しますが、次のようにします.
繰り返し:壁のクロック時間を駆動中に直接処理することは、ポリシーを実現する信号であることが多く、そのために疑問視されるべきである.
人が読める時間を必ずしも処理する必要はありませんが、カーネル空間で絶対時間を処理する必要がある場合もあります.そのため、出力do_gettimeofday関数呼び出されるとstruct timevalポインタ--gettimeofdayシステム呼び出しで使用するのと同じ--類似の秒とミリ秒値を使用する.do_gettimeofdayのプロトタイプは:
このソースコードはdo_を宣言します.gettimeofdayには「ミリ秒に近い精度」がある.これは、時間ハードウェアが現在jiffyのどの割合が失われているかを尋ねるためである.この精度はシステムごとに異なるが、実際に使用するハードウェアのメカニズムに依存するためである.例えば、一部のm 68 knommuプロセッサ、Sun 3システム、その他のm 68 kシステムではjiffyよりも大きい精度を提供することができない.Pentiumシステムは、一方で、この章の前に説明するタイムスタンプカウンタを読み取ることにより、非常に高速で正確なビットよりも小さい測定を提供する.
現在の時間はxtime変数、struct timespec値からjiffyの粒度を用いるもよい.この変数の直接使用は、この2つのフィールドに原子的に同時にアクセスすることが困難であるため、奨励する.したがって、カーネルは実用的な関数current_を提供します.kernel_time:
現在時刻を様々に取得するためのコードは、O'Reillyが提供するFTPサイト上のソースファイルのjit(「just in time」)モジュールから取得することができる.jitは/proc/currentimeというファイルを作成し、読み取り時にASCIIコードで次の項目を返します.現在のjiffiesとjiffies_64の値は、16進数である. はdo_のようですgettimeofdayが返す同じ現在時刻. current_kernel_timeが返すtimespec.
テンプレートコードを最小限に抑えるために動的/procファイルを使用することを選択しました.デバイス全体を作成する価値はありません.テキスト情報を少し返すだけです.
このファイルは、このモジュールがロードされている限り、テキスト行を連続的に返します.readシステムが呼び出すたびに収集し、一連のデータを返し、よりよく読むために2行に組織する.1クロック未満で複数のデータセットを読むとdo_が表示されますgettimeofdayの違いは、ハードウェアに問い合わせるものであり、他の値はクロックのつぶやき時にのみ更新される.
上のスクリーンショットでは、2つの面白いことから注意してください.まず、このcurrent_kernel_time値は、ナノ秒で表されるが、クロックのつぶやきの粒度しかない.do_gettimeofdayは少し遅い時間を報告し続けたが、次の時計より遅くない.第二に、この64ビットのjiffiesカウンタは、高32ビットワードの集合の最低有効ビットを有する.これはINITIAL_JIFFIESのデフォルト値は、起動時間にカウンタを初期化するために使用され、起動時間の数分後に低ワードオーバーフローを強要することで、このちょうどオーバーフローに関連する問題を検出するのに役立つ.これは、jiffiesが壁クロック時間とは無関係であるため、カウンタにおける初期化の好ましいは効果的ではない./proc/uptimeでは、ここでカーネルはカウンタからuptimeを抽出する、初期化の好みは変換前に除去される.
1、rtcデバイスを使用して、このクロックは各種モード2に使用することができて、システム呼び出しadjtimexを参考にしてここで第2の方式を使用する
システム呼び出しadjtimex
ずっとついていくとvoid doが最後に呼び出されたことに気づきますgettimeofday(struct timeval *tv)
ではdo_をそのまま使いますgettimeofday、struct timevalを得ることができます
struct timeval { time_t tv_sec;/* seconds */suseconds_t tv_usec;/* microseconds */};
では、このtv_sec、すなわち1970年から現在までの秒数を年月日分秒に変換するカーネルにはすでにこのような関数があります/**Convert seconds since 01-01-1970 00:00:00 to Gregorian date.*/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);
カーネルコードはjifiesの値を表示することによって、現在の時間の表現を常に取得することができる.しばしば、この値は、最後の起動からの時間のみを表すが、この事実は、システムのuptimeに制限されているため、駆動には関係ない.図示するように、ドライバはjiffiesの現在の値を使用してイベント間の時間間隔を計算することができる(例えば、入力ドライバでクリックからダブルクリックまたは計算タイムアウトを区別する).簡単に言えば、jiffiesを見るのはほとんど十分で、時間間隔を測定する必要がある場合は十分です.短時間で失われる非常に正確な測定が必要な場合は、プロセッサ固有のレジスタが役立ちます(移植性の問題は深刻ですが).
それは非常に不可能な駆動で、壁の時計の時間を知る必要があります.月、日、時間で表現されています.この情報はcronやsyslogdなどのユーザプログラムにのみ必要とされることが多い.実際の世界を処理する時間は常にユーザー空間に残したほうがいい.そこのCライブラリはより良いサポートを提供している.また、このようなコードは、カーネルに属すほどポリシーに関連しすぎることが多い.カーネル関数が壁クロック時間をjiffies値に変換しますが、次のようにします.
#include <linux/time.h>
unsigned long mktime (unsigned int year, unsigned int mon,
unsigned int day, unsigned int hour,
unsigned int min, unsigned int sec);
繰り返し:壁のクロック時間を駆動中に直接処理することは、ポリシーを実現する信号であることが多く、そのために疑問視されるべきである.
人が読める時間を必ずしも処理する必要はありませんが、カーネル空間で絶対時間を処理する必要がある場合もあります.そのため、
#include <linux/time.h>
void do_gettimeofday(struct timeval *tv);
このソースコードはdo_を宣言します.gettimeofdayには「ミリ秒に近い精度」がある.これは、時間ハードウェアが現在jiffyのどの割合が失われているかを尋ねるためである.この精度はシステムごとに異なるが、実際に使用するハードウェアのメカニズムに依存するためである.例えば、一部のm 68 knommuプロセッサ、Sun 3システム、その他のm 68 kシステムではjiffyよりも大きい精度を提供することができない.Pentiumシステムは、一方で、この章の前に説明するタイムスタンプカウンタを読み取ることにより、非常に高速で正確なビットよりも小さい測定を提供する.
現在の時間はxtime変数、struct timespec値からjiffyの粒度を用いるもよい.この変数の直接使用は、この2つのフィールドに原子的に同時にアクセスすることが困難であるため、奨励する.したがって、カーネルは実用的な関数current_を提供します.kernel_time:
#include <linux/time.h>
struct timespec current_kernel_time(void);
現在時刻を様々に取得するためのコードは、O'Reillyが提供するFTPサイト上のソースファイルのjit(「just in time」)モジュールから取得することができる.jitは/proc/currentimeというファイルを作成し、読み取り時にASCIIコードで次の項目を返します.
テンプレートコードを最小限に抑えるために動的/procファイルを使用することを選択しました.デバイス全体を作成する価値はありません.テキスト情報を少し返すだけです.
このファイルは、このモジュールがロードされている限り、テキスト行を連続的に返します.readシステムが呼び出すたびに収集し、一連のデータを返し、よりよく読むために2行に組織する.1クロック未満で複数のデータセットを読むと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を参考にしてここで第2の方式を使用する
システム呼び出しadjtimex
ずっとついていくとvoid doが最後に呼び出されたことに気づきますgettimeofday(struct timeval *tv)
ではdo_をそのまま使いますgettimeofday、struct timevalを得ることができます
struct timeval { time_t tv_sec;/* seconds */suseconds_t tv_usec;/* microseconds */};
では、このtv_sec、すなわち1970年から現在までの秒数を年月日分秒に変換するカーネルにはすでにこのような関数があります/**Convert seconds since 01-01-1970 00:00:00 to Gregorian date.*/void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
唯一の不足はUTC時間で、北京時間と8時間の差があることだ.ユーザ状態localtime()の効果を達成するには、/etc/localtimeのタイムゾーン情報を取得する必要があります.
サンプルコード:
#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);