USBNIX は、まず Linux で開発して、基本的な動作を確認し、その後で AVRで動かしている。AVR 版は、動くことが判っているパーツの割合が大きいので、(比較的)すみやかに動かすことができた。MinGW でも同じことができれば、AVR-CDCベースでなにかを作ろうとする人の参考になるだろうし、USBNIX を Windowsで動かしてみて、なにか作ってみようと思ってくれる人も出てくるかも知れない。そういう意味で、MinGW版を作りたいと思っている。
さて、MinGW というのは、WIN32API (のみ)を使うので dll のインストールが必要なく便利な開発環境だ。当然 USBNIX のキーボード入力をコンソールに対応すれば(細かいところは別にして)それだけで移植が終わると思っていた。
方針としては、WIN32API のコンソールAPIをすなおに使う。具体的には、エラー処理とか省いて簡略化すると次のようなかんじ。
#include <windows.h>
#include $lt;wincon.h>
初期化:
HANDLE conin;
DWORD conin_mode = 0;
conin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(conin, &conin_mode);
conin_mode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
SetConsoleMode(conin, conin_mode);
char usbcdc_getc(void) {
char buf[3];
DWORD nrec = 0;
while (!ReadConsole(conin, buf, 1 , &nrec, NULL)
|| nrec == 0)
;
return buf[0];
}
これが全然うごかない。でも、ためしに "コマンドプロンプト" の上で動かすと動いてしまったのだ。どうも MSYS のコンソール(rxvt) は、WIN32API で扱えるコンソールではないらしい。
WIN32API でコンソールとして扱うにはどうしたらよいのか? と考えてしまったので、はまりにはまった。結局、rxvt のソースを見たら MinGW のAPIとして提供していない termios を使っていたことがわかった。
これだと、cygwin の環境がなければ、移植できない。逆に cygwin さえあれば簡単で、termios のインターフェイスで OK ということになるのかも知れないい。でも、MSYSという環境は結構気に入っているので、コンソールアプリもそこでビルドし、かつ動かしたいところ。
WIN32APIはよく知らないが、CreateConsoleScreenBufferで コンソールを作って、イベントを送り込むようなことをすれば、 rxvt のコンソールを WIN32API で扱えるようにできるのかもしれない。まぁ、そこまでする気力はないので、termios.h と MinGW で使える tcsetattr/tcgetattr が用意できれば、対応できるようにだけはしておくけれども、通常は MSYS で実行したら GetConsoleMode がエラーになってアボートする程度にしておいた。
というわけで、中途半端ながら、最新版。→usbnix-0.4.tar.gz
参考になったページ(リンク)
MSYS/MINGW 環境設定、その1
MSYS/MINGW 環境設定、その2
Msysで日本語
追記:
MSYSのソースコード一式(msys-1.0.10-src.tar.bz2)をダウンロードしてみた。
その中の
msys/1.0/10/rt/src/winsup/cygwin/include/sys/termios.h
が、どうも 正しいヘッダファイルらしい。
あと、
msys/1.0/10/rt/src/winsup/cygwin/termios.cc
が、正しくコンパイルできれば、MSYSコンソール(rxvt)で動く USBNIX が作れそうだ。ただし、ビルドの方法はまだよくわかっていない。
ただ、termios.cc (のさらに一部)のために、18MB近いソースを扱うのはどうかという気がする。できれば、必要なものだけをシンプルにまとめて、USBNIX に添付したい。
追記2:
msys の bin にある msys-1.0.dll に termios で使用している関数 tcgetattr/tcsetattr が含まれていることがわかった。でこれを Google Code Search で調べる と libmsys-1.0.dll.a を使ってリンクすることがわかった。これは、結局 Msysで日本語に書かれていた msysDVLPR-1.0.0-alpha-1.tar.gzに含まれていた。
lib/gcc-lib/i686-pc-msys/2.95.3-1/include/sys/termios.h
lib/crt0.o
lib/libmsys-1.0.dll.a
を取り出し、termios.h 48行目の CTRL のバグを修正する。
次に usbnix-0.4 の usbnix.c の tcsetattr/tcgetattr の defineをコメントにしておいて、
gcc -DHAVE_TERMIOS -I. -nostdlib crt0.o usbnix.c minicrypt.c \
libmsys-1.0.dll.a -L/d/MinGW/lib -lmingw32 -luser32 \
-lkernel32 -lgcc -lmoldname -lmingwex -lmsvcrt
としてコンパイルすると ... MSYSコンソール(rxvt)の上で動くようになった。
そして、MSYS/MINGW 環境設定、その1 で知った日本語対応 ...
/d/msys/1.0/msys.bat で指定しているフォントを
Courier-12 → Terminal-14に変更する
を試してみたら、USBNIX で漢字が使えるようになった!
注意:
msys-1.0.dllを使えるようにした .. というのは、逆にいうと msys-1.0.dll がなければ動作しないということです。cygwin で動作したというのと意味的にはあまり変わりません。ものとしても msys-1.0.dll は、cygwin1.dll から枝分かれしたものです。MSYSのコンソールで動くようになったのと引き換えに、動作には MSYS を必要としますので注意してください。
追記2おわりに
追記2は内容からいって独立した記事にすべきだったかもしれない。でも、あまり取り上げると AVR研究から MSYS+MinGW研究にしたくなるので、追記にしておいた。それはともかく、termios が動き漢字も使えるのなら、ちょっとしたものをビルドしたり作ったりするのは、楽しそうだ。