このページは HPET driver が提供する API をまとめたページです。map ページに似た書式を使います。man page の書式に次の修正・追加をしています。
HPET ドライバには次の機能が備わっています。
より詳細な情報は HPET 仕様書 を見て下さい。
多くの Linux ディストリビューション では HPET ドライバを有効化して構築されています。/dev/hpet ノードが用意されています。/dev/hpet ノードはキャラクタ・デバイス・ノードで major=10, minor=228 という番号が付いています。"misc device" の一つです。
HPET を使うには /dev/hpet を O_RDONLY モードで開きます。未使用の HPET timer が有れば、一つの timer を開いたファイル・ディスクリプタに割り当てます。timer は HPET 回路ブロックに複数ある timer のうちの一つです。ioctl() システム・コールでファイル・ディスクリプタに割り当てられた timer を操作します。
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 を提供しています。
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 を参照して下さい。
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);
メンバ | 説明 |
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) をそれぞれ置き換えるために使われているからです。 |
int ioctl(int fd, HPET_IRQFREQ, unsigned long frequency);
int ioctl(int fd, HPET_EPI);
int ioctl(int fd, HPET_DPI);
int ioctl(int fd, HPET_IE_ON);
int ioctl(int fd, HPET_IE_OFF);
この節では HPET ドライバに関係するファイル・システムとメモリ・マップ API について説明します。open(), close(), read(), mmap(), munmap(), fcntl() とこれらの類似関数を HPET に対して使うと、HPET 特有の動作をします。ここでは HPET 特有の動作を示します。ファイル・システムの基本的な動作と詳細はシステム・コールの man page を参照してください。ファイル・ディスクリプタからシグナルを送る詳細は man 2 fcntl を参照してください。
int open(const char *hpet_path, /* open mode */ O_RDONLY);
int close(int fd);
int read(int fd, unsigned long *buf, /* size */ sizeof(unsigned long));
void *mmap(void *addr, size_t length, int prot, int flags, int fd, /* offset */ 0); int munmap(void *addr, size_t length);
int fcntl(int fd, F_GETOWN);
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);
int fcntl(int fd, F_SETOWN, int owner);
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);
int fcntl(int fd, F_GETFL);
int fcntl(int fd, F_SETFL, int flags);
int fcntl(int fd, F_GETSIG);
int fcntl(int fd, F_SETSIG, int signal);