Μεταφράστε

Translate to EnglishÜbersetzen Sie zum Deutsch/GermanΜεταφράστε στα ελληνικά/GreekПереведите к русскому/RussianOversetter til Norsk/NorwegianÖversätta till Svensk/Swedishहिन्दी अनुवाद करने के लिए/Hindi
Tradueix al català/CatalanTulkot uz latviešu/LatvianPreložiť do slovenčiny/SlovakVertaal aan het Nederlands/Dutchترجمة الى العربية/ArabicTraduzca al Español/SpanishTraduisez au Français/French
Traduca ad Italiano/ItalianTraduza ao Português/Portuguese日本語に翻訳しなさい /Japanese한국어에게 번역하십시오/Korean中文翻译/Chinese Simplified中文翻译/Chinese TraditionalПереклад на українську/Ukrainian
Εικόνα των σύγχρονων λειτουργικών συστημάτων (3$η έκδοση)
Εικόνα της ανάπτυξης πυρήνων Linux (3$η έκδοση)
Εικόνα XSLT 2.0 και XPath 2.0 αναφορά του προγραμματιστή (προγραμματιστής στον προγραμματιστή)
Εικόνα της αρρενωπής ασύρματης ανάπτυξης εφαρμογών

Υποστήριξη Linux HPET

Το ia-PC HPET (χρονόμετρο γεγονότος υψηλής ακρίβειας) είναι μια προδιαγραφή που αναπτύχθηκε από κοινού από τη Intel και τη Microsoft στο πρώτο μέρος αυτής της δεκαετίας. Η πιό πρόσφατη έκδοση είναι της Οκτωβρίου 2004. Έχει δηλώσει ότι ο σκοπός είναι

αρχικά το συμπλήρωμα και αντικαθιστά τελικά την κληρονομιά 8254 προγραμματίσημο χρονόμετρο διαστήματος και ο πραγματικός - το χρονικό ρολόι περιοδικό διακόπτει τις λειτουργίες παραγωγής που χρησιμοποιούνται αυτήν την περίοδο ως de - facto υλικό χρονομέτρων `για τα iA-PC.

Η αρχιτεκτονική HPET καθορίζει ένα σύνολο χρονομέτρων που μπορεί να χρησιμοποιηθεί από το λειτουργικό σύστημα. Ένας φραγμός χρονομέτρων είναι ένας συνδυασμός ενιαίου μετρητή και μέχρι 32 συγκριτές και καταλόγων αντιστοιχιών. Ο συγκριτής συγκρίνει το περιεχόμενο του καταλόγου αντιστοιχιών ενάντια στην αξία ενός ελεύθερου τρέχοντας μονοτονικού επάνω-μετρητή. Όταν η παραγωγή του επάνω-μετρητή είναι ίση με την αξία στον κατάλογο αντιστοιχιών διακόψτε παράγεται. Κάθε ένας από τους συγκριτές μπορεί παραγωγή διακόπτει. Ένα μέγιστο 8 φραγμών χρονομέτρων υποστηρίζεται για συνολικά 256 χρονόμετρα. Κάθε φραγμός χρονομέτρων μπορεί να έχει τις διαφορετικές ιδιότητες χρονομέτρησης. Οι συγκεκριμένες εφαρμογές μπορούν να περιλάβουν μόνο ένα υποσύνολο αυτών των χρονομέτρων. Ένα ελάχιστο τριών χρονομέτρων απαιτείται.

Η προδιαγραφή περιέχει το ακόλουθο διάγραμμα φραγμών της αρχιτεκτονικής HPET.

Διάγραμμα φραγμών υλικού

Μερικά από τα χρονόμετρα μπορούν να επιτραπούν για να παραγάγουν έναν περιοδικό διακόπτουν. Εάν ένα χρονόμετρο τίθεται ως στόχος να είναι περιοδικό, η περίοδός της προστίθεται στον κατάλογο αντιστοιχιών κάθε φορά που εμφανίζεται μια αντιστοιχία, υπολογίζοντας κατά συνέπεια την επόμενη φορά για αυτό το χρονόμετρο για να παραγάγει διακόψτε. Ένας επάνω-μετρητής είναι συνήθως 64 μπιτ ευρύς αλλά οι τριανταδυάμπιτες εφαρμογές επιτρέπονται από την προδιαγραφή και οι εξηντατετράμπιτοι επάνω-μετρητές μπορούν επίσης να οδηγηθούν στον τριανταδυάμπιτο τρόπο. Οι επάνω-μετρητές τρέχουν σε ένα ελάχιστο 10 MHZ. όποιος είναι πολύ γρηγορότερος από το παλαιότερο RTC (πραγματικό - χρονικό ρολόι) και μπορεί έτσι να παραγάγει περιοδικό διακόπτει σε ένα πολύ υψηλότερο ψήφισμα. Οι κατάλογοι που συνδέονται με αυτά τα χρονόμετρα χαρτογραφούνται στο διάστημα μνήμης.

Το ΖΩΝΤΑΝΟ ΟΝ χρησιμοποιεί ( προηγμένη διεπαφή διαμόρφωσης και δύναμης) τη λειτουργία ACPI για να ενημερώσει το λειτουργικό σύστημα για τη θέση του μνήμη-ταξινομικού HPET διαστήματος καταλόγων. Εδώ είναι ένα παράδειγμα ενός αποσυντεθειμένου πίνακα ACPI HPET από μια μητρική κάρτα της Intel DX48BT2 (AKA BoneTrail).

$ cat /sys/firmware/acpi/tables/HPET > /var/tmp/hpet.out
$ iasl -d /var/tmp/hpet.out
$ cat /var/tmp/hpet.dsl
/*
 * Intel ACPI Component Architecture
 * AML Disassembler version 20090123
 *
 * Disassembly of /var/tmp/hpet.out, Sun Jul  5 19:34:47 2009
 *
 * ACPI Data Table [HPET]
 *
 * Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
 */

[000h 000  4]                    Signature : "HPET"    /* High Precision Event Timer table */
[004h 004  4]                 Table Length : 00000038
[008h 008  1]                     Revision : 01
[009h 009  1]                     Checksum : CE
[00Ah 010  6]                       Oem ID : "INTEL "
[010h 016  8]                 Oem Table ID : "DX48BT2 "
[018h 024  4]                 Oem Revision : 0000076E
[01Ch 028  4]              Asl Compiler ID : "MSFT"
[020h 032  4]        Asl Compiler Revision : 01000013

[024h 036  4]            Hardware Block ID : 8086A301

[028h 040 12]         Timer Block Register : 
[028h 040  1]                     Space ID : 00 (SystemMemory)
[029h 041  1]                    Bit Width : 00
[02Ah 042  1]                   Bit Offset : 00
[02Bh 043  1]                 Access Width : 00
[02Ch 044  8]                      Address : 00000000FED00000

[034h 052  1]              Sequence Number : 00
[035h 053  2]          Minimum Clock Ticks : 0001
[037h 055  1]        Flags (decoded below) : 00
                              Page Protect : 0
                           4K Page Protect : 0
                          64K Page Protect : 0
Raw Table Data

  0000: 48 50 45 54 38 00 00 00 01 CE 49 4E 54 45 4C 20  HPET8.....INTEL
  0010: 44 58 34 38 42 54 32 20 6E 07 00 00 4D 53 46 54  DX48BT2 n...MSFT
  0020: 13 00 00 01 01 A3 86 80 00 00 00 00 00 00 D0 FE  ................
  0030: 00 00 00 00 00 01 00 00                          ........
$


Δείτε τη σελίδα 30 της προδιαγραφής HPET v1.0a για μια λεπτομερή κατανομή του μεμονωμένου χρονικού φραγμού κομματιών σε περίπτωση (που καλείται φραγμό υλικού από το AML disassember). Σημειώστε ότι μόνο ένας φραγμός χρονομέτρων γεγονότος χρειάζεται να περιγραφεί στο επιτραπέζιο HPET προκειμένου δόλωμα ένα λειτουργικό σύστημα. Αυτό συμβαίνει εδώ. Για τις πλατφόρμες μη-κληρονομιών, ο φραγμός χρονομέτρων γεγονότος που περιγράφεται στο HPET είναι αυτός που παρέχει ότι η λειτουργία για να αντικαταστήσει το 8254/RTC περιοδικό διακόπτει τη λογική.

Άλλοι χρονικοί φραγμοί γεγονότος περιγράφονται στο ACPI namespace. Εδώ είναι το σχετικό τμήμα από τον αποσυντεθειμένο πίνακα ACPI DSDT.

            Device (HPET)
            {
                Name (_HID, EisaId ("PNP0103"))
                Name (_CRS, ResourceTemplate ()
                {
                    Memory32Fixed (ReadOnly,
                        0xFED00000,         // Address Base
                        0x00004000,         // Address Length
                        )
                })
                Method (_STA, 0, NotSerialized)
                {
                    If (HPEE)
                    {
                        Return (0x0F)
                    }
                    Else
                    {
                        Return (Zero)
                    }
                }
            }


Σημειώστε το ορισμένο PNPID (PNP0103) για το HPET. Επειδή κανένα _UID δεν διευκρινίζεται σημαίνει ότι δεν υπάρχει κανένας άλλος φραγμός χρονομέτρων HPET.

Εδώ είναι ένας κατάλογος των hPET-σχετικών μηνυμάτων όταν τίθεται σε έναρξη επάνω αυτή η ιδιαίτερη μητρική κάρτα κάτω από Fedora 11.

$ dmesg | grep -i HPET
ACPI: HPET CFBF2000, 0038 (r1 INTEL  DX48BT2       76E MSFT  1000013)
ACPI: HPET id: 0x8086a301 base: 0xfed00000
hpet clockevent registered
HPET: 4 timers in total, 0 timers will be used for per-cpu timer
hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0
hpet0: 4 comparators, 64-bit 14.318180 MHz counter
rtc0: alarms up to one month, 114 bytes nvram, hpet irqs
$


Η πρώτη γραμμή είναι όταν διαβάζεται ο πίνακας ACPI HPET. Η δεύτερη γραμμή είναι όταν χαρτογραφείται ο πίνακας ACPI HPET στη μνήμη από… /arch/x86/kernel/acpi/boot.c. Η επόμενη γραμμή είναι όταν διακόπτει η κληρονομιά HPET αρχίζει και HPET καταχωρείται ως σφαιρικό ρολόι. Η ακόλουθη γραμμή είναι όταν ελέγχει ο πυρήνας για να εξασφαλίσει ότι τουλάχιστον ένα χρονόμετρο είναι διατηρημένο για το userspace (/dev/hpet.) Οι επόμενες δύο γραμμές παραγωγής προέρχονται από τον οδηγό συσκευών HPET (… /drivers/char/hpet.c.) Δείχνει ότι 2 χρονόμετρα έχουν διαθέσει διακόπτουν και δύο όχι.

Εδώ είναι το σχετικό μέρος της παραγωγής από το /proc/time_list όπως αφορά HPET:

Tick Device: mode:     1
Broadcast device
Clock Event Device: hpet
 max_delta_ns:   149983005959
 min_delta_ns:   5000
 mult:           61496114
 shift:          32
 mode:           3
 next_event:     9223372036854775807 nsecs
 set_next_event: hpet_legacy_next_event
 set_mode:       hpet_legacy_set_mode
 event_handler:  tick_handle_oneshot_broadcast
tick_broadcast_mask: 00000000
tick_broadcast_oneshot_mask: 00000000


Εδώ είναι η παραγωγή από το /proc/sys/dev/hpet και το /proc/driver/rtc:

$ cat /proc/sys/dev/hpet/max-user-freq
64
$ cat /proc/driver/rtc
rtc_time	: 06:34:31
rtc_date	: 2009-07-06
alrm_time	: **:24:40
alrm_date	: ****-**-**
alarm_IRQ	: no
alrm_pending	: no
24hr		: yes
periodic_IRQ	: no
update_IRQ	: no
HPET_emulated	: yes
DST_enable	: no
periodic_freq	: 1024
batt_status	: okay

Ο οδηγός HPET (/dev/hpet) έχει ένα παρόμοιο API στον πραγματικό - οδηγός χρονικών ρολογιών. Είναι μια συσκευή χαρακτήρα που μπορεί να υποστηρίξει οποιοδήποτε αριθμό συσκευών HPET. Ο πυρήνας API εξάγει τρεις διεπαφές από τον οδηγό:

hpet_register( struct hpet_task *tp, int periodic )
hpet_unregister( struct hpet_task *tp )
hpet_control( struct hpet_task *tp, unsigned int cmd, unsigned long arg )


Η διεπαφή userspace σε HPET καθορίζεται στην επιγραφή /usr/include/linux/hpet.h. Το τρέχον σύνολο υποστηριγμένων διαδικασιών είναι:

#define HPET_IE_ON      _IO('h', 0x01)                        /* interrupt on */
#define HPET_IE_OFF     _IO('h', 0x02)                        /* interrupt off */
#define HPET_INFO       _IOR('h', 0x03, struct hpet_info)     /* get information */
#define HPET_EPI        _IO('h', 0x04)                        /* enable periodic */
#define HPET_DPI        _IO('h', 0x05)                        /* disable periodic */
#define HPET_IRQFREQ    _IOW('h', 0x6, unsigned long)         /* set frequency */


Το ακόλουθο παράδειγμα επιδεικνύει πώς να χρησιμοποιήσει τη δημοσιευμένη διεπαφή για να έχει πρόσβαση σε ένα HPET και να καλέσει έναν απλό περιοδικό χειριστή σημάτων hpet_alarm μεταξύ 2 και 99 φορές το δευτερόλεπτο.

#include <stdio.h>
#include <stdlib.h;>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include <linux/hpet.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <signal.h>

static uint16_t hpet_sigio_count;
static uint64_t secs;

static void
hpet_alarm(int val)
{
   struct timespec t;
   clock_gettime(CLOCK_REALTIME, &t);

   if (!secs)  secs = t.tv_sec;

   fprintf(stderr, "hpet_alarm called. iteration: %2d  secs: %ld  nsecs: %ld \n",
                    hpet_sigio_count, (t.tv_sec - secs) , t.tv_sec * 100000 + t.tv_nsec );

   hpet_sigio_count++;
}

int
main(int argc, const char **argv)
{
    struct sigaction old, new;
    struct hpet_info info;
    int              frequency;
    int              iterations;
    int              retval = 0;
    int              fd;
    int              r, i, value;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s frequency(1-64) iterations(10-99)\n", argv[0]);
        return -1;
    }

    frequency = atoi(argv[1]);
    iterations = atoi(argv[2]);

    if (frequency > 64 || frequency < 1 ) {
        fprintf(stderr, "ERROR: Invalid value for frequency\n");
        return -1;
    }

    if (iterations < 10 || iterations > 99 ) {
        fprintf(stderr, "ERROR: Invalid value for iterations\n");
        return -1;
    }

    hpet_sigio_count = 0;

    sigemptyset(&new.sa_mask);
    new.sa_flags = 0;
    new.sa_handler = hpet_alarm;

    sigaction(SIGIO, NULL, &old);
    sigaction(SIGIO, &new, NULL);

    fd = open("/dev/hpet", O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "ERROR: Failed to open /dev/hpet\n");
        return -1;
    }

    if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
        ((value = fcntl(fd, F_GETFL)) == 1) ||
        (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
        fprintf(stderr, "ERROR: fcntl failed\n");
        retval = 1;
        goto fail;
    }

    if (ioctl(fd, HPET_IRQFREQ, frequency) < 0) {
        fprintf(stderr, "ERROR: Could not set /dev/hpet to have a %2dHz timer\n", frequency);
        retval = 2;
        goto fail;
    }

    if (ioctl(fd, HPET_INFO, &info) < 0) {
        fprintf(stderr, "ERROR: failed to get info\n");
        retval = 3;
        goto fail;
    }

    fprintf(stdout, "\nhi_ireqfreq: 0x%lx  hi_flags: %0x%lx  hi_hpet: 0x%x  hi_timer: 0x%x\n\n",
            info.hi_ireqfreq,  info.hi_flags, info.hi_hpet, info.hi_timer);

    r = ioctl(fd, HPET_EPI, 0);
    if (info.hi_flags && (r < 0)) {
        fprintf(stderr, "ERROR:  HPET_EPI failed\n");
        retval = 4;
        goto fail;
    }

    if (ioctl(fd, HPET_IE_ON, 0) < 0) {
        fprintf(stderr, "ERROR: HPET_IE_ON failed\n");
        retval = 5;
        goto fail;
    }

    /* wait for specified number of signal interrupts */
    for (i = 0; i < iterations; i++) {
        (void) pause();
    }

    if (ioctl(fd, HPET_IE_OFF, 0) < 0) {
        fprintf(stderr, "ERROR: HPET_IE_OFF failed\n");
        retval = 6;
    }

fail:
    sigaction(SIGIO, &old, NULL);

    if (fd > 0)
        close(fd);

    return retval;
}


Εδώ είναι η παραγωγή από αυτό το παράδειγμα όταν επικαλείται με μια συχνότητα 32 και μια αρίθμηση επανάληψης 64.

$ sudo ./hpet_example 32 64

hi_ireqfreq: 0x20  hi_flags: 00  hi_hpet: 0x2  hi_timer: 0x4a1cb9c8

hpet_alarm called. iteration:  0  secs: 0  nsecs: 124683205055050
hpet_alarm called. iteration:  1  secs: 0  nsecs: 124683236313149
hpet_alarm called. iteration:  2  secs: 0  nsecs: 124683267566342
hpet_alarm called. iteration:  3  secs: 0  nsecs: 124683298821905
hpet_alarm called. iteration:  4  secs: 0  nsecs: 124683330077493
hpet_alarm called. iteration:  5  secs: 0  nsecs: 124683361341893
hpet_alarm called. iteration:  6  secs: 0  nsecs: 124683392590764
hpet_alarm called. iteration:  7  secs: 0  nsecs: 124683423849157
hpet_alarm called. iteration:  8  secs: 0  nsecs: 124683455101917
hpet_alarm called. iteration:  9  secs: 0  nsecs: 124683486357683
hpet_alarm called. iteration: 10  secs: 0  nsecs: 124683517617931
hpet_alarm called. iteration: 11  secs: 0  nsecs: 124683548872198
hpet_alarm called. iteration: 12  secs: 1  nsecs: 124682580229541
hpet_alarm called. iteration: 13  secs: 1  nsecs: 124682611481235
hpet_alarm called. iteration: 14  secs: 1  nsecs: 124682642740016
hpet_alarm called. iteration: 15  secs: 1  nsecs: 124682673992697
hpet_alarm called. iteration: 16  secs: 1  nsecs: 124682705247479
hpet_alarm called. iteration: 17  secs: 1  nsecs: 124682736504664
hpet_alarm called. iteration: 18  secs: 1  nsecs: 124682767758840
hpet_alarm called. iteration: 19  secs: 1  nsecs: 124682799014280
hpet_alarm called. iteration: 20  secs: 1  nsecs: 124682830270129
hpet_alarm called. iteration: 21  secs: 1  nsecs: 124682861530334
hpet_alarm called. iteration: 22  secs: 1  nsecs: 124682892784577
hpet_alarm called. iteration: 23  secs: 1  nsecs: 124682924038220
hpet_alarm called. iteration: 24  secs: 1  nsecs: 124682955294110
hpet_alarm called. iteration: 25  secs: 1  nsecs: 124682986550572
hpet_alarm called. iteration: 26  secs: 1  nsecs: 124683017805756
hpet_alarm called. iteration: 27  secs: 1  nsecs: 124683049061117
hpet_alarm called. iteration: 28  secs: 1  nsecs: 124683080318331
hpet_alarm called. iteration: 29  secs: 1  nsecs: 124683111576954
hpet_alarm called. iteration: 30  secs: 1  nsecs: 124683142828988
hpet_alarm called. iteration: 31  secs: 1  nsecs: 124683174083954
hpet_alarm called. iteration: 32  secs: 1  nsecs: 124683205337967
hpet_alarm called. iteration: 33  secs: 1  nsecs: 124683236593144
hpet_alarm called. iteration: 34  secs: 1  nsecs: 124683267851530
hpet_alarm called. iteration: 35  secs: 1  nsecs: 124683299104054
hpet_alarm called. iteration: 36  secs: 1  nsecs: 124683330358748
hpet_alarm called. iteration: 37  secs: 1  nsecs: 124683361617445
hpet_alarm called. iteration: 38  secs: 1  nsecs: 124683392870249
hpet_alarm called. iteration: 39  secs: 1  nsecs: 124683424124489
hpet_alarm called. iteration: 40  secs: 1  nsecs: 124683455379717
hpet_alarm called. iteration: 41  secs: 1  nsecs: 124683486634424
hpet_alarm called. iteration: 42  secs: 1  nsecs: 124683517889149
hpet_alarm called. iteration: 43  secs: 1  nsecs: 124683549144315
hpet_alarm called. iteration: 44  secs: 2  nsecs: 124682580500695
hpet_alarm called. iteration: 45  secs: 2  nsecs: 124682611761325
hpet_alarm called. iteration: 46  secs: 2  nsecs: 124682643011863
hpet_alarm called. iteration: 47  secs: 2  nsecs: 124682674265864
hpet_alarm called. iteration: 48  secs: 2  nsecs: 124682705521034
hpet_alarm called. iteration: 49  secs: 2  nsecs: 124682736776049
hpet_alarm called. iteration: 50  secs: 2  nsecs: 124682768030654
hpet_alarm called. iteration: 51  secs: 2  nsecs: 124682799285398
hpet_alarm called. iteration: 52  secs: 2  nsecs: 124682830544701
hpet_alarm called. iteration: 53  secs: 2  nsecs: 124682861797319
hpet_alarm called. iteration: 54  secs: 2  nsecs: 124682893051578
hpet_alarm called. iteration: 55  secs: 2  nsecs: 124682924306748
hpet_alarm called. iteration: 56  secs: 2  nsecs: 124682955562132
hpet_alarm called. iteration: 57  secs: 2  nsecs: 124682986823545
hpet_alarm called. iteration: 58  secs: 2  nsecs: 124683018073636
hpet_alarm called. iteration: 59  secs: 2  nsecs: 124683049327560
hpet_alarm called. iteration: 60  secs: 2  nsecs: 124683080586707
hpet_alarm called. iteration: 61  secs: 2  nsecs: 124683111841132
hpet_alarm called. iteration: 62  secs: 2  nsecs: 124683143095147
hpet_alarm called. iteration: 63  secs: 2  nsecs: 124683174349985
hpet_alarm called. iteration: 64  secs: 2  nsecs: 124683205607103
$


Καλά, σκέφτομαι ότι έχω παράσχει σε σας αρκετές πληροφορίες έτσι ώστε πρέπει τώρα να είστε σε θέση να πάτε μακριά και να πειραματιστείτε με τη διεπαφή HPET οι ίδιοι.

Επ'ευκαιρία δεν υποστηρίζουν όλα τα προϊόντα VMware HPET. Αυτήν την περίοδο ESX δεν παρέχει ένα εικονικό HPET στα λειτουργικά συστήματα φιλοξενουμένων και σε μερικές περιπτώσεις μπορεί να είναι απαραίτητο να τεθεί εκτός λειτουργίας HPET συνολικά λόγω της κλίσης χρονομέτρων στα μηχανήματα εικονικής πραγματικότητας. Δείτε VMware TimeKeeping για περισσότερες πληροφορίες.

P.S. Εξέτασα το ανωτέρω παράδειγμα σε μια μητρική κάρτα της Intel DX48BT2 που τρέχει το 2.6.29.5 - πυρήνας 191.
 

Τα σχόλια είναι κλειστά.