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 の仕様を知るためにサンプルプログラム
hpet_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_INFO | timer の情報を取得します 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_ON | timer からの割り込みを許可します int ioctl(int fd, HPET_IE_ON); |
HPET_IE_OFF | timer からの割り込みを禁止します 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_flags | timer の機能。 次の値のいずれかになります。 0x00UL ハードウエアで実装された周期割り込み機能がありません。 0x10UL ハードウエアで実装された周期割り込み機能が有ります。 解析で気づいたこと: 将来的にはビットフィールドで示される可能性がありそうです。 |
hi_hpet | プラットホーム上で番号づけられた HPET デバイス番号です。(hi_hpet >= 0) && (hi_hpet < M) を満たします。M はプラットホーム上に存在する HPET デバイス(回路ブロック) 番号です。 注: HPET デバイス(回路ブロック) の中に複数の timer があります。 |
hi_timer | HPET デバイス(回路ブロック) 中の 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
- ERRORS
- EBADF: ファイル・ディスクリプタの値が正しくない。
- EFAULT: info が指しているメモリにアクセスできない。
- KERNEL SOURCE
HPET_INFO
HPET_IRQFREQ - 割り込み周波数(Hz)を設定します †
HPET_EPI - ハードウエアによる周期割り込み機能を使うようにします †
HPET_DPI - ハードウエアによる周期割り込み機能を使わないようにします †
HPET_IE_ON - timer からの割り込みを許可します †
HPET_IE_OFF - timer からの割り込みを禁止します †
HPET と関係する ファイル・システム と メモリ・マップ API †
この節では HPET ドライバに関係するファイル・システムとメモリ・マップ API について説明します。open(), close(), read(), mmap(), munmap(), fcntl() とこれらの類似関数を HPET に対して使うと、HPET 特有の動作をします。ここでは HPET 特有の動作を示します。ファイル・システムの基本的な動作と詳細はシステム・コールの man page を参照してください。ファイル・ディスクリプタからシグナルを送る詳細は man 2 fcntl を参照してください。
open - HPET timer を開く †
close - HPET timer を閉じる †
- SYNOPSIS
int close(int fd);
- DESCRIPTION
ファイル・ディスクリプタ fd に割り当てられた timer をクローズします。ファイル・ディスクリプタ fd に割り当てられた timer を開放し、timer は未使用状態になります。厳密に言えば、ファイル・ディスクリプタ fd に対する参照が全て無くなった時に timer は開放されます。ファイル・ディスクリプタ fd を二重化したり、メモリ・マッピングを行った時にファイル・ディスクリプタ fd に対する参照が増えます。timer を開放するときに次の処理を行います。
- timer からの割り込みを止めます。
- ハードウエアによる周期割り込み機能を使わない設定にします。
- IRQ ハンドラを開放します。
- KERNEL SOURCE
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 - ファイル・ディスクリプタのオーナーを取得する †
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 - ファイル・ディスクリプタのオーナーを設定する †
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 - ファイル・ステータス・フラグを取得する †
F_SETFL - ファイル・ステータス・フラグを設定する †
F_GETSIG - 送ろうとするシグナル番号を取得する †
F_SETSIG - 送ろうとするシグナル番号を設定する †