rtc -
リアルタイムクロック
#include <linux/rtc.h>
int ioctl(fd, RTC_request,
param);
これはリアルタイムクロック
(RTC)
のドライバのインターフェースである。
多くのコンピュータは、現在の「壁時計」時刻
("wall clock" time) を記録する、
ハードウェアクロックを
1 個以上持っている。
これらは「リアルタイムクロック」(RTC)
と呼ばれる。
これらの時計のうち 1
つは、通常は電池でバックアップして駆動されるので、
コンピュータのスイッチを切っても、時刻を保持できる。
多くの場合、RTC
はアラームやその他の割り込みの機能を提供する。
全ての i386 PC と ACPI
ベースのシステムには
RTC がある。 この RTC
は、元々の PC/AT
に存在した Motorola MC146818
チップと互換性がある。
このような RTC
は、今日ではマザーボードの
チップセット
(サウスブリッジ)
内で実装されていることが多く、
交換可能な硬貨くらいの大きさのバックアップ電池を使っている。
システムオンチップ
(system-on-chip)
プロセッサを使って作られた
組み込みシステムといった、PC
以外のシステムでは、別な実装を用いている。
このようなシステムでは、PC/AT
の RTC
と同じ機能を提供していない場合が多い。
RTC
をシステムクロックと混同すべきではない。
システムクロックは、カーネルに管理されるソフトウェアクロックであり、
ファイルによるタイムスタンプ設定などとともに、
gettimeofday(2) や
time(2)
を実装するのに使用されている。
システムクロックは、POSIX
における紀元 (Epoch; 1970-01-01 00:00:00
+0000 (UTC))
からの秒とミリ秒を表す。
1
つの一般的な実装ではタイマー割り込みを、"jiffy"
毎に 1 回、 100, 250, 1000 Hz
という周波数でカウントする。
RTC
とシステムクロックの重要な違いは、
RTC
はシステムが低電力状態
(「オフ」の場合も含む)
でも動作するのに対し、
システムクロックは動作しない点である。
システムクロックは、初期化が行われるまでは、
POSIX
紀元からではなくシステムのブート時からの時刻しか返せない。
そのため、ブート時やシステムの低電力状態からの復帰
(resume) 後には、
システムクロックは RTC
を使って現在の壁時計時刻に設定される場合が多い。
RTC
を持たないシステムでは、
他の時計を使ってシステムクロックを設定する必要があり、
ネットワークにアクセスしたり、(時刻)
データを手動で入力したりするだろう。
RTC は
hwclock(8) または下記の
ioctl(2)
リクエストで読み書きができる。
日付と時間をカウントするのに加えて、
多くの RTC
は以下のように割り込みを発生できる。
- *
- クロックの更新毎
(つまり 1 秒毎)。
- *
- 2 Hz から 8192 Hz までの 2
の乗数の周波数で、定期的な間隔。
- *
- 前もって指定したアラーム時刻に達した時。
これらの割り込み元は、個別に有効にしたり無効にしたりできる。
多くのシステムでは、アラーム割り込みをシステムの
ウェイクアップイベントとして設定できる。
このイベントは、RAM
へのサスペンド (STR, ACPI
システムで S3
と呼ばれる) や
ハイバーネーション (ACPI
システムで S4
と呼ばれる)
といった低電力状態や、
「オフ」(ACPI システムで
S5 と呼ばれる)
からでも、システムを復帰できる。
電池でバックアップされた
RTC
が割り込みを発生できるシステムと、
できないシステムがある。
/dev/rtc (または
/dev/rtc0,
/dev/rtc1
などの) デバイスは
(クローズされるまで) 1
回しかオープンすることができず、
読み込み専用である。
read(2) と
select(2)
を呼び出したプロセスは、
RTC
からの割り込みを受け取るまで停止
(block) される。
割り込みの後、プロセスは
long
型整数を読み出すことができる。
この整数の最下位バイトは発生した割り込みの種別を
コード化したビットマスクであり、
残りの 3
バイトは最後の
read(2)
以降に発生した割り込みの回数である。
ioctl(2)_インターフェース">ioctl(2)_%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9">ioctl(2)
インターフェース
以下の
ioctl(2)
リクエストが RTC
デバイスの接続された
ファイルディスクリプターに対して定義されている:
- RTC_RD_TIME
- RTC
の時刻を以下の構造体で返す:
-
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday; /* 未使用 */
int tm_yday; /* 未使用 */
int tm_isdst; /* 未使用 */
};
- この構造体のフィールドは
gmtime(3)
で説明されている tm
構造体のフィールドと同じ意味で同じ範囲である。
この構造体へのポインターを
ioctl(2) の第 3
引数として渡す。
- RTC_SET_TIME
-
ioctl(2) の第 3
引数が指す rtc_time
構造体の値を RTC
時刻に設定する。 RTC
時刻の設定する場合、プロセスは特権
(つまり CAP_SYS_TIME
ケーパビリティ)
を持たなければならない。
-
RTC_ALM_READ, RTC_ALM_SET
- アラームがサポートされている
RTC に対して、
アラーム時刻の読み込みと設定を行う。
アラーム割り込みは、
RTC_AIE_ON, RTC_AIE_OFF
を使って、これとは別に有効または無効にしなければならない。
ioctl(2) の第 3 引数は、
rtc_time
構造体へのポインターでなければならない。
この構造体の tm_sec,
tm_min, tm_hour
フィールドのみが使用される。
-
RTC_IRQP_READ, RTC_IRQP_SET
- 周期的な割り込みがサポートされている
RTC に対して、
周期的な割り込みの周波数の読み込みと設定を行う。
周期的な割り込みは、
RTC_PIE_ON, RTC_PIE_OFF
を使って、これとは別に有効または無効にしなければならない。
ioctl(2) の第 3
引数は、それぞれ
unsigned long * と unsigned long
である。 この値は 1
秒当たりの割り込みの回数である。
指定可能な周波数は、2
の乗数で 2 から 8192
の範囲である。
特権プロセス (つまり
CAP_SYS_RESOURCE
ケーパビリティを持つプロセス)
のみが、 /proc/sys/dev/rtc/max-user-freq
に書かれた上記の周波数を設定できる。
(このファイルにはデフォルトで
64
という値が書かれている)。
-
RTC_AIE_ON, RTC_AIE_OFF
- アラームがサポートされている
RTC に対して、
アラーム割り込みを有効または無効にする。
ioctl(2) の第 3
引数は無視される。
-
RTC_UIE_ON, RTC_UIE_OFF
- 1
秒毎の割り込みがサポートされている
RTC に対して、
クロック更新毎の割り込みを有効または無効にする。
ioctl(2) の第 3
引数は無視される。
-
RTC_PIE_ON, RTC_PIE_OFF
- 周期的な割り込みがサポートされている
RTC に対して、
周期的な割り込みを有効または無効にする。
ioctl(2) の第 3
引数は無視される。
特権プロセス (つまり
CAP_SYS_RESOURCE
ケーパビリティを持つプロセス)
のみが、 その時点で
/proc/sys/dev/rtc/max-user-freq
に周期が上記の値に指定されている場合に、
周期的な割り込みを有効にできる。
-
RTC_EPOCH_READ, RTC_EPOCH_SET
- 多くの RTC は年を 8
ビットのレジスターにコード化する。
年は 8
ビットのバイナリ数または
BCD 数に変換される。
どちらの場合でも、その数値は
RTC
の紀元から相対値に変換される。
多くのシステムでは
RTC の紀元は 1900
に初期化されるが、
Alpha と MIPS では、RTC
レジスターの年の値に応じて、
1952, 1980, 2000
の何れかに初期化される。
これらの操作でそれぞれ
RTC
の紀元の読み込みと設定が可能な
RTC もある。 ioctl(2) の第 3
引数は、それぞれ
unsigned long * と unsigned long
である。 返される値
(または指定される値)
は紀元である。 RTC
の紀元を設定する場合、プロセスは特権
(つまり CAP_SYS_TIME
ケーパビリティ)
を持たなければならない。
-
RTC_WKALM_RD, RTC_WKALM_SET
- RTC
の中にはより強力なアラームインターフェースをサポートするものもあり、
これらの ioctl
を使うことで、以下のような構造体で
RTC のアラーム時刻を
(それぞれ)
読み書きできる:
struct rtc_wkalrm {
unsigned char enabled;
unsigned char pending;
struct rtc_time time;
};
-
enabled
フラグはアラーム割り込みを有効または無効したり、
現在の状態を読み込むのに使用される。
これらのフラグを使う場合、
RTC_AIE_ON と RTC_AIE_OFF
は使用されない。
pending フラグは RTC_WKALM_RD
で使用され、処理待ちの割り込みを表示する
(EFI
ファームウェアで管理される
RTC
と通信するとき以外、
Linux
ではほとんど役に立たない)。
time フィールドは
RTC_ALM_READ や RTC_ALM_SET
の場合と同じように使用されるが、
tm_mday, tm_mon, tm_year
フィールドも有効であるという点が異なる。
この構造体へのポインターを
ioctl(2) の第 3
引数として渡さなければならない。
-
/dev/rtc, /dev/rtc0, /dev/rtc1
など。
- RTC
特殊キャラクターデバイスファイル。
- /proc/driver/rtc
- (1 つ目の) RTC
の状態
カーネルのシステムクロックを
adjtimex(2)
を使って外部参照で同期させる場合、
adjtimex(2) は指定された RTC
を 11
分毎に定期的に更新する。
これを行うためカーネルは周期的な割り込みを短期間無効にする必要がある。
これは RTC
を使うプログラムに影響を与える。
RTC
の紀元は、システムクロックでのみ使用される
POSIX
の紀元とは何の関係もない。
RTC
の紀元と年のレジスターに基づく年が
1970 未満である場合、 100
年後、つまり 2000 から 2069
であると仮定される。
RTC
の中にはアラームフィールドに
「ワイルドカード」の値をサポートするものもあり、
毎時 15
分や各月の初日など、定期的なアラームを行うシナリオをサポートする。
このような使い方は移植性がない。
移植性の高いユーザー空間コードでは、単独のアラーム割り込みだけを想定し、
割り込みの受信後にアラームを無効または再初期化すべきである。
以下の機能をサポートする
RTC もある。 1
秒の分数ではなく、1
秒の倍数を周期とする周期的な割り込み。
複数のアラーム。
プログラム可能な出力クロックシグナル。
不揮発性 (nonvolatile)
メモリー。 この API
で現在提供していない、その他のハードウェア機能。
date(1),
adjtimex(2),
gettimeofday(2),
settimeofday(2),
stime(2),
time(2),
gmtime(3),
time(7),
hwclock(8)
Linux カーネルソース内の
Documentation/rtc.txt
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。