4. Juni 2005
1 2 Timer Interrupts Software Timer System Calls
Die Real Time Clock befindet sich zusammen mit CMOS-RAM (Bios) auf einem Chip, zb Motorola 1416818. Wenn der PC ausgeschaltet wird, wird die Spannungsversorgung mittels einer Batterie aufrechterhalten. Linux nutzt die RTC lediglich um das aktuelle Datum und die aktuelle Uhrzeit auszulesen.
Alle 80x86 Prozessoren haben einen CLK-Eingang, der mit einem externen Oszillator beschaltet ist. Die meisten Prozessoren haben ein 64-Bit Register welches von jedem CLK-Signal inkrementiert wird. Die Oszillatorfrequenz wird jedoch nicht in den Kernel einkompiliert, beim Bootprozess muss also die Taktrate festgestellt werden. Diese Funktion uebernimmt calibrate tsc(): Das TSC-Register wird gelesen, dann wird ca. 50 Millisekunden gewartet und nochmal das TSC-Register ausgelesen. Die Differenz der beiden TSC-Werte gibt die Anzahl der in 50 Millisekunden verstrichenen Takte an, hieraus wird die Dauer eines Taktes und in Mikrosekunden errechnet.
TSC auslesen - Codebeispiel Das TSC-Register soll mittels des Assemblerbefehls rdtsc zweimal ausgelesen werden, wobei die Messzeitpunkte gespeichert werden. Aus der Differenz der TSC Werte in Verbindung mit δt kann dann der CPU-Takt bestimmt werden.
Neben RTC und TSC gibt es auf x86-architekturen einen weiteren Chip zur Zeitmessung, den PIT. Den PIT kann man sich als Eieruhr mit Endlosschleife vorstellen: Anstatt einem Alarmton loest der PIT einen Timer-Interrupt aus. Fuer den PIT wird meist ein 8254 CMOS Chip verwendet, der mit den I/O Ports 0x40-0x43 angesprochen wird.
Programmierung des PIT Konstanten HZ = Anzahl Timer Interrupts pro Sekunde (= 100) CLOCK TICK RATE = Freq. des Oszillators. (=1.193.180) LATCH =, um den PIT zu programmieren. CLOCK TICK RATE HZ Initialisierung des PIT outb p(0x34, 0x43); outb p(latch & 0xff, 0x40); /* LSB */ outb(latch >> 8, 0x40); /* MSB */
Behandlung von Timer-Interrupts Timer Interrupts Software Timer System Calls Auf einem Uniprozessorsystem werden alle zeitabhaengigen Aktivitaeten von einem vom PIT ausgeloesten Timer-Interrupt angestossen. Die Funktion timer interrupt() behandelt diese Interrupts: Wenn ein TSC-Register vorhanden ist: last tsc low 32 niederwertigen Bits des TSC-Registers. delay at last interrupt Zeitspanne (in µs) zwischen auftreten des Interrupts und Ausfuehren der ISR. do timer interrupt() ausfuehren: do timer() ausfuehren. (aktiviert bottom half) x86 do profile() ausfuehren, wenn Interrupt im Kernelmode auftrat eventuell set rtc mmss() ausfuehren um die RTC nachzustellen
TIMER BH bottom half Timer Interrupts Software Timer System Calls Ruft lediglich zwei Funktionen auf: update times() und run timer list(). Erstere sorgt dafuer, dass xtime die richtige Zeit enthaelt. Letztere verwaltet die Software-Timer.
Dynamische Timer Timer Interrupts Software Timer System Calls struct timer list { struct list head list; unsingned long expires; unsingned long data; void (*function)(unsigned long); }; Funktionen die auf Timern arbeiten void init timer(struct timer list * timer) void add timer(struct timer list * timer) int mod timer(struct timer list*timer,unsigned long expire) int del timer(struct timer list * timer) int del timer sync(struct timer list *timer)
Wichtige Systemcalls Timer Interrupts Software Timer System Calls int gettimeofday(struct timeval *tv, struct timezone *tz) int adjtimex(struct timex *buf); int setitimer(int which, const struct itimerval *value, struct itimer- val *ovalue); unsigned int alarm(unsigned int seconds);