DS9とうとうDeepSpaceNineまでやってきました。メニュートップページログインエントリー2009年12月の記事は以下のとおりです。15:38カテゴリー:マニアックなおはなしAVRの開発環境を実現するために,MacBookProに仮想環境として,VitrualBoxを導入したことは先日書きました。このVirtualBox,実に良くできているので,簡単に紹介しておきたいと思います。VirtualBoxはSunMicrosystemsの製品で,無償かつオープンソースの仮想マシンソフトです。ライセンスはGPLv2に準拠していて,個人・商用を問わず利用出来ます。エンタープライズ用途向けに24時間対応のサポートが受けられるオプションもあります。個人的には,エンタープライズ用途向けをちゃんと目指していることを評価していて,その上きちんとアップデートを継続していることもよいと思います。現在のところ最新版はVer.3.1.0ですが,特にVer.3以降はかなりこなれてきたという印象があります。そもそも論ですが,昨今はやりの仮想マシンというのは,実機の上に複数のマシンを独立で構築する仕組みです。Windows上でX68000を再現するX68000エミュレータも一種の仮想マシンですし,Javaの実行環境はJavaVMといって,これも仮想マシンの一種です。これらは,ソフトウェアで別のマシンを実装するもので,実機のCPUが仮想マシンのCPU向けの命令をソフトウェアでいちいち翻訳しながら動作しています。動作が低速になることは想像が付くと思います。最近よく耳にする仮想マシンには,x86の上で,複数のx86を動作させる仮想マシンの話が多いようです。いえば昔仮想86モードなんてのを耳にしましたね。あれは80386上で仮想8086を実現するものでしたが,言ってみれば仮想8086が仮想x86に昇格した,という感じかも知れません。1台の実機上で複数のマシンを稼働できると,古い機種でしか動作しないソフトウェアをそのまま動作させる事ができたり,それぞれで異なるOSを動作させることができたりしますし,またそれぞれのマシンを完全に独立させることが出来る事から,セキュリティや信頼性の向上が期待できます。仮想マシンの実装には,元々1つしかないリソースを複数で共有し,互いに影響を与えないようにするために,仮想マシンモニタと呼ばれるソフトウェアがリソースの配分などを行う必要があります。この仮想マシンモニタはオーバーヘッドが大きく,処理速度の低下が深刻であったため,出来るだけオーバーヘッドが発生しないよう,機能の一部をハードウェアで支援できるような拡張が,近年のCPUには実装されつつあります。x86(正確にはIA32プログラミングアーキテクチャ)の場合,リング0からリング3までの特権レベルがあり,OSの低レベルの部分などはハードウェアリソースのほぼすべてにアクセスが可能なリング0で実装されてきたのですが,仮想マシンを実装する上で,OSがリング0で動作していては他のOSへの影響が避けられないため,仮想マシンモニタをリング0で動作させ,OSはリング1から3で動作させることになります。ところが,OSにはリング0のみ許される特権命令が含まれているため,リング1から3で動作している状態では例外が発生します。これを回避するため仮想マシンモニタが例外を監視し,例外が発生したら命令をエミュレートして,OSに結果を返すようにしていたのです。なんか,非常に重たそうなことをしないと,x86で仮想マシンを実現出来ないっぽいですね。1つ,x86で仮想マシンが面倒臭いというお話をしましょう。こっちはちょっと笑えます。popf命令などが例ですが,なんとユーザーモードと特権モードで動作の異なる命令がx86では存在しています。建て増しを繰り返してきたから,という意見もあるのですが,どっちにしても同じ命令で動きが違うなんて,ちょっとビックリです。これは仮想マシンモニタにすれば非常に迷惑な話で,この命令がリング1から3で動作しているOS上で見つかった場合,それは本来リング0での動作を期待されていて,リング1から3では動作させてはならないので,例外によって知らせて欲しいのに,実際にはどちらのリングにも存在する命令ゆえに,例外すら発生しないのです。いうことは,リング1から3で動作しているOSが発行する命令を,常時監視しなければならないわけです。VMwareなどは,こうした仕組みを実装し,もともと仮想マシンを考慮していないx86で仮想マシンを実現していました。これらの仮想マシンが高い評価を受けているのは,こうした重たい処理を必要としながらも,実用的な速度で動作する仮想マシンを実現したことにあると思います。ところが,こうした不細工な方法で無理矢理仮想マシンを実現するというのは,決して褒められたことではありません。そこで,x86にも仮想マシンをハードウェアで支援する機構が用意されるようになってきました。VT,AMDではAMD-Vと呼ばれるものです。それぞれ異なるものではありますが,やってることは基本的には同じです。リングプロテクションに関する支援です。リング0から3までをそれぞれ持つ,VMXrootとVMXnon-rootの2つのモードを用意しました。VMXrootでは仮想マシンモニタが動作しており,VMXnon-rootモードではOSを動作させます。OSが特権命令を発行した場合にはVMXrootモードに移行し,仮想マシンモニタに制御を移します。このように仮想マシンモニタが特権命令を監視しなくても良いので,オーベーヘッドは大幅に削減されることになります。仮想マシンごとにレジスタなどのコンテキストを保存する専用領域を用意してあり,これらの切り替えが自動化されるようになっています。このこともオーバーヘッドの削減に寄与しています。I/Oについても仮想マシンの実装支援が行われています。VT-dなどと呼ばれている機能です。仮想マシンでは,I/Oはそれぞれのデバイスのエミュレーションによって実装され,DMAを行う場合はアドレスのリマップが必要となります。このことは速度の低下に加えて,エミュレートされたデバイス用のデバイスドライバが必要になるため,従来のドライバをそのまま使用できなくなる場合があります。そこで,ハードウェアによってDMAのアドレスをリマップする機能を用意しておきます。すれば速度的にも有利な上,I/Oのエミュレートを行わないので従来のデバイスドライバがそのまま使えるようになります。した支援機構によって,従来に比べて2割ほど性能が向上するそうです。現在利用されているx86用の仮想マシンは,別にこれらの支援機構が必須になっている訳ではありません。多くがこれらの支援機構を利用出来るようにもなっており,対応したCPUを使えば,さらに速度や利便性の向上を期待できるというわけです。VTのうちVT-xとAMD-Vに対応しています。過去にはこれらを使うと速度が低下したケースもあったそうですし,他にもいろいろ問題が出ていたようですので,ちゃんと考えて使わないと失敗しそうです。私のMacBookProにインストールしてみます。ホストOSはSnowLeopardで,64bitカーネルです。ここにVirtualBoxの最新版である3.1.0をインストールしますが,これはあっさりと終了。VirtualBoxを起動すると,最初にディスクのイメージファイルを作る事になります。仮想ドライブの容量と同じ大きさのイメージファイルを作る方法と,イメージファイルの大きさが可変するものの2つを選ぶことが出来ますが,後者はドライブの容量サイズを変更できるという意味ではなく,これは最初にしていした容量のまま変えることが出来ません。仮想ドライブにデータを書き込むと,イメージファイルの大きさも大きくなるという仕組みで,ホストOS上に無駄にでかいファイルを置かずに済むということを狙ったものです。ここにWindowsXPをインストールします。MacBookPro内蔵のDVDドライブもVirtualBoxの支配下にあり,ここにWindowsのCD-ROMを入れて置けば,インストーラが起動して,いつものようにWindowsXPがセットアップされます。仮想マシンのメモリですが,あまり巨大なものを設定すると,ホストOSでスワップが発生し,パフォーマンスががた落ちになります,私の場合4GBを搭載しているので1GBくらいなら設定してもよいだろうと思いましたが,考えてみるとホストOSにとって1GBも占有するソフトが起動するというのは結構きついことで,スワップが発生すると大変なことになります。WindowsXPなら512MBもあれば十分です。インストールが終わればMacの画面上でWindowsが動くという見慣れない状況が起こりますが,それぞれちゃんと動いています。当たり前なのですが感動的です。デバイスドライバも普通のデフォルトでインストールされるので,特に問題はなく動くのですが,ここでGuestAdditionをインストールしておきます。VirtualBoxのメニューからGuestAdditionのインストールを選ぶと,Windows上でインストーラが動き出してさらに便利な仕組みが使えるようになります。便利なのが,マウスカーソルの移動です。デフォルトでは左のコマンドキーを押すごとにマウスカーソルがホストOSとゲストOSで切り替わるのですが,これが案外面倒です。ところがGuestAdditionをインストールすれば,VirtualBoxのウィンドウの上では自動的にゲストOSのものと判断され,そこから外れた領域ではホストOSのものとされます。通常のMacOSのソフトと同じようにマウスが動かせるということです。ネットワーク関連ですが,ここはなにも考えず,NATで設定すればOK。ホストOSとは異なるIPアドレスを割り振る必要があるだろうと思っていたのですが,NATを実装してあるので,ホストOSのネットワークを,ゲストOSが失敬するような仕組みになっているようです。グラフィック周りは期待しない方がよいのですが,一応2Dと3Dのアクセラレーションが有効に出来るようです。2Dのアクセラレーションはしない方がいいと警告されますし,3Dの方はチェックしても私の環境では有効にならないようでした。2Dのアクセラレーションが有効にならないという事はDirectXを使ったソフトは動作しないという事になるので,実は結構な数のソフトが動作しません。古いパソコンのエミュレータを動かそうと思っていましたが,ほとんどが無理でした。画面関係でいえば,最大解像度がXGAまでなので,これで狭いと思っても手がありません。MacBookProの画面の大きさを考えると,ホストOSの邪魔をしないようにするにはXGA位が適当だと思うので私はそれほど問題とは思っていませんが,確かに開発系の統合環境などは,窮屈な感じがします。USB周りは今回の目的,開発環境の動作のためには妥協できない部分です。そもそもハードウェアリソースとしてのUSBをホストOSとゲストOSで共有することになるのですから,排他使用になる事は当たり前です。どちらかでしか動作しないデバイスなら別にいいのですが,USBメモリのようなどちらでも使えるものはどうするか,です。なにも設定をしないと,まずホストOSでマウントします。この状態でゲストOSでマウントさせようとしても,グレイアウトしてマウントできません。そこでホストOSでアンマウントすると,ゲストOSでマウントします。そこでVirtualBoxでは,USBのIDを登録しておき,どちらのOSで使用するかを設定することが出来るようになっています。この方法で,AVRライタやMSP430のデバッガ,USB-シリアル変換ケーブル,USBメモリを登録しておきました。それぞれ,Windows用のデバイスドライバでなんの問題もなく動作しています。これは本当に期待通りです。ファイル共有ですが,VirtualBoxの設定からホストOS上のフォルダを指定しておきます。そのフォルダがhogehogeだったとすると,これがゲストOS上では\\vboxsvr\hogehogeとなりますので,これをネットワークドライブとしてマウントすればOKです。この程度の環境設定を行って実際に使ってみると,Macで動かしているという感覚を忘れてしまうほど,そのまんまWindowsです。速度も全く問題なく高速で動きますし,ホストOSに悪さをするようなこともありません。音もきちんと出ますし,光学ドライブもちゃんと共有出来るようになっています。VirtualBoxでWindowsを動かしつつ,iChatAVを使ってビデオチャットということも問題なく出来ていますので,メインはMacだが時々Windowsが欲しい,という程度の話であれば,それぞれに妥協をすることなく,両方のOSを同時に使用することが十分出来ると思います。本当に処理速度が欲しい,あるいはスタンバイや休止状態を確実に使用したい,グラフィック関係が動かないといけない,という場合にはBootcampで再起動をかけるしかありませんが,逆に言うとVirtualBoxでダメな場合にはBootcampという手があるという事ですから,MacBookを持っている人は無敵のパソコンを手に入れたに等しいと,私は感じました。以前からちゃんとした仮想マシンに興味があって,それは利便性だけではなく技術的な興味関心から,実際に使ってみたいと思っていたのですが,これだけ簡単に導入でき,しかも十分実用になるというのは,良くできているなあと感じました。私は以前PowerMac7600をPowerPCG3の500MHz程度で使っていた頃に,Connectixという会社のVirtualPCを使っていたことがありました。Windwos95を入れて,当時使っていたシャープのザウルスの母艦にしていたのですが,動作はあまりに遅く,忍耐なしで使う事は不可能でした。すべてのデバイスをエミュレーションするだけでななく,CPUでさえもエミュレーションしなければならなかったVirtualPCと比べるのはかわいそうですが,互換性においても速度においても,ただ動くというレベルから使えるレベルになっていることは,ユーザーにとって大きなメリットになっていると思います。ゲストOSが有償なら当然買う必要はありますが,VirtualBoxは無償で利用出来ますから,特にMacの人は便利だと思います。それまで一般のユーザーが使うことの出来なかった高度な技術がいとも簡単に利用出来るのが,PCの世界です。高速なクロック,膨大なメモリ,スーパースカラ,ベクトルプロセッサ,仮想メモリ,賢いコンパイラ,プリエンプティブカーネル,そして今回の仮想マシンと,すべて大型機のために開発された技術ばかりです。それがこうして安価に提供され,コンスーマ用に新しい活用方法が提案されて,より便利になっていきます。これから先,お手本とすべき大型機が不在になるなか,PCの進化はどちらを向くことになるのでしょうか。14:31カテゴリー:make:GPS時計ですが,その後も毎日のように検討を続けていました。GPSを使って時刻情報を得ていながら,1秒近くずれるというのはもはや言語道断といえて,何とかなるならしてみたいし,駄目な場合でも駄目な理由を理解してからあきらめたいと思ったからです。前回,UARTのボーレートを38400ボーにするということと,使っていないセンテンスは送出させないようにしたこと,それと1秒に1回だったデータの送信周期を1秒に2回にしたことで対応を図ったが,あまり良い結果が得られなかったことを書きました。最大で1秒弱の遅れは解消されず,遅れる時間も長かったり短かったりとバラツキがみられます。根本的にGPS本来の精度の時計を作るなら,GPSモジュールから1PPSの信号を得なければどうにもならない,ということもはっきりしました。ここまでが前回までのお話です。一般論としてですが,どうもGPSモジュールから出てくる時刻情報は,実際の時刻よりも少しだけ進んでいるのが普通のようです。進んだ時刻をマイコンが取り込み,その後やってくる1PPSの信号で表示を更新することで,GPS本来の精度の時計が実現出来るというわけです。今回使っているGT-720Fというモジュールはこの1PPSの信号が出ていませんので,そもそもGPS時計を作るのに適していないモジュールを選んでいることになります。それに,これまでいじった結果として感じるのですが,少し進んだ時刻が出ているかどうかもあやしいです。いうことで,1PPSがないと正確な時計を作る事が出来ないなら,GT-720Fから1PPSの信号を引っ張り出せないか,と考えました。ないことに,GT-720Fで使われているベースバンドチップは,Venus621LPというもので,1PPS信号の出力を持つLSIです。モジュールのどこかに1PPS信号が出ているに違いないと考えました。そこで背面のシールドケースをあけ,1PPS信号を探したのですが,結論からいうと見つかりませんでした。Venus621はBGAパッケージのLSIですから,端子から直接信号を取り出せません。基板上のどこかに出してくれていることを期待したのですが,スルーホールや抵抗などの部品をすべてあたっても,1PPSの出ている箇所を見つけることができませんでした。衛星をつかまえたことを示すLEDはどうだろう,と考えました。GT-720Fは,衛星をつかまえていない時はLEDが点灯,つかまえると一定間隔で点滅します。このLEDの点滅が1PPSに同期しているなら,1PPS信号として使えるでしょう。いい所に気が付いたと思ったのですが,残念ながら全く同期しておらず,無関係でした。この段階で,GT-720Fから1PPS信号を得る事はあきらめ,外したシールドケースを元に戻しました。ここに至って,1秒近く遅れる,という人間の感覚でもばれてしまうズレを,せめて意識しないで済む程度にする,という消極的な方法しかなくなってしまいました。そのためには,前回も書きましたが,何らかの理由でずれた時刻が送られて来ても,更新周期を早めて表示を頻繁に行うのが有利です。周期が短いほど,ずれた時刻の表示が正しい時刻になるまでの時間が短くなります。そこで,GT-720Fの設定ツールを使って,更新周期を設定可能な最大である1秒間に10回に設定しました。ボーレートを19200ボーに下げました。これは,38400ボーに上げたところで数msしか高速化されませんし,96バイトとバッファサイズを大きくしてまでこのボーレートで受け取るのは無駄で,64バイトのバッファで受信可能な19200ボーが最適という判断です。前回書きましたが,バッファを64バイトにすれば,リングバッファの実現が条件分岐ではなく,ANDによるマスクという処理だけで可能となります。これは処理速度にもコードサイズにも有利です。LCDへのデータ転送タイミングには十分すぎる時間を確保してあったのですが,これを大幅に切り詰めました。LCDへの転送クロック周期はスペックでは500nsから1000ns程度なのに,2msと2000倍も長くとってありました。動作は確実でしょうが,処理時間の大半はLCDへの転送にかかっていたことになります。試したところ,確かに見た目のズレはかなり軽減されています。そのズレ方は一定ではなく,1/10秒くらい遅れているときもあれば,ほとんどずれていない時もあります。この違いはなんだろう・・・はっきりしないと,時計として全く信用できません。この疑問は,GPSモジュールの吐き出すセンテンスを直接PCで見た時に氷解しました。実は,GPGGAにしてもGPRMCにしても,時刻情報として133227.999というデータが,13時32分28秒の段階で送り出されていることがあるようなのです。27.999秒というのは,もうほとんど28秒なのですが,1/10秒以下を無視してしまうと,27秒と表示されてしまいます。1秒間に1度の更新周期なら,次のデータは28.999秒となり,実際の時刻である29秒との表示のズレは,またしても1秒出てきてしまいます。して,GPSモジュールが何かのきっかけでxx.999ではなく,xx.000を出してくれるようになるまで,この1秒の遅れは続きます。133229.500という順番で出てくる事になり,ズレは0.5秒まで軽減されます。いえ,0.5秒のズレはばれてしまいますね。133229.000という形で送られて来るようになると,.xxxを無視して表示すれば,ほとんどずれることなく表示が出来る事になります。調べていくと,.xxxの部分は一定ではなくばらつくこと,バラツキの大きさによって遅れる時間が変わることも分かりました。これが,表示時刻が不規則に遅れる理由でした。PCで.999というデータが出ていることを確認した上で,実機の表示を1/10秒まで表示させてみました。...という具合に変化します。1/10秒にゼロが表示されないことと,1秒の桁は11.9では変わらず12.1で変わるので,実際の時刻よりも1/10秒遅れているのがよくわかります。PCで.000で揃ったデータが出ている状態で同様に確認すると,ほとんど同時に表示も変化するようになります。これではっきりしました。...という変則的な表示となり,見た目が非常に悪くなりました。キャラクタコードに1を加えただけの手抜きはダメで,やっぱり真面目にやるしかありません。そこで,さらに大幅な変更をします。日付はともかくとして,時刻だけはちゃんと処理する事にしましょう。日付は24時間に一度変化しますが,GPSからのデータの取得はは1秒おきですので,1秒だけ32日とか出てしまうことが考えられますが,まあいいでしょう。メモリも足りませんし。このため,これまで直接リングバッファの値を表示用の関数に渡していたものを,一度グローバル変数に取り込んで,文字列-から数値への変換,補正や表示を行う事にしました。あと,潜在的なバグとして日付の処理に問題があり,UTCで9日をJSTに変換するところでくだらないミスをしていたため,10日とならず,0:日と表示されていました。配列の宣言のミスで,暴走一歩手前だったことも白状します。して出来た最終的なソースが,以下です。18:14カテゴリー:できごと長く続いた「鉄道データファイル」がいよいよ最終回を迎えました。