WindowsXP時代のパラレルポート制御
パラレルポートのアクセス権を理解するため、parport.sysの使い方を習得しました。
parport.sysにアクセスすると、パラレルポートのアドレス等の情報や、排他的アクセス権を取得することができます。
このデバイスドライバを理解するのに、いちばん参考になったのは、翔泳社の「WDMデバイスドライバ 」という本でした。
この本によれば、
1.「\Device\ParallelPort0」という名前のドライバがある。
2.IoGetDeviceObjectPointerでデバイスオブジェクトのポインタを得る。
3.Internal IOCTLを発行する。
4.TryAllocatePort関数を呼び出す。
5.FreePort関数を呼び出す。
という手順が書かれています。1ページに満たない短い解説なのですが、意味を理解するのに数日かかりました。
何が大変だったかというと、Internal IOCTLを発行するにはIoBuildDeviceIoControlRequest関数でIRPを作って、IoCallDriverを呼び出す、という手順を理解するので一苦労。
IoCallDriverでIOCTL_INTERNAL_GET_PARALLEL_PORT_INFOを発行する方法がわかれば、PARALLEL_PORT_INFORMATION構造体を得ることができます。
そして、PARALLEL_PORT_INFORMATION構造体の中にTryAllocatePort関数のポインタが格納されています。
このTryAllocatePort関数を呼べばよいのですが、引数をどうすればよいのか、かなり悩みましたが、PARALLEL_PORT_INFORMATION構造体の中にあるContextという値を引数にして、
portinfo.TryAllocatePort(portinfo.Context);
とするのが正解のようです。
ただし、同一のプログラムでTryAllocatePortを2回呼び出してしまうと、なんかロックがかかってしまうようで、パソコンを再起動しないとアクセス権が得られなくなってしまうようです。
さて、苦労の末、ようやくInternal IOCTLの使い方をマスターできたのですが、これを使うと、パラレルポートのアドレスや、ポートがECPやEPPに対応しているか、などの情報を得ることができます。
おそらく、ポートのアドレスを調べる最も正当な方法でしょう。
私のPCでは、こんな情報が得られました。
OriginalController=0x378
Controller=0x378
SpanOfController=0x8
OriginalEcpController=0x778
EcpController=0x778
SpanOfEcpController=8
HardwareCapabilities=0x9 (ECP mode,BYTE mode, )
FifoDepth=16
FifoWidth=1
EppControllerPhysicalAddress=0
SpanOfEppController=0
Ieee1284_3DeviceCount=0
CurrentMode=0x0
いろいろやった末、ようやくTryAllocateで排他的制御権を獲得することができるようになりました。
WindowsXPのWarmPollを停止させることができ、当初の問題は解決できました。
しかし、排他的アクセス権を得ると、もっと重大な問題が出たのです。
そのことを書く前に、そもそも、なんでこんなことをやっているかを説明しましょう。
ことの発端は、MITOUJTAGからALTERAのByteBlasterを使おうとしたとき、WindowsXPで動作がおかしいことに気が付いたことでした。
WindowsXPでWarmPollが動きだすと、ByteBlasterの中の重要な制御信号がWarmPollに勝手にいじられてしまい、ByteBlasterが正常に動作できません。そこで、WarmPollの回避方法として排他的アクセス権を獲得しようと考えたのです。
確かに、パラレルポートへの排他的アクセス権は獲得できました。WarmPollも回避できました。
ところで、ALTERAのQualtusIIは、内蔵のJTAGプログラマを使用しなくても、なぜかコンパイル中にパラレルポートへ頻繁にアクセスします。困ったことに、QualtusIIも排他的アクセス権を獲得しようとするらしいのです。しかも、獲得できない場合には、諦めるのではなく、長時間のWAITを行ってしまいます。
つまり、QualtusIIは、パラレルポートの排他的アクセス権が得られないと、コンパイルがとても遅くなるらしいのです。
この現象は、QualtusIIに内蔵されたJTAGプログラマを使わない場合でも発生します。
例えば、スカスカのVHDLファイルをコンパイルすると、普通なら10秒くらいで完了します。しかし、QualtusIIがパラレルポートの排他的アクセス権を得られないと4~5分かかってしまうようです。
これではちょっと困ります。QualtusIIを使う場合にはMITOUJTAGが排他的アクセス権を持ったままにはできないのです。
結局、WarmPollを回避するには、レジストリに値を設定するのがベストということなのでしょう。
Windows2000やXPで、パラレルポートのアドレスを正当に取得する方法がわかっただけでも、この数日間の作業の成果があったと思うことにしましょう。
いずれ時間ができたら「WindowsXP時代のパラレルポート制御」ということで、まとめようと思います。
| 固定リンク
コメント
センチネルのプロテクトの為のドライバが、ドングルを見に行っているのでしょうか?
http://www.hdl.co.jp/SPP-100/index.html
投稿: shirou | 2006.02.07 09:59