実験(12)では、ドライバ内に実装した割り込みハンドラによって、ドライバ内
部で割り込みによる非同期処理を行なう方法を考えた。
今回は、割り込み発生時にユーザ空間のアプリケーションで非同期処理を行なう
方法を考える。
今までは、ユーザ空間のアプリケーションからドライバへ通信方法としてシステム
コールを使用したが、今回は、逆にドライバからユーザ空間へ非同期通信を実現
する方法としてシグナルを考えることにする。
シグナルは、プロセスとプロセスの間やプロセスとカーネルの間で非同期イベン
トを伝達するために使用される通信方法である。これは通信内容に合わせて複数
のシグナルが定義されている。それぞれのシグナルはカーネルで定義された値を
持っており、そのシステム上で使用可能なシグナルとその値は、ヘッダーファイ
ルの/usr/include/asm/signal.h
の内容を見れば分かるが、次のように
kill -l
コマンドで確認することもできる。
# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 32) SIGRTMIN 33) SIGRTMIN+1 34) SIGRTMIN+2 35) SIGRTMIN+3 36) SIGRTMIN+4 37) SIGRTMIN+5 38) SIGRTMIN+6 39) SIGRTMIN+7 40) SIGRTMIN+8 41) SIGRTMIN+9 42) SIGRTMIN+10 43) SIGRTMIN+11 44) SIGRTMIN+12 45) SIGRTMIN+13 46) SIGRTMIN+14 47) SIGRTMIN+15 48) SIGRTMAX-15 49) SIGRTMAX-14 50) SIGRTMAX-13 51) SIGRTMAX-12 52) SIGRTMAX-11 53) SIGRTMAX-10 54) SIGRTMAX-9 55) SIGRTMAX-8 56) SIGRTMAX-7 57) SIGRTMAX-6 58) SIGRTMAX-5 59) SIGRTMAX-4 60) SIGRTMAX-3 61) SIGRTMAX-2 62) SIGRTMAX-1 63) SIGRTMAX |
デバイスドライバからの非同期通信ではシグナル番号が29で、シグナル名が
SIGIO
のシグナルを使用する。SIGIO
は、
入出力が可能になったことを通知するI/O
シグナルである。
シグナルを使用するときに、アプリケーション(dio_tst)
側で必要となる
処理は次のようになる。
最初に、sigaction
関数を使用してSIGIO
に対応するコールバックを登録
する。次に、fcntl
システムコールのF_SETOWN
コマンドを使用してシ
グナルを受けるプロセスのプロセスID
を設定する。
最後に、fcntl
システムコールのF_GETFL
コマンドと
F_SETFL
コマンドを実行して、非同期通信を行なうためのフラグ
(FASYNC)
を追加している。
fcntl
システムコールは、今までに使ったioctl
システムコールと
同じように第2引数に指定したコマンドによって、異なる動作を行なう関数であ
る。
ioctl
と異なる点は、ファイルデスクリプタに対しての操作を行なうシス
テムコールであることと、一部のコマンドを除いてシステム側で自動的に処理さ
れるので、コマンドの内容をドライバ側に実装する必要がないことである。
シグナルの設定を行なう際にはF_SETOWN
、F_GETFL
、
F_SETFL
の3つのコマンドを使用しているが、このうちF_SETFL
コ
マンドを実行するときにはドライバ側で処理が必要になる。