| いまさら利用価値のほとんど無い情報かと思いますが...
Navin'You(PCQ-NYH5とPCQ-NY55DUG)には「GPS/ルートガイド機能設定においてSONY Corp.IPS-5000 SERIESを指定してシリアル通信ポート(IPS-5100G等)にアクセスするとCPU 使用率が 100 % になる」現象が見られます。
この現象はSonyIPS.dllの欠陥(必要なコードの欠落)により発生していると思われます。
Serial device monitorを使用して、Navin'You(SonyIPS.dll)がアクセスしているシリアル通信ポートをモニターするとすぐに分かるのですが、IOCTL_SERIAL_GET_COMMSTATUSが異常に短い周期で呼び出されています。(CPU使用率100%の原因) IOCTL_SERIAL_GET_COMMSTATUSは、ClearCommError APIの呼び出しにより発生しますので、「受信データの有無をポーリングしているプログラムループ内にSleep APIの呼び出しが欠落している」ことが容易に想像できます。典型的で稚拙なバグだと思われます(^^;
そこでSonyIPS.dllがClearCommError API呼び出す時に欠陥部分を補完するコードを挿入します。 補完するコードの挿入方法は一般にAPIフックと呼ばれる手法を使うのが局所的で簡単です。
1)kernel32.dllをラップするdllを作成してClearCommError = dummy_ClearCommErrorの呼び出し時に以下のコードで補完する。
BOOL WINAPI dummy_ClearCommError( HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat ) { BOOL retv = ::ClearCommError( hFile, lpErrors, lpStat ); if( retv ) { if( lpStat->cbInQue == 0 ) Sleep( 50 ); } return retv; }
2)SonyIPS.dllのImport Name Tableの名前(kernal32.dll)を1)のファイル名に変更する。 3)SonyIPS.dllと同じディレクトリに1)のdllを配置する。 以上
※No16,22で示した補完方法はKernel modeで動作するDriver内で補完するコードを実行すると言う方法なのですが、この方法だと欠陥等無いまともなプログラムでも補完するコードが実行されてしまうため、没としました。
|