Thu 05/27, 2010

NetBSD/USL-5P でボタン押下検出 [Computer and Networking ]

最新のデバイスには背を向けた振りをして古い機械をいじり回す日々。今日は IO-DATA の USL-5P。当家では NetBSD を仕込んで使っている。USL-5P のオリジナル Linux ファームウェアには buttond というボタン押下検出デーモンがあって、これはソースコードが公開されていないものの Debian 化などしたものでもバイナリを持ってきて使用することができる。NetBSD/landisk ポートに、この buttond に相当するものは含まれていないようだが、powerd で電源ボタンの押下を検知して電源オフには対応している。また、その他のボタンについては /var/log/message に "remove: btn_event_send can't handle me." のようなログが出力されることから、カーネルレベルでは対応していることが判る。そこで usr.sbin/powerd や sys/arch/landisk/dev/ のコードを見てプログラムを書いてみた。

まず # cd /dev; mknod button c 84 0 としてデバイスファイルを作成しておく。 でもって button.c をコンパイルして実行し、ボタンを押すと次のような出力が得られる。

$ ./button
read
[select] button pressed
read
[remove] button pressed
read
[copy] button pressed
read
^C
$

要は /dev/button デバイスを読めば良いのだが、この時に 32 byte (BUTTON_EVENT_MSG_SIZE)単位で読まなければならないことに注意する。read(2) の読み取りサイズで違う値を指定すると -1 が返され、errno = EINVAL となってしまう。読み込んだ 32 byte の最初の 4 byte がイベントタイプだが、これは 0 (BUTTON_EVENT_STATE_CHANGE) しか返されない。それ以降がボタン識別文字列になっていて、上記のようにボタンにより 'select', 'remove', 'copy' となる。null char の後はゴミデータだ。ボタンが押されるまで read はブロックされるから、powerd のように kevent (2) を使うまでも無いと思うが、kevent を使う方法、使わない方法の両方を試した。

Posted by masato at 10:26 PM
このエントリーのトラックバックURL: http://bird.dip.jp/cgi-bin/mt/mt-tb.cgi/1761
コメントする

おそらく携帯電話等からは投稿できません。日本語文字列を含まないコメントやトラックバック、および当サイトへの言及を含まないトラックバックは御遠慮いただいております。また、90日以上経過した記事へのコメントはできません。










名前、アドレスを登録しますか?