実験(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コ
マンドを実行するときにはドライバ側で処理が必要になる。