HPET API

HPET API English page

このページは HPET driver が提供する API をまとめたページです。man ページに似た書式を使います。man page の書式に次の修正・追加をしています。

  • "SYNOPSIS" 定数あるいは望ましい引数で示している箇所が有ります。
  • "PRECONDITION" 関数を呼び出す前に満たす必要がある条件を示しています。
  • "RETURN VALUE" and "ERROR" HPET ドライバ固有の仕様だけ示しています。基本的な system call 仕様は man ページを見て下さい。
  • "KERNEL CONFIGURATION and PARAMETER" API の機能に影響するカーネル構築条件、カーネル起動パラメータを示します。
  • "KERNEL SOURCE" 関係する kernel のソース・コード位置を示します。

機能一覧

HPET ドライバには次の機能が備わっています。

より詳細な情報は HPET 仕様書 を見て下さい。

サンプルプログラム

HPET ドライバ /drivers/char/hpet.c API の仕様を知るためにサンプルプログラム filehpet_example.tar.gz を用意しました。このプログラムは /Documentation/timers/hpet_example.c に基づいて作成されています。修正と機能拡張が施されています。

Device path

多くの Linux ディストリビューション では HPET ドライバを有効化して構築されています。/dev/hpet ノードが用意されています。/dev/hpet ノードはキャラクタ・デバイス・ノードで major=10, minor=228 という番号が付いています。"misc device" の一つです。

device を開く

HPET を使うには /dev/hpet を O_RDONLY モードで開きます。未使用の HPET timer が有れば、一つの timer を開いたファイル・ディスクリプタに割り当てます。timer は HPET 回路ブロックに複数ある timer のうちの一つです。ioctl() システム・コールでファイル・ディスクリプタに割り当てられた timer を操作します。

Header files

user space (Linux アプリケーション) から HPET device を使うには次のヘッダファイルを取り込んで下さい。

#define _GNU_SOURCE
#include <features.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/hpet.h>

poll() を使うには次のヘッダファイルを取り込んで下さい。

#include <poll.h>

select() を使うには次のヘッダファイルを取り込んで下さい。

#include <sys/time.h>
#include <sys/select.h>

signal() を使うには次のヘッダファイルを取り込んで下さい。

#include <signal.h>

mmap() を使うには次のヘッダファイルを取り込んで下さい。

#include <sys/mman.h>

システム・コール エラーを使うには次のヘッダファイルを取り込んで下さい。

#include <string.h> /* strerror() */
#include <errno.h>  /* errno, Exxx macros. */

HPET ドライバの ioctl API

ここでは HPET ドライバの ioctl() API を示します。HPET ドライバは次に示す ioctl() API を提供しています。

ioctl 要求番号説明
HPET_INFOtimer の情報を取得します
int ioctl(int fd, HPET_INFO, /* out */ struct hpet_info *info);
HPET_IRQFREQ割り込み周波数(Hz)を設定します
int ioctl(int fd, HPET_IRQFREQ, unsigned long frequency);
HPET_EPIハードウエアによる周期割り込み機能を使うようにします
int ioctl(int fd, HPET_EPI);
HPET_DPIハードウエアによる周期割り込み機能を使わないようにします
(ソフトウエアによって周期割り込みを起こします)
int ioctl(int fd, HPET_DPI);
HPET_IE_ONtimer からの割り込みを許可します
int ioctl(int fd, HPET_IE_ON);
HPET_IE_OFFtimer からの割り込みを禁止します
int ioctl(int fd, HPET_IE_OFF);

このページでは HPET ドライバ固有の仕様を示します。ioctl() システム・コールの基本的な仕様については man 2 ioctl を参照して下さい。

HPET_INFO - timer の情報を取得します

  • SYNOPSIS
    struct hpet_info {
    	unsigned long  hi_ireqfreq; /* Period or time in Hz */
    	unsigned long  hi_flags;    /* Information: 0x0: Not supported periodic int., 0x10: Supported periodic int. */
    	unsigned short hi_hpet;     /* HPET device number, [0..TheNumberOfHPETDevicesInPlatform-1] */
    	unsigned short hi_timer;    /* Timer number in HPET device, [0..31] */
    };
    int ioctl(int fd, HPET_INFO, /* out */ struct hpet_info *info);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer の情報を取得します。リクエスト・コード HPET_INFO で ioctl() を呼び出すと、timer の情報を *info に格納します。hpet_info 構造体の各メンバは次に示す値になります。
    メンバ説明
    hi_ireqfreq周波数(Hz)で表した割り込み周期
    hi_flagstimer の機能。 次の値のいずれかになります。
    0x00UL ハードウエアで実装された周期割り込み機能がありません。
    0x10UL ハードウエアで実装された周期割り込み機能が有ります。
    解析で気づいたこと: 将来的にはビットフィールドで示される可能性がありそうです。
    hi_hpetプラットホーム上で番号づけられた HPET デバイス番号です。(hi_hpet >= 0) && (hi_hpet < M) を満たします。M はプラットホーム上に存在する HPET デバイス(回路ブロック) 番号です。
    注: HPET デバイス(回路ブロック) の中に複数の timer があります。
    hi_timerHPET デバイス(回路ブロック) 中の timer 番号です。(hi_timer >= 0) && (hi_timer < N) を満たします。N は HPET デバイス(回路ブロック) 中で数えた timer 番号です。N <= 32 を満たします。
    NOTE: 恐らく一番初めに開いた HPET timer は {hi_hpet, hi_timer} == {0, 2} となっているでしょう。これは timer 0 と timer 1 が PIT(programmable Interval Timer) と RTC(Real Time Clock) をそれぞれ置き換えるために使われているからです。
  • RETURN VALUE
    • 0: 成功
    • -1: エラー
  • ERRORS
    • EBADF: ファイル・ディスクリプタの値が正しくない。
    • EFAULT: info が指しているメモリにアクセスできない。
  • KERNEL SOURCE
    HPET_INFO

HPET_IRQFREQ - 割り込み周波数(Hz)を設定します

  • SYNOPSIS
    int ioctl(int fd, HPET_IRQFREQ, unsigned long frequency);
    
  • PRECONDITION
    • timer 割り込みを禁止して下さい。HPET_IE_OFF を使います。
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer に割り込み周波数(Hz) で設定します。割り込み周期は 1/frequency 秒になります。プロセスに CAP_SYS_RESOURCE ケーパビリティが付与されていない場合は、周波数は /proc/sys/dev/hpet/max-user-freq から読んだ値以下で設定できます。 max-user-freq の初期値は 64 (==HPET_USER_FREQ) です。
    割り込み許可状態で割り込み周期を更新しないで下さい。
  • RETURN
    • 0: 成功
    • -1: エラー
  • ERRORS
    • EACCESS プロセスに CAP_SYS_RESOURCE ケーパビリティが付与されていないのに、/proc/sys/dev/hpet/max-user-freq から読んだ値より大きい周波数を設定しようとしました。max-user-freq から読んだ値の初期値は 64 (==HPET_USER_FREQ) です。
    • EINVAL: 周波数を 0 にしようとしました。
  • FILES
    • /proc/sys/dev/hpet/max-user-freq
  • KERNEL SOURCE
    HPET_IRQFREQ, hpet_max_freq, HPET_USER_FREQ, hpet_interrupt()

HPET_EPI - ハードウエアによる周期割り込み機能を使うようにします

  • SYNOPSIS
    int ioctl(int fd, HPET_EPI);
    
  • PRECONDITION
    • timer 割り込みを禁止して下さい。HPET_IE_OFF を使います。
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer のハードウエアによる周期割り込み機能を使用するようにします。ソフトウエアによる周期割り込み機能は使わないようになります。この ioctl() HPET_EPI 要求は timer の割り込みを許可する HPET_IE_ON をする前に使って下さい。
  • RETURN VALUE
    • 0: 成功
    • -1: エラー
  • ERRORS
    • EBADF: ファイル・ディスクリプタ fd が無効です。
    • ENXIO: ファイル・ディスクリプタ fd に割り当てられた timer にハードウエアによる周期割り込み機能が無い。
  • KERNEL SOURCE
    HPET_EPI

HPET_DPI - ハードウエアによる周期割り込み機能を使わないようにします

  • SYNOPSIS
    int ioctl(int fd, HPET_DPI);
    
  • PRECONDITION
    • timer 割り込みを禁止して下さい。HPET_IE_OFF を使います。
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer のハードウエアによる周期割り込み機能を使用しないようにします。ソフトウエアによる周期割り込み機能を使うようにします。この ioctl() HPET_FPI 要求は timer の割り込みを許可する HPET_IE_ON をする前に使って下さい。
    timer を HPET_DPI (ハードウエアによる周期割り込み禁止) で使う場合、HPET ドライバは timer を割り込みハンドラ中で更新し、次の割り込みを発生させるようにします。従って timer 割り込みはソフトウエアが応答するのに掛かる時間を含んだ周期で周期的に割り込みが発生します。
  • RETURN VALUE
    • 0: 成功
    • -1: エラー
  • ERRORS
    • EBADF: ファイル・ディスクリプタ fd が無効です。
    • ENXIO: ファイル・ディスクリプタ fd に割り当てられた timer にハードウエアによる周期割り込み機能が無い。
  • KERNEL SOURCE
    HPET_DPI, hpet_interrupt()

HPET_IE_ON - timer からの割り込みを許可します

  • SYNOPSIS
    int ioctl(int fd, HPET_IE_ON);
    
  • PRECONDITION
    • 割り込み周期を ioctl HPET_IRQFREQ リクエストで設定して下さい。
    • ハードウエアによる周期割り込み機能を使うか (HPET_EPI)・使わない (HPET_DPI) か設定して下さい。
      注: ハードウエアによる周期割り込み機能が無い場合はソフトウエアにより周期割り込みが発生します。
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer の割り込みを許可します。timer がプロセッサに割り込みを掛けたならば、ファイル・ディスクリプタ fd は (POLLIN|POLLRDNORM) イベントにて準備済み状態になります(待ちが解除されます)、同時にファイル・ステータス・フラグに O_ASYNC、有効なオーナー、有効なシグナル番号が設定されているならばシグナルが送られます。
  • RETURN VALUE
    • 0: 成功
    • -1: 失敗
  • ERRORS
    • EBADF: ファイル・ディスクリプタ fd が無効です。
    • EIO: 次のうちいずれかの状態です。
      • 割り込み周波数が無効です。
      • 割り込み周波数が設定されていません。
      • 割り込みハンドラを登録要求できません。チップセットか BIOS のバグが原因になっている可能性があります。
    • EBUSY:
      • 割り込みは既に許可状態です。
  • KERNEL SOURCE
    HPET_IE_ON, hpet_interrupt()

HPET_IE_OFF - timer からの割り込みを禁止します

  • SYNOPSIS
    int ioctl(int fd, HPET_IE_OFF);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer からの割り込みを禁止します。
  • RETURN VALUE
    • 0: 成功
    • -1: エラー
  • ERRORS
    • EBADF: ファイル・ディスクリプタ fd が無効です。
  • KERNEL SOURCE
    HPET_IE_OFF

HPET と関係する ファイル・システム と メモリ・マップ API

この節では HPET ドライバに関係するファイル・システムとメモリ・マップ API について説明します。open(), close(), read(), mmap(), munmap(), fcntl() とこれらの類似関数を HPET に対して使うと、HPET 特有の動作をします。ここでは HPET 特有の動作を示します。ファイル・システムの基本的な動作と詳細はシステム・コールの man page を参照してください。ファイル・ディスクリプタからシグナルを送る詳細は man 2 fcntl を参照してください。

open - HPET timer を開く

  • SYNOPSIS
    int open(const char *hpet_path, /* open mode */ O_RDONLY);
    
  • DESCRIPTION
    未使用の HPET timer を開きます。殆どの Linux ディストリビューションで hpet_path は "/dev/hpet" となります。このパスは major = 10, minor = 228 のキャラクタデバイスノードです。未使用の HPET timer がない場合は、open は失敗し EBUSY エラーになります。オープン・モードに O_RDONLY を使用してください。
  • RETURN VALUE
    • return_value >= 0: HPET timer が割り当てられたファイル・ディスクリプタです。
    • -1: エラー
  • ERROR (HPET デバイス固有)
    • EINVAL: オープン・モードに書き込みモードが含まれている。
    • EBUSY: 未使用の HPET timer がない。すなわち、すべての HPET timer が使われている。
  • FILES
    • /dev/hpet
  • KERNEL SOURCE

close - HPET timer を閉じる

  • SYNOPSIS
    int close(int fd);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd に割り当てられた timer をクローズします。ファイル・ディスクリプタ fd に割り当てられた timer を開放し、timer は未使用状態になります。厳密に言えば、ファイル・ディスクリプタ fd に対する参照が全て無くなった時に timer は開放されます。ファイル・ディスクリプタ fd を二重化したり、メモリ・マッピングを行った時にファイル・ディスクリプタ fd に対する参照が増えます。timer を開放するときに次の処理を行います。
    • timer からの割り込みを止めます。
    • ハードウエアによる周期割り込み機能を使わない設定にします。
    • IRQ ハンドラを開放します。
  • KERNEL SOURCE

read - 割り込み回数を読みだしクリアする

  • SYNOPSIS
    int read(int fd, unsigned long *buf, /* size */ sizeof(unsigned long));
    
  • DESCRIPTION
    割り込み回数を読みだしてクリアします。割り込み回数は *buf に格納されます。size 引数に sizeof(unsigned long) を使ってください。サイズ引数は sizeof(unsigned long) 以上の値を指定できます。しかし、関数が成功した場合の戻り値は sizeof(unsigned long) と同じになります。
    • O_NONBLOCK モードで HPET timer をオープンした場合は read() は次のように動作します。
      • timer の割り込みが前回の read() から、今の read() までに発生していたならば、割り込み回数を *buf に格納し戻ります。
      • timer の割り込みが前回の read() から、今の read() までに発生していないならば、read() は EAGAIN エラーで失敗します。
    • O_NONBLOCK モード無しで HPET timer をオープンした場合は read() は次のように動作します。
      • timer の割り込みが前回の read() から、今の read() までに発生していたならば、割り込み回数を *buf に格納し戻ります。
      • timer の割り込みが前回の read() から、今の read() までに発生していないならば、read() は割り込み発生まで戻りません。
  • RETURN VALUE
    • sizeof(unsigned long): 成功
    • -1: エラー
  • ERROR (HPET デバイス固有)
    • EIO: 割り込み周波数が設定されていません。
    • EFAULT: buf で指したアドレス空間はアクセスできません。
    • EINVAL: size の値が sizeof(unsigned long) より小さい。
    • EAGAIN: 前回の read() システム・コールから割り込みは発生していません。
    • EINTR: シグナルを受けました。
  • KERNEL SOURCE
    hpet_read()

mmap - HPET レジスタをメモリ・アドレス空間にマップする

  • SYNOPSIS
    void *mmap(void *addr, size_t length, int prot, int flags, int fd, /* offset */ 0);
    int munmap(void *addr, size_t length);
    
  • DESCRIPTION
    mmap() と munmap() でファイル・ディスクリプタ fd に割り付けられた timer を含む HPET レジスタをメモリ・アドレス空間にマップします。このシステム・コールは fd に割り付けた timer を含んだ HPET ブロックの全てのレジスタをメモリ空間にマップします。mmap() が有効なポインタを返したならば、ポインタは HPET の "General Capabilities and ID Register" を指しています。
    length に指定できる値の範囲は [ 0x1 .. page size (equal to sysconf(_SC_PAGESIZE)) ] です。しかし、HPET の全てのレジスタと場合によっては他のデバイスのレジスタを含んだ範囲をページサイズあるいはそれ以上の範囲でメモリ・アドレス空間へマップします。
    offset は 0 にして下さい。
  • RETURN VALUE
    • return_value != MAP_FAILED: 関数が返したポインタは HPET "General Capabilities and ID Register" を指しています。
    • MAP_FAILED: HPET レジスタをマップ出来ません。
  • ERROR (HPET デバイス固有)
    • EACCESS: mmap() に対応していません。kernel が CONFIG_HPET_MMAP_DEFAULT を指定せずに構築されたか、kernel の boot パラメータに "hpet_mmap=0" が指定された状態で起動されました。HPET の mmap() 機能を使うには kernel の boot パラメータに "hpet_mmap=1" を指定して下さい。
    • ENOSYS:
      • kernel に HPET レジスタを mmap() でメモリ・アドレス空間にマップする機能が有りません。kernel が CONFIG_HPET_MMAP を指定されずに構築されています。この場合、kernl の boot パラメータに "hpet_mmap=1" を指定してもエラーになります。
      • HPET のハードウエア実装に起因する問題があります。HPET レジスタの位置がページ境界に合っていません。
  • KERNEL CONFIGURATION and PARAMETER
    HPET レジスタを mmap() 出来るようにするには次の条件を満たして下さい。
    • CONFIG_HPET_MMAP=y を指定して kernel を構築して下さい。
    • CONFIG_HPET_MMAP_DEFAULT=y を指定せずに構築された kernel ならば kernel boot パラメータに "hpet_mmap=1" を指定して下さい。
  • SEE ALSO
  • KERNEL SOURCE
    hpet_mmap()

F_GETOWN - ファイル・ディスクリプタのオーナーを取得する

  • SYNOPSIS
    int fcntl(int fd, F_GETOWN);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd のオーナーを取得します。オーナーはシグナルの送り先になります。
  • RETURN VALUE
    • 0: オーナーはありません。シグナルは送られません。
    • return_value > 0: プロセス ID 番号です。
    • return_value < 0: 負のプロセス・グループ ID です。エラーとして扱われる可能性があるので注意が必要です。F_GETOWN_EX を使うのが良いです。
  • KERNEL SOURCE
    F_GETOWN

F_GETOWN_EX - ファイル・ディスクリプタのオーナーを拡張仕様を使って取得する

  • SYNOPSIS
    struct f_owner_ex {
      int    type; /* F_OWNER_PID, F_OWNER_PGRP, or     F_OWNER_TID */
      pid_t  pid;  /* process id,  process group id, or thread id. */
    }
    int fcntl(int fd, F_GETOWN_EX, /* out */ struct f_owner_ex *owner_ex);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd のオーナーを取得します。*owner_e に結果が格納されます。詳細は F_SETOWN_EX を参照して下さい。
  • KERNEL SOURCE
    F_GETOWN_EX

F_SETOWN - ファイル・ディスクリプタのオーナーを設定する

  • SYNOPSIS
    int fcntl(int fd, F_SETOWN, int owner);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd のオーナーを設定します。オーナーはプロセス ID、負の値にしたプロセス・グループ ID です。fd に割り付けられた timer からプロセッサに割り込みが入りファイル・ステータス・フラグに O_ASYNC が論理和されていたならば、シグナルがオーナーに送られます。
  • KERNEL SOURCE
    F_SETOWN

F_SETOWN_EX - ファイル・ディスクリプタのオーナーを拡張仕様を使って設定します

  • SYNOPSIS
    struct f_owner_ex {
      int    type; /* F_OWNER_PID, F_OWNER_PGRP, or     F_OWNER_TID */
      pid_t  pid;  /* process id,  process group id, or thread id. */
    }
    int fcntl(int fd, F_GETOWN_EX, /* in */ struct f_owner_ex *owner_ex);
    
  • DESCRIPTION
    ファイル・ディスクリプタ fd に プロセス ID, プロセス・グループ ID, スレッド ID のいずれかを設定します。owner_ex->type で owner_ex->pid の種別を指定します。owner_ex->type は F_OWNER_PID (プロセス ID), F_OWNER_PGRP (プロセス・グループ ID), F_OWNER_TID (スレッド ID) のいずれかを指定します。owner_ex->pid には先の type の指定に従って値を設定します。
    fd に割り付けられた timer からプロセッサに割り込みが入りファイル・ステータス・フラグに O_ASYNC が論理和されていたならば、シグナルがオーナーに送られます。
  • KERNEL SOURCE
    F_SETOWN_EX

F_GETFL - ファイル・ステータス・フラグを取得する

  • SYNOPSIS
    int fcntl(int fd, F_GETFL);
    
  • DESCRIPTION
    この関数はファイル・ディスクリプタ fd の ファイル・ステータス・フラグに O_ASYNC フラグをセットまたはクリアするために使います。使用方法は F_SETFL の説明を参考にして下さい。
  • KERNEL SOURCE
    F_GETFL

F_SETFL - ファイル・ステータス・フラグを設定する

  • SYNOPSIS
    int fcntl(int fd, F_SETFL, int flags);
    
  • DESCRIPTION
    timer からの割り込みでシグナルを送るには、ファイル・ディスクリプタ fd のファイル・ステータス・フラグに O_ASYNC を論理和した値を設定して下さい。設定は次の擬似コード片のようにします。
    Expand allFold all
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    
    -
    |
    -
    |
    !
    |
    -
    |
    !
    !
    
    {       int     flags;
            flags = fcntl(fd, F_GETFL);
            if (flags < 0) {
                    /* error handling. */
            }
            flags |= O_ASYNC;
            if (fcntl(fd, F_SETFL, flags) != 0) {
                    /* error handling. */
            }
    }
  • KERNEL SOURCE
    F_SETFL, setfl(), #define O_ASYNC FASYNC

F_GETSIG - 送ろうとするシグナル番号を取得する

  • SYNOPSIS
    int fcntl(int fd, F_GETSIG);
    
  • DESCRIPTION
    timer 割り込み発生時に送るシグナル番号を取得します。
  • KERNEL SOURCE
    F_GETSIG

F_SETSIG - 送ろうとするシグナル番号を設定する

  • SYNOPSIS
    int fcntl(int fd, F_SETSIG, int signal);
    
  • DESCRIPTION
    timer 割り込み発生時に送るシグナル番号を設定します。
  • KERNEL SOURCE
    F_SETSIG, send_sigio()

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-11-07 (火) 12:29:30 (2364d)