none
WDMプログラムでの時間計測の仕方 RRS feed

  • 質問

  • お世話になります。時間の計測の仕方を教えて下さい。
    2台のPCをパラレルポートで接続して、
    送信側のPCのパラレルポートのDataBit1を5msec ONする(パルス出力)
    受信側のPCではそのパルスのON時間を計測する実験をしました。

    送信側の出力をオシロスコープで確認すると5msecの出力を確認しました。
    しかし受信側のプログラムでの時間の取得の仕方がわかりません。
    以下のソースのgetcout関数の中で、どの様な命令を使用すればよいのでしょうか。
    アプリケーションプログラムであれば,queryperformancecounterなどでクロックを取得すれば
    よいと思うのですが、カーネルプログラムではどの様にすればよいのでしょうか。
    教えて下さい。
    また以下のようにDo while文で制御を返さない処理は問題でしょうか?
    割り込みなどを使用するのが良いのでしょうか?

    宜しくお願いします。



    //-----------------------------------------------
    // 送信側PCより指定時間パルス出力
    //-----------------------------------------------
    void PulseOut(int data)
    {
     unsigned short PrintDataAd=0x0378;
     unsigned short PrintStartAd=0x0379;
     unsigned short PrintCommandAd=0x037a;
     unsigned char outdata;

     //出力モード
     outdata=0xcc; 
     WRITE_PORT_UCHAR((unsigned char *)PrintCommandAd,outdata);
     
     outdata=0x01; //DataBit1 ON
     WRITE_PORT_UCHAR((unsigned char *)PrintDataAd,outdata);
     KeStallExecutionProcessor(5000);
     outdata=0x00;   //DataBit1 OFF
     WRITE_PORT_UCHAR((unsigned char *)PrintDataAd,outdata);
    }


    //-----------------------------------------------
    // 受信側PC パルス受信
    //-----------------------------------------------
    void PulseRecv(void)
    {
     unsigned short PrintDataAd=0x0378;
     unsigned short PrintStartAd=0x0379;
     unsigned short PrintCommandAd=0x037a;
     unsigned char outdata;
     unsigned char inpdata;

     LARGE_INTEGER start1;
     LARGE_INTEGER end1;
     LARGE_INTEGER delay1;

     //入力モード
     outdata=0xec; 
     WRITE_PORT_UCHAR((unsigned char *)PrintCommandAd,outdata);
      
     do
     {
      inpdata = READ_PORT_UCHAR((unsigned char *)PrintDataAd);
      if((inpdata & 1)==1) //立ち上がりの確認
      {
       start1=getcunt();
       kPrint("bit1 ON \n");
       break;
      }

     }while(-1);
     do
     {
      inpdata = READ_PORT_UCHAR((unsigned char *)PrintDataAd);
      if((inpdata & 1)==0) //立下りの確認
      {
       end1=getcunt();
       delay1.QuadPart=end1.QuadPart-start1.QuadPart;
       kPrint("bit1 OFF %d\n",delay1.QuadPart);
       break;
      }

     }while(-1);
     DbgBreakPoint();
    }

    LARGE_INTEGER  getcunt(void)
    {
        ?
    }

    • 移動 Mike Wang (MSCS) 2012年10月2日 12:32 (移動元:Windows デバイスドライバー開発)
    2010年3月5日 8:42

回答

  • カーネル モード ドライバでの時間計測に関しては、以下のカーネル関数か
    ReadTimeStampCounter などのマクロを使えば取得出来るのでは...と思います。

    ----------------------------------------------------
    KeQueryPerformanceCounter()
    http://msdn.microsoft.com/en-us/library/ms801657.aspx

    KeQuerySystemTime()
    http://msdn.microsoft.com/en-us/library/ms801642.aspx

    KeQueryTimeIncrement()
    http://msdn.microsoft.com/en-us/library/ms801957.aspx

    ReadTimeStampCounter()
    x86 環境では、RDTSC 命令と同義のはずです。
    このマクロを使えば、CPU 依存を排除することが可能なはずです。
    ----------------------------------------------------

    ただ、これらの関数も結局はシステム クロックをベースとしているので、
    システム クロック以上の分解能での時間計測は無理なのでは...と思います。
    (以下の KB にも、それらしいことが書いてあります。)

    ----------------------------------------------------
    DOC: Obtaining System Time Using KeQuerySystemTime
    http://support.microsoft.com/kb/239818/en-us
    ----------------------------------------------------

    あと、
    「Do while文で制御を返さない処理は問題でしょうか?」
    に関しては、「絶対にやらないほうがいい」処理だと思います。
    koridorasu さんも認識されているように、割り込みを使用して、
    ISR や DPC などのルーチンで適切に処理すべきだと思います。

    • 回答としてマーク koridorasu 2010年3月8日 6:11
    2010年3月5日 10:30

すべての返信

  • カーネル モード ドライバでの時間計測に関しては、以下のカーネル関数か
    ReadTimeStampCounter などのマクロを使えば取得出来るのでは...と思います。

    ----------------------------------------------------
    KeQueryPerformanceCounter()
    http://msdn.microsoft.com/en-us/library/ms801657.aspx

    KeQuerySystemTime()
    http://msdn.microsoft.com/en-us/library/ms801642.aspx

    KeQueryTimeIncrement()
    http://msdn.microsoft.com/en-us/library/ms801957.aspx

    ReadTimeStampCounter()
    x86 環境では、RDTSC 命令と同義のはずです。
    このマクロを使えば、CPU 依存を排除することが可能なはずです。
    ----------------------------------------------------

    ただ、これらの関数も結局はシステム クロックをベースとしているので、
    システム クロック以上の分解能での時間計測は無理なのでは...と思います。
    (以下の KB にも、それらしいことが書いてあります。)

    ----------------------------------------------------
    DOC: Obtaining System Time Using KeQuerySystemTime
    http://support.microsoft.com/kb/239818/en-us
    ----------------------------------------------------

    あと、
    「Do while文で制御を返さない処理は問題でしょうか?」
    に関しては、「絶対にやらないほうがいい」処理だと思います。
    koridorasu さんも認識されているように、割り込みを使用して、
    ISR や DPC などのルーチンで適切に処理すべきだと思います。

    • 回答としてマーク koridorasu 2010年3月8日 6:11
    2010年3月5日 10:30
  • CPU依存命令になりますが、
    RDTSC(Read Time Stamp Counter)のアセンブラ命令を使って読み出すことで、
    CPUクロックと同じ分解能を持つ精度のタイマが実現できます。興味があれば検索して調べてみて下さい。
    2010年3月5日 11:09
    モデレータ
  • ニコチャン大王様
    ありがとうございます。
    大変参考になりますた。
    ISRとDPCについて勉強したいと思います。
    2010年3月8日 6:14