ぱたぱたキーボードを LinuxZaurus に接続する(ソフト編)


トラップ <CXL00145_AT_nifty.com>
2003.08.13 Create
2005.03.13 Modify

linux zaurus with stowaway keyboard
対応確認機種:SL-C7x0/860/C3000

ハードが出来たらソフトもね

先の ハード編では、 stowaway keyboard と通信するためのちょっとした回路を製作しました。 ここでは、キーボードからキーコードを得て、 普通にキーボードとして使えるようにしてみます。

なお、本文では SL-Cシリーズとして SL-C7x0/860 に合わせて記述していますが、 SL-B500, SL-C3000 でも動作します(一部キーコードが異なるので、キー割り当てファイルの変更要)。


概要

外部キーボードを実現するポイントは次の3つです。

  1. キーボードからキーコードを受信
  2. キーコードの変換
  3. OSへキーコードを送信
色々やり方はあると思いますが、ここでは、 キーボードからの受信とキーコード変換をユーザーレイヤのプログラムで行います。 OSへのキー入力は、VNCの kbdsim ドライバへの WRITE による方法と、 (SL-Cシリーズ/B500 限定ですが) sharp_kbdctl ドライバへの ioctl で行う方法があります。 縁起物なので、どちらも使えるようにしてみましょう。


キーボードからキーコードを受信

Zaurus の I/Oポートは /dev/ttyS0 に割り当てられています。 stowaway keyboard の通信プロトコルは、9600bps, data 8bit, non parity, stop 1bit ですので、 この設定でポートを開いて読み込めばいいだけです。 単純なシリアルポート入出力ですので、実際に試してみた方が早いでしょう。

キーを押すことで、どんなコードが受信されるか確かめたのが次の表です。 キーが離された時は、このコードに $80 を OR した値が届きます。

[stowaway keyboard (for visor) key scan code]

コードキー コードキー コードキー コードキー コードキー コードキー
$001 $10x $20 $30- $40* $50Delete
$012 $11a $21 $31\| $41Enter $51
$023 $12s $22Fn $32BS $42ToDo $52
$03z $13d $23Alt $33予定表 $43 $53
$044 $14f $24 $348 $44j $54
$055 $15g $25 $359 $45k $55
$066 $16h $26 $360~ $46l $56
$077 $17空白 $27 $37Space/New $47+ $57
$08Cmd $18Caps $28 $38@ $48?_ $58LShift
$09q $19tab $29 $39{ $49 $59RShift
$0aw $1aCtrl $2a $3a} $4aメモ帳
$0be $1b $2b $3bアドレス $4b
$0cr $1c $2cc $3cu $4cm
$0dt $1d $2dv $3di $4d<
$0ey $1e $2eb $3eo $4e>
$0f/^ $1f $2fn $3fp $4f終了

具体的には、'A' のキーが押されたら $11 のコードが届き、 'A' のキーが離されたら、最上位ビットを立てたコード $91 が届きます。 なお、今離したキーで、全てのキーが離されているという場合には、 最後に離されたコード(この場合だと $91)が、もう1回届きます。 詳細は参考文献にありますので、そちらをご覧ください。


キーコードの変換

当然の事ですが、stowaway keyboard と Zaurus とではキーコードが異なります。 だから、受け取ったコードをそのまま送信しても満足にキー入力できるわけはなく、 コードの変換処理が必要です。

・・・とは言っても処理は簡単です(単にテーブルを引くだけ)。 面倒なのは、Zaurusにどんなキーコードを送らなければならないか調べることです。 まずは、SLシリーズの技術サポートページに情報がありますので、それが参考になるでしょう。

ただ、それだけではちょっと情報が不足してましたので、 カーネルソースを展開し sharp_keycode.h を見て 試行錯誤でテーブルを作りました。


OSへキーコードを送信

ここまでは、ユーザーレイヤで動いているプログラムが、 キーボードとシリアル通信を行っているだけに過ぎません。 何とかして OS に渡してあげる必要がありますが、 さて、どうしましょ。

・・・というわけで、再びカーネルソースを参照すると、 キーコードとキーのOn/Off状態を引数にして handle_scancode() を呼び出せば良いとあります。 これはドライバのレベルで呼ぶのですが、 都合の良いことにユーザーレイヤのプログラムから簡単に使える方法があります。

1つは VNC のキー入力用ドライバ kbdsim の利用。 参考文献を読むと、/dev/kbdsim に キーコードと キーのON/OFF状態を 2byte 1組で WRITE してあげれば、 kbdsim 内部で WRITE 要求を受け取って handle_scancode() してくれるそうです。 VNC Server が入っていれば(入ってなくても kbdsim.o を入れて insmod すれば) 機種非依存で使えて便利です。

そしてもう1つは、SL-Cシリーズ/B500 限定ですが sharp_kbdctl.c の IOCTL を使う方法です。 カーネルソースを展開して見てもらえばわかりますが、/dev/sharp_kbdctl を開いて、 SHARP_KBDCTL_SENDKEY で 4byte の値を渡してあげれば、 一度に ON/OFF 情報を含めて 最大6個 のコード送信ができます。 他にもキーボード制御のIOCTLがあるので、機種限定とはいえ結構便利に使えます(最初から入ってますし)。

ともかく、このいずれかを使ってあげれば、ユーザーレイヤからキー入力できます。


ser_code_ksim の移り変わり

以上を踏まえて 2003年2月 に作成し、日記ページで公開したのが、ser_code_ksim の初版です。 ser_code をベースに、 ksim を真似て /dev/kbdsim によるキー入力から始めたため、 ser_code_ksim という名称にしました。

ser_code_ksim 2003年2月版(日記公開版)

公開した最初の ser_code_ksim。 借り物の SL-C700 を使って2日間で仕上げたものなので、 とりあえず動かしてみたというレベルでしかありません。 実際、問題点も多かったですね。

これらの問題はあったものの 端末エミュレータ上だけでなく GUI上でも普通に使え、 CtrlキーもPCとほぼ同様に使えるなど、やはり外部キーボードは便利だと再認識させてくれました。

ser_code_ksim 2003年7月版(未公開版)

SL-C760 を導入したので、約束どおり ser_code_ksim の不具合を修正。 palm 用キーボードには対応していないものの、キーリピートも効くし、 CPU負荷も大幅に減らして実用的なものとなりました。

ただし、どうせ公開するなら palm キーボード対応版に仕上げてからの方が良いだろうというのと、 キー割り当ての自由度を高めたいといった理由から、ごく一部の方にテストしてもらったのみで 未公開としています。

ser_code_ksim 2003年8月版 1.0.0

多くの不具合を解消し、新たに次の機能を追加。

概ね、こんなところで機能的には一区切りでしょうか。 残件としては、もし palm用キーボードからの HotSync 信号を WakeUp で受けられるのであれば、 それに対応させればよりスマートかな?というところです。

ser_code_ksim 2003年12月版 1.1.0

パッケージ化するついでに、処理の見直しを行いました(一番時間かかったのはアイコン作成でしたが・・・)。

※なお、パッケージ名の都合で - (ハイフン)と _ (アンダースコア)が、 従来とは逆になってしまいました(実行ファイルはそのまま)。

2004年11月

SL-C3000 のキーコードが従来と一部異なるため、専用のキー割り当てファイルを作成しました。 従来の SL-C 用キー割り当てファイルも一緒に 下記 download に置いておきます。 ダウンロードして、/opt/QtPalmtop/etc/ 以下に入れて使ってください。


インストール

ipk ファイル の場合

設定タブの、ソフトウェアの追加/削除 から行ってください。 インストールされるファイルは下記になります。

tar ball の場合 (old: for 1.0.0)

アーカイブをどこか適当な実行パスの通っているところに展開してください。 /usr/local/bin/ に展開してもいいでしょうし、 /home/zaurus/ に展開しておいてターミナル開いて ./ser_code_ksim で実行というのでもいいでしょう。 この辺りはお好みに合わせてということで。

[ホームディレクトリ(/home/zaurus/) に入れた場合の例]

  # cd /home/zaurus
  # tar xzvf ser-code-ksim_1.0.0.tar.gz
展開すると、実行ファイルである ser_code_ksim と、設定ファイル ser_code_ksim.ini, ser_code_direct.ini, ソースファイル ser_code_ksim.c ができます。 使うだけであれば、ソースファイルは不要ですから消しても結構です。


アンインストール

ipk ファイル の場合

設定タブの、ソフトウェアの追加/削除 からアンインストールしてください。

もし設定ファイル (ser_code_ksim.ini) を変更した場合は消されずに残るはずですので、 不要なら手作業で消してあげてください。

tar ball の場合 (old: for 1.0.0)

展開したもの (ser_code_ksim, ser_code_ksim.ini, ser_code_direct.ini, ser_code_ksim.c など) を削除してください。

[ホームディレクトリ(/home/zaurus/) に入れた場合の例]

  # cd /home/zaurus
  # rm ser_code_ksim ser_code_ksim.ini ser_code_direct.ini ser_code_ksim.c


使い方

起動と停止

ipk の場合の起動

Home の アプリケーションタブに、keyboard start と joypad start, kbd/js stop の 3つのアイコンがありますので、 こちらから起動/停止が可能です。

実際には、シェルスクリプト sck_kup, sck_dup, sck_down を呼んでいるだけですので、 コマンドラインからスクリプトを実行しても構いません。

tar ball の場合の起動 (old: for 1.0.0)

複数のターミナルが上がる環境であれば、ser_code_ksim のあるディレクトリに移って、 ./ser_code_ksim で起動するのが楽でしょう(止める時も Ctrl-C で止められるし)。 ターミナルが1つしか上がらない環境ならば、./ser_code_ksim -b でデーモン化すると良いです。 カレントディレクトリに設定ファイルが無い場合は、 後述の -m オプションで設定ファイルの場所を指定してあげてください。 設定ファイルを複数用意しておいて、-m オプションで配列を切り替えて使うということも可能です (CapsLock に Ctrl を割り当てた配列だとか、US配列だとか)。

※無論、PATH の通ったところに実行ファイルを置いた場合は ser_code_ksim で実行できます。

フォアグラウンドで動いている場合の停止

Ctrl-C で停止させてください(Zaurus本体キーボードなら Fn + C)。 シグナルを受けるとポートを閉じて正常に終了します。

デーモン化したなど、バックグラウンドで動いている場合の停止

ser_code_ksim のプロセス番号を調べて、kill でシグナルを送ってください。 シグナルを受けるとポートを閉じて正常に終了します。

  # kill `ps -o pid= -C ser_code_ksim`

  または

  # ps -ef | grep ser_code_ksim | grep -v grep
  # kill 調べたプロセス番号

起動オプションの説明

ヘルプの表示

ser_code_ksim -h で使い方が表示されます

  # ./ser_code_ksim -h
  Usage: ser_code_ksim [OPTION]
  -p : serial port device name (defalt: /dev/ttyS0)
  -k : vnc kbdsim module use
  -i : debug info print
  -d : direct mode
  -b : background daemon
  -v : print version
  -h : display this message
  -m : key mapping file name
       default: /opt/QtPalmtop/etc/ser_code_ksim.ini (or ser_code_direct.ini)

ポートや設定ファイルを指定したい場合

デフォルトではシリアルポートとして /dev/ttyS0 を、 設定ファイルは /opt/QtPalmtop/etc/ser_code_ksim.ini (ダイレクトモード時は ser_code_direct.ini) を見るようになっています。 例えば、シリアルポートに /dev/ttyS1 を使い、設定ファイルは /etc/ser_code_ksim.ini を使う場合には、 次のように指定することになります。

  # ./ser_code_ksim -p /dev/ttyS1 -m /etc/ser_code_ksim.ini

VNC の kbdsim ドライバを使いたい場合

標準では、/dev/sharp_kbdctl を使ったキー入力を行いますが、 VNC の /dev/kbdsim を使う場合には、-k オプションを指定してください。 なお、/dev/kbdsim は通常は root 権限でないと使えないようになっていますので、 su して root ユーザになってから実行するとかしてください。

  # ./ser_code_ksim -k

キーコードを見るなどデバッグ情報を表示したい場合

  # ./ser_code_ksim -i

ゲーム用に、ダイレクトモードで利用したい場合

通常モードでは、キーを押すことで Zaurus 用のコードを作成してキー入力を行います。 この時、内部的にはキーを離す処理や、キー割り当て変更により意図しないキーも押されます。 普通の文書入力ならこれでも良いのですが、 キーのON/OFF状態を必要とするゲームのようなアプリケーションにとっては困るため、 修飾キー処理を行わずに "N" 指定の行のみ有効とし、キーを押した/離したをダイレクトに OS に伝えるモードです (この場合、設定ファイルには修飾キー Shift, Ctrl, Fn, cMd の分も通常キーとして設定しておく必要あり)。

  # ./ser_code_ksim -d

バックグラウンド・デーモン化したい場合

単に ser_code_ksim を起動したのでは、そのターミナルが占有されてしまいます。 ser_code_ksim & のようにすれば裏にまわすことができますが、 それでも起動したターミナルに関連づけられていることに変わりはありません。 -b オプションを指定すれば、バックグラウンドで動くデーモンになってくれます。

  # ./ser_code_ksim -b

※なお、標準の Terminal (qpe-terminal-ja_1.5.0-3_arm.ipk) では、それでも少々問題が出る (実行した後に Terminal を閉じてしまうと、停止するまで Terminal に入れなくなる)があります。 embedded-console 等を使うか、または 1.1.0 から追加した HOME 画面からの起動/停止が便利でしょう。


キー割り当て設定ファイルの書式

2003年12月版から、設定ファイルの位置が変わりました。 -m オプションで明示的に指定しなければ、モードに応じて次のファイルが使用されます。

2003年8月版以降から、キー割り当て設定ファイルのフォーマットが大きく変わりました。 設定ファイルは、大きく分けて "キーリピート速度の設定", "修飾キーの定義", "通常キーの定義" の3つのブロックに分かれ、修飾キーも含めて任意の割り当てが可能です。 行頭が # (シャープ)の行や空行はコメント行として無視されます。 付属の ser_code_ksim.ini をもとにして、 好みの割り当てに修正して使うと良いでしょう。

[修飾キーの定義とその役割]

キーは、それ自身では働きを持たない修飾キーと、それ自身で働く通常キーの2種類にわけられます。 修飾キーは、(便宜上)Shift, Ctrl, Fn, cMd の4種類があり、それぞれ最大 2個 定義可能です。 これら修飾キーは、通常のキーが押された時に、どのコードを出力するかを選択するためにあります。 つまり、普通は '1' なのに、Shift を押しながらだと '!' になるといったものです。

便宜上、Shift,Ctrl,Fn,cMd と呼んでいますが、別にその通りのキーを割り振る必要はなく、 例えば stowaway keyboard の CapsLockキー(A の左隣)を Ctrl にしても良いのです。 何でしたら、親指シフトキーボードのような配置にしても構いません。 Shift, Ctrl は必須でしょうが、Fn, cMd などは必要なければ修飾キーとして定義しなくても結構です。

[キーリピート速度の設定]

書式: {keyrep_first | keyrep_next } 値(1〜32)

first は初回のリピート開始までの時間、nextはそれ以降のリピート時間。 どちらも 0.1秒 単位で指定し、値が大きいほどリピートが遅くなります。 デフォルトで 3, 1 に指定されていますので、変更の必要はないでしょう。

keyrep_first	3
keyrep_next	1

[修飾キーの定義方法]

書式: {lshift | rshift | lfn | rfn | lcmd | rcmd | lctrl | rctrl } stowawayのキーコード

Shift, Ctrl, Fn, cMd のそれぞれの役割に対し、左右の2個(l,r)を指定可能。 以下の例では、左シフト、右シフト、左Fn、左Cmd、左Ctrl のみを定義している。 修飾キーとして指定したキーは、たとえ通常キー定義で指定されていても、こちらが優先される。

lshift	58
rshift	59
lfn	22
lcmd	08
lctrl	18

[キー割り当て設定の方法]

書式: stowawayのキーコード コメント 修飾キー組み合わせ(SCFMN) 4byteのZaurusキーコード指定

A のキーに対する定義例を以下に示します。 stowaway キーボードで A が押されると 11 が来ますから、第1項目は 11 ですね。 第2項目は、人が見てわかりやすいようにキーの名称などを記述します(空白,TAB は含めてはならない)。 第3項目は、修飾キーがどの状態の時の設定かを示します(後述)。 第4項目は、この時に Zaurus に送るキーコードの指定です(後述)。

11	a	N	03000001
11	A	S	0f001b01
11	^A	C	0f006801
11	^A	CS	3f1b6801
この例では、そのまま押した時には 03000001 を出力。 Shiftキーを押しながらなら 0f001b01 を出力。 Ctrlキーを押しながらは 0f006801 を出力。 CtrlとShiftを一緒に押しながらなら 3f1b6801 を出力します。 他の修飾キーの組み合わせの場合は、何も出力しません。

[修飾キー組み合わせ(SCFMN)]

通常キーの定義行での、修飾状態の指定について説明します。

何の修飾キーもいらない場合(そのまま押した場合)の指定には N を、 Shift を押している時なら S を、 Shift と Ctrl を押している時なら SC のように修飾子を並べて指定します(順番は関係ないので CS でも同義)。 CFMS のように指定した場合には、Ctrl, Fn, cMd, Shift の修飾キー全てが押されている時という指定になります。

CS と記述した場合には、Ctrl と Shift が両方押されている時(AND条件)という意味ですので、 仮にどちらかが押されていれば良いという場合(OR条件)ならば、 C だけの行と S だけの行の 2行を記述してください。

[4byte の Zaurusキーコード指定]

上記で何の説明も無しに 03000001 だの 3f1b6801 だのと書いていますが、 これは /dev/sharp_kbdctl への送信指定に合わせた Zaurus のキーコード指定です。 この4バイトは、ON/OFF フラグと3つのZaurus用キーコードを合わせたもので、 上位バイトから順に、1バイトずつ, フラグ, コード3, コード2, コード1となっています。

フラグコード3コード2コード1
4byteコード3f1b6801

フラグバイトは 2bit ずつ 4組の値に分かれます。 上記の例では フラグバイトは 3f ですが、 これを2進数表記して 2bit ずつ分けると 00_11_11_11 となり、それぞれの組が コード3, コード2, コード1 に対応します。

---コード3コード2コード1
フラグ部bit00111111

2bitのフラグは、更に細かく見ると、 上位ビットがキーを離すコード送信の指定、下位ビットがキーを押すコード送信の指定となります。 1 を指定した場合にはコードを送信し、0 の場合には何もしません。 通常は、キーを押して離すで1セットですから、このように 11 となるのがほとんどでしょう。

Release flagPress flag
11

つまり、この例 ( 3f 1b 68 01 ) であれば、次のようなキー入力操作になるというわけです。

同様にして、0f 00 1b 01 であれば、

03 00 00 01 であれば、

と、なります。

要するに、3つのキーの ON/OFF 指定をまとめて表記しているだけだと考えてください。 面倒であれば、1byte xx を送るだけなら 030000xx で、2byte yy xx を送るなら 0f00yyxx で、 3byte zz yy xx を送りたいなら 3fzzyyxx を指定すると思ってください。

ちなみに、上記で例にあげた コードで、1b は Zaurus の左SHIFT、 68 は Zaurus の Ctrl キーという扱いになっています。 SL-C7x0/860 本体には Ctrl キーは存在しないのですが、コードとしては 68 でいけます (SL-C3000 では 38 です)。 Zaurus のキーコードについては、 カーネルソースの sharp_keycode.h や、/opt/QtPalmtop/etc/keycode.tbl が参考になります。

[参考: LinuxZaurus のキーコード]

SL-C7x0/860, C3000 で確認したキーコードの一部を載せておきます(16進数表記です)。

キーSL-C7x0/860SL-C3000
DELETE5151
TAB4141
SHIFT1b1b
ENTER1c1c
Fn1e1e
カナひら7945
全/半7a46
CTRL6838
ALT6a39
HOME2828
CANCEL (ESC)2222
OK2727
MENU1d1d
LEFT2323
UP2424
DOWN2525
RIGHT2626
カレンダー5858
アドレス帳5959
メール5a5a
*割り当て機能473a
メール受信実行6e6e
画面キャプチャ7373
PCリンク開始7575
BACK_SPACE1f1f
記号入力ボード20
Num Lock20
ライト(トグル)2121
電源OFF6d6d
漢字モード5f
縦持ち時のOK7b54?
同CANCEL7c5e
同ジョグアップ7d7d
同ジョグダウン7e7e
リモコン再生653d,40
リモコン停止643e,44
リモコン巻き戻し6342,74
リモコン早送り6243,6c
リモコンボリュームUP6076
リモコンボリュームDOWN6177
リモコンミュート78


KeyHelper との組み合わせ

ser_code_ksim はキーボードモードで動作している場合、 内部的にキーを押してから離すまでを一度に処理しています。 この為、KeyHelper で Zaurus の Address キーを Launch にした時などにうまく働きません。 その場合は、次のように 030000xx を 010000xx に変更してください。 前者は xx のコードを押して離す設定、後者は xx のコードを押すだけという設定です。

# アドレス帳を Launch に設定する例
42	ToDo	N	01000059

この他、Shift + Home などを利用したい場合には、 次のように Shift 時に送信するコードも指定しておく必要があります。

# Home, Shift + Home を働かせるための例
33	Yotei	N	03000028
33	Yotei	S	0f001b28

# Menu, Shift + Menu を働かせるための設定
3b	Address	N	0300001d
3b	Address	S	0f001b1d


download

バイナリだけで構わない方は ipk を、ソースも欲しい方は .tar.gz をどうぞ。

[ソフトウェア]

2003.12月版 ser-code-ksim_1.1.0
ser-code-ksim_1.1.0-1_arm.ipk
md5 : dd89da298574039b83b9f945cb295839 *ser-code-ksim_1.1.0-1_arm.ipk
ser-code-ksim_1.1.0.tar.gz
md5 : 13355ea04e647f4f9dbfc6b8bf251e6a *ser-code-ksim_1.1.0.tar.gz
2003.8月版
ser_code_ksim-1.0.0.tar.gz
md5 : c65d3062ceafb0218182834d2d86b913 *ser_code_ksim-1.0.0.tar.gz
2003.2月版
ser_code_ksim.tar.gz
md5 : 816045e23ee623e8101f59676ca6b081 *ser_code_ksim.tar.gz
(一応残していますが、もう使わないでしょう。リピートも効きませんし。)

[キー定義ファイル]

SL-C7x0/860
キーバインド説明
ser_code_ksim_inis_c7x0.tar.gz
(ser_code_ksim-jp.ini)
(ser_code_ksim-us.ini)
(ser_code_direct.ini)

SL-C3000
キーバインド説明
ser_code_ksim_inis_c3000.tar.gz
(ser_code_ksim-jp.ini)
(ser_code_ksim-us.ini)
(ser_code_direct.ini)

SL-B500 (参考程度)
キーバインド説明
ser_code_ksim_inis_b500.tar.gz
(ser_code_ksim.ini)

参考文献

  • ザウルス宝箱Pro (SLシリーズの技術サポート情報ページに、I/Oポート仕様書やカーネルソース類があります)
  • 4つ折りキーボード接続計画 for E1
  • 4つ折りキーボード接続計画
  • 他機種用キーボードについての補足
  • Linux serial keyboards
  • Interfacing the Palm Stowaway Keyboard to the serial port
  • VNC server
  • びっくまのゴミ置き場

  • [INDEX]