BEZEICHNUNG¶
rtc - Echtzeituhr
ÜBERSICHT¶
#include <linux/rtc.h>
int ioctl(fd, RTC_request,
param);
BESCHREIBUNG¶
Dies ist die Schnittstelle zu Treibern für Echtzeit-Uhren (RTCs).
Die meisten Computer verfügen über eine oder mehrere Hardware-Uhren,
die die aktuelle »Wanduhr«-Zeit erfassen. Diese werden als
»Real Time Clocks« (RTC) bezeichnet. Eine von ihnen ist in der Regel
batteriegepuffert, sodass sie die Zeit verfolgt, auch während der
Computer ausgeschaltet ist. RTCs stellen oft Alarme und andere Interrupts
bereit.
In allen i386-PCs und ACPI-basierten Systemen ist eine RTC eingebaut, die
kompatibel zum Chip aus dem Originalen PC/AT ist, dem Motorola MC146818.
Heutzutage ist solch eine RTC im Allgemeinen in den Chipsatz des Mainboards
(South Bridge) integriert und nutzt eine austauschbare münzgroße
Batterie.
Nicht-PC-Systeme wie beispielsweise eingebettete Systeme, die um
»System-on-chip«-Prozessoren aufgebaut sind, nutzen andere
Implementierungen. Üblicherweise bieten sie nicht die gleiche
Funktionalität wie die RTC aus einem PC/AT.
RTC im Vergleich zur Systemuhr¶
RTCs sollten nicht mit der Systemuhr verwechselt werden. Diese ist eine
Software-Uhr, die vom Kernel gepflegt wird. Er verwendet sie für die
Implementierung von
gettimeofday(2) und
time(2) sowie für
die Zeitstempel von Dateien usw. Die Systemuhr zählt Sekunden und
Mikrosekunden seit einem Startpunkt, der als die »POSIX Epoch«
(1970-01-01 00:00:00 +0000 (UTC)) definiert ist. (Eine verbreitete Umsetzung
zählt Timer-Interrupts, einmal pro »Jiffy«, bei einer Frequenz
von 100, 250 oder 1000 Hz). Das heißt, sie sollte die
»Wanduhr«-Zeit angeben, wie es auch RTCS tun.
Ein wesentlicher Unterschied zwischen einer RTC und der Systemuhr ist, dass RTCs
auch dann laufen, wenn sich das System in einem Zustand niedrigen
Energieverbrauchs (einschließlich »ausgeschaltet«) befindet,
und die Systemuhr das nicht kann. Bis sie initialisiert wird, kann die
Systemuhr nur die Zeit seit Systemstart berichten ... und nicht seit der POSIX
Epoch. Also wird beim Booten und nach der Rückkehr aus einem
Niedrigenergie-Zustand des Systems die Systemuhr oft über eine RTC auf
die aktuelle Wanduhr-Zeit gesetzt werden. Systeme ohne eine RTC müssen
die Systemuhr mit einer anderen Uhr stellen, vielleicht über das Netzwerk
oder durch die manuelle Eingabe der Daten.
RTC-Funktionen¶
RTCs können direkt mit den im Folgenden aufgeführten ioctl-Aufrufen
und mittels
hwclock(8) gelesen und geschrieben werden.
Neben der Verfolgung von Zeit und Datum können viele RTCs Interrupts
erzeugen
- *
- bei jeder Aktualisierung der Uhr (d.h. einmal pro
Sekunde);
- *
- in periodischen Abständen mit einer Frequenz, die ein
Mehrfaches einer beliebigen Zweierpotenz im Bereich zwischen 2 Hz und 8192
Hz ist;
- *
- bei Erreichen einer vorher festgelegten Alarmzeit.
Jede dieser Interruptquellen kann separat aktiviert oder deaktiviert werden. Auf
vielen Systemen kann ein solch ein Interrupt als ein Ereignis zum
»Wecken« aus einem Energiesparzustand wie Suspend-to-RAM (STR, auf
ACPI-Systemen S3 genannt), Hibernation (S4 auf ACPI-Systemen) oder sogar
»aus« (S5) konfiguriert werden. Auf manchen Systemen kann nicht die
batteriegepufferte RTC Interrupts auslösen, sondern eine andere.
Das Gerät
/dev/rtc (oder
/dev/rtc0,
/dev/rtc1 usw.)
kann nur einmal (bis es wieder geschlossen wird) und nur für einen
Lesezugriff geöffnet werden. Beim Aufruf von
read(2) und
select(2) wird der aufrufende Prozess blockiert, bis er den
nächsten Interrupt von dieser RTC empfängt. Im Anschluss an den
Interrupt kann der Prozess einen »long integer« auslesen. Dessen
niedrigstwertiges Byte enthält eine Bitmaske, die die Typen der
aufgetretenen Interrupts codiert, während die verbleibenden 3 Bytes die
Anzahl von Interrupts seit dem letzten
read(2) enthalten.
Die folgenden
ioctl(2)-Anfragen sind für mit RTC-Geräten
verbundene Dateideskriptoren definiert:
- RTC_RD_TIME
- gibt die Zeit der RTC in der folgenden Struktur
zurück:
-
struct rtc_time {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday; /* nicht verwendet */
int tm_yday; /* nicht verwendet */
int tm_isdst; /* nicht verwendet */
};
- Die Felder dieser Struktur haben die gleiche Bedeutung und
die gleichen Wertebereiche wie die in gmtime(3) beschriebene
Strukur tm. Als drittes Argument von ioctl(2) sollte ein
Zeiger auf diese Strukur übergeben werden.
- RTC_SET_TIME
- setzt die Zeit der RTC auf die in der
rtc_time-Struktur festgelegte Zeit, auf die das dritte
ioctl(2)-Argument zeigt. Zum Setzen der Zeit muss der Prozess
privilegiert sein (d.h. über die Fähigkeit CAP_SYS_TIME
verfügen).
- RTC_ALM_READ, RTC_ALM_SET
- liest und setzt die Alarmzeit bei RTCs, die Alarme
unterstützen. Der Interrupt für den Alarm muss separat mit den
Anfragen RTC_AIE_ON und RTC_AIE_OFF aktiviert oder
deaktiviert werden. Das dritte Argument für ioctl(2) ist ein
Zeiger auf eine rtc_time-Struktur. Von der Struktur werden
lediglich die Felder tm_sec, tm_min und tm_hour
ausgewertet.
- RTC_IRQP_READ, RTC_IRQP_SET
- liest und setzt die Frequenz periodischer Interrupts bei
RTCs, die periodische Interrupts unterstützen. Der periodische
Interrupt muss separat mit den Anfragen RTC_PIE_ON und
RTC_PIE_OFF aktiviert oder deaktiviert werden. Das dritte Argument
von ioctl(2) ist ein unsigned long * beziehungsweise
ein unsigned long. Der Wert ist die Anzahl der Interrupts pro
Sekunde. Der Satz von zulässigen Frequenzen besteht aus Vielfachen
von zwei aus dem Bereich von 2 bis 8192. Nur ein privilegierter Prozess
(d.h. einer mit der CAP_SYS_RESOURCE-Fähigkeit) kann
Frequenzen über dem in /proc/sys/dev/rtc/max-user-freq
festgelegten Wert festlegen. (Diese Datei enthält
standardmäßig den Wert 64.)
- RTC_AIE_ON, RTC_AIE_OFF
- aktiviert oder deaktiviert den Alarm-Interrupt für
RTCs, die Alarme unterstützen. Das dritte Argument von
ioctl(2) wird ignoriert.
- RTC_UIE_ON, RTC_UIE_OFF
- aktiviert oder deaktiviert den Interrupt bei jeder
Aktualisierung der Uhr für RTCs, die diesen »einmal pro
Sekunde«-Interrupt unterstützen. Das dritte Argument von
ioctl(2) wird ignoriert.
- RTC_PIE_ON, RTC_PIE_OFF
- aktiviert oder deaktiviert den periodischen Interrupt
für RTCs, die diese periodischen Interrupts unterstützen. Das
dritte Argument von ioctl(2) wird ignoriert. Nur ein privilegierter
Prozess (d.h. einer mit der CAP_SYS_RESOURCE-Fähigkeit) kann
den periodischen Interrupt aktivieren, wenn die Frequenz über dem in
/proc/sys/dev/rtc/max-user-freq festgelegten Wert liegt.
- RTC_EPOCH_READ, RTC_EPOCH_SET
- Viele RTCs codieren das Jahr in einem 8-Bit-Register, das
entweder als 8-Bit-Binärzahl oder als BCD-Zahl interpretiert wird. In
beiden Fällen wird die Zahl relativ zum zeitlichen Bezugspunkt
(Epoch) der RTC interpretiert. Auf den meisten Systemen ist dies das Jahr
1900, aber auf Alpha und MIPS könnte es abhängig vom
RTC-Register für das Jahr auch 1952, 1980 oder 2000 sein. Bei einigen
RTCs kann mit diesen Operationen das Bezugsjahr gelesen bzw. gesetzt
werden. Das dritte Argument von ioctl(2) ist ein unsigned
long * oder ein unsigned long und entsprechend ist der
zurückgegebene (oder zugewiesene Wert) das Bezugsjahr.
- RTC_WKALM_RD, RTC_WKALM_SET
- Einige RTCs unterstützen eine leistungsfähigere
Alarm-Schnittstelle mittels dieser »ioctls« zum Schreiben oder
Lesen der Alarmzeit der RTC mit dieser Struktur:
struct rtc_wkalrm {
unsigned char enabled;
unsigned char pending;
struct rtc_time time;
};
- Der Schalter enabled wird zur Aktivierung oder
Deaktivierung des Alarm-Interrupts oder zur Ermittlung seines aktuellen
Status verwendet; wenn Sie diese Aufrufe einsetzen, werden
RTC_AIE_ON und RTC_AIE_OFF nicht beachtet. Der Schalter
pending wird von RTC_WKALM_RD verwendet, um einen
anstehenden Interrupt anzuzeigen. (Er ist also unter Linux meist nutzlos -
es sei denn, es wird mit durch EFI-Firmware verwalteteten RTCs
kommuniziert.) Das Feld time wird mit RTC_ALM_READ und
RTC_ALM_SET verwendet, mit dem Unterschied, dass die Felder
tm_mday, tm_mon und tm_year ebenfalls gültig
sind. Ein Zeiger auf diese Struktur sollte als drittes Argument an
ioctl(2) übergeben werden.
DATEIEN¶
/dev/rtc,
/dev/rtc0,
/dev/rtc1, etc.: (zeichenorientierte)
RTC-Gerätedateien.
/proc/driver/rtc: Status der (ersten) RTC
ANMERKUNGEN¶
Wenn die Systemzeit des Kernels mittels
adjtimex(2) mit einer externen
Referenz synchronisiert wird, wird er eine bestimmte RTC periodisch alle 11
Minuten aktualisieren. Dafür muss der Kernel kurzzeitig periodische
Interrupts ausschalten. Dadurch könnten Programme beeinträchtigt
werden, die diese RTC verwenden.
Der Zeitbezugspunkt (Epoch) hat nichts mit der POSIX Epoch zu tun, die lediglich
für die Systemuhr verwendet wird.
Wenn das Jahr entsprechend der RTC-Epoch und dem Jahres-Register kleiner als
1970 ist, werden 100 Jahre drauf geschlagen, also ein Jahr zwischen 2000 und
2069 angenommen.
Einige RTCs unterstützen Platzhalterwerte (wildcards) in den Alarm-Feldern,
um Szenarien wie regelmäßige Alarme 15 Minuten nach jeder vollen
Stunde oder am ersten Tag eines jeden Monats zu unterstützen. Die
Verwendung ist nicht portabel; portabler User-Space-Code erwartet lediglich
einen einzelnen Alarm-Interrupt und wird den Alarm bei Erhalt entweder
deaktivieren oder neu initialisieren.
Einige RTCs unterstützen periodische Interrupts mit Zeiten, die ein
Vielfaches einer Sekunde anstatt Bruchteile einer Sekunde sind; mehrere
Alarme, programmierbare Ausgangs-Taktsignale; nichtflüchtigen Speicher
und weitere Fähigkeiten, die derzeit nicht von dieser API zugänglich
gemacht werden.
SIEHE AUCH¶
date(1),
adjtimex(2),
gettimeofday(2),
settimeofday(2),
stime(2),
time(2),
gmtime(3),
time(7),
hwclock(8), /usr/src/linux/Documentation/rtc.txt
KOLOPHON¶
Diese Seite ist Teil der Veröffentlichung 3.42 des Projekts Linux-
man-pages. Eine Beschreibung des Projekts und Informationen, wie Fehler
gemeldet werden können, finden sich unter
http://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG¶
Die deutsche Übersetzung dieser Handbuchseite wurde von Martin Eberhard
Schauer <Martin.E.Schauer@gmx.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public
License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird
KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken
Sie bitte eine E-Mail an <debian-l10n-german@lists.debian.org>.