試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Linux上におけるフォースフィードバックの振動の低レベル制御に関するメモ(前半)

GNU/Linux上の振動対応ジョイパッドデバイスの振動テストを行うGUIツールを作成」のGUI振動テストツール作成上のメモの内、フォースフィードバック関係の(低レベル/OS依存な)操作に関するメモを扱う。ここで扱うのは主にカーネル付属ドキュメントのDocumentation/input/ff.txtに書かれている内容となる。検索(google:ff.txt)をするとWeb上にもあるようだ。
なお、ここでは扱わないが、SDLというライブラリでは次期バージョンの1.3系から抽象化された(特定のOS向けの書き方に依存しない/クロスプラットフォームな)フォースフィードバックサポート機能が追加されるようだ(参考)。

必要なヘッダファイル

フォースフィードバック関係の処理を行うために、少なくとも以下のヘッダファイルを参照する必要がある。Linux(カーネル)のヘッダファイルも用いる。

#include <linux/input.h>
#include <unistd.h>
#include <fcntl.h>

fcntl.hopen(),unistd.hclose()write()のために用いる。linux/input.hフォースフィードバック関係の構造体やマクロを用いるために必要。

イベントデバイスファイルを開く

まずは/dev/input/event[数字]のデバイスファイルをopen()関数で開き、ファイル記述子を得る。その際にはモードをO_RDWRとし、書き込み(データの送信)もできるようにして開く。
失敗すると-1が返るので、この値で成功か失敗かをチェックする。

int fd_eventdev;
fd_eventdev = open (eventdev, O_RDWR);
/* (fd_eventdevが-1かどうかのチェックをしておく) */

どのデバイスファイルを開けばよいのかの要領については「PSX-CV02上の PlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第3回)」で扱っている。実際にはディレクトリを開いて中の項目を調べる(Cライブラリではopendir(),GLibではg_dir_open()やGIOのg_file_enumerate_children()を用いる)などの処理が必要となる。

振動サポートのチェック

バイスフォースフィードバックのどの種類をサポートしているのかをioctl()関数でEVIOCGBIT()という引数付きマクロによるリクエストを送って調べる。
事前に「1 + FF_MAX / sizeof (unsigned long)」の長さを持ったunsigned long型の配列を用意し、ここに入れるように指定する。
これをユーザ定義の引数付きマクロtest_bit()によりチェックする。振動のサポート状態をチェックするには1つ目の引数にFF_RUMBLEを指定するが、他の種類も同様にしてFF_CONSTANTなどを指定することでチェックできる。マクロはfftestのソースに定義されているものを流用すると楽。

#define BITS_PER_LONG        (sizeof (long) * 8)
#define OFF(x)               ((x) % BITS_PER_LONG)
#define LONG(x)              ((x) / BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG (bit)] >> OFF (bit)) & 1)

...

unsigned long features[1 + FF_MAX / sizeof (unsigned long)];

if (ioctl (fd_eventdev, EVIOCGBIT (EV_FF, sizeof (features)), features) == -1)
{
  /* サポート状態の問い合わせに失敗した場合の処理 */
}
if (test_bit (FF_RUMBLE, features))
{
  /* 振動がサポートされている場合 */
}
else
{
  /* 振動がサポートされていない場合 */
}

(「Linux上におけるフォースフィードバックの振動の低レベル制御に関するメモ(後半)」に続く)

関連記事:

使用したバージョン: