_RsDebug_

  【ソフトの内容】

このソフトは、API関数単位でデバックするソフトです。
「シリアルはWinで行こう」のソフトをベースに作りました。
操作性は「シリアルはWinで行こう」と同じです。


【API関数のシリアル通信の基礎】

簡単に説明するとファイルをアクセスするAPI関数を使って制御します。
CreateFileでOPENして、ReadFileで読込、WriteFileで書込、CloseHandleでcloseします。
まるで、ファイルをアクセスしているのと同じだ。
   コメント「DOSのファックションコールは貧弱で使えなかったが、API関数は、
        しっかり作られているようだ」

<OPENの仕方>
handle = CreateFile(lpszCommName // ポートの名前
             ,GENERIC_READ | GENERIC_WRITE // Read/Write
             , 0 // 共有しない
             , NULL // セキュリティ属性デフォルト
             , OPEN_EXISTING // 既存ファイル
             , FILE_FLAG_OVERLAPPED // 非同期 I/O を許す
             , NULL);
ポートの名前に"COM1〜255"とする。
FILE_FLAG_OVERLAPPEDは、非同期であることを意味する。
非同期とは、この関数を実行するとすぐに制御が戻ってくるが、実際には処理されてない。
この関数を実行した時点で、処理はOSに渡される。(スレッドで別タスクが実行される)
OSがWindows9×系の場合は同期及び非同期両方設定できるがWindowsNT系は、
非同期しか設定できない。(ファイルの場合はWindows9×系は同期のみです)
同期とは、この関数を実行すると処理が完了するまで待たされる。処理完了で制御が
戻ってくる。この場合処理している間は他の処理が出来ないことになる。
このCreateFile関数が正常に実行すると、戻り値にハンドル番号が戻ってくる
このハンドル番号は、後の処理で必要な番号なのです。
失敗するとINVALID_HANDLE_VALUEが戻ってくる

<受信方法>
一般的に受信する場合スレッドを作ってその中でぐるぐる回しますが、ポーリングになって
しまうと、CPUに負担がかかるので、I/Oイベント駆動を使って受信するほうが、
ベストです。
手順として
  1・SetCommMaskでイベントをマスクする
  2・WaitCommEventでマスクしたイベントが発生するかで待機する
  3・ReadFileで受信処理を開始させる
  4・GetLastErrorでERROR_IO_PENDINGならば正常、そうでないときは、失敗
  5・GetOverlappedResultで受信処理が完了したか常時監視する
  6・GetOverlappedResultも戻り値が0以外で受信完了です。
  7・GetOverlappedResultで処理された文字数が受信文字となる。

SetCommMask (handle,EV_RXCHAR);
     handle=CreateFileのハンドル番号
     EV_RXCHAR=受信バッファに文字が入ったというフラグ
WaitCommEvent (handle, &dwEvent, NULL);
    handle=CreateFileのハンドル番号
    &dwEvent=DWORDのアドレス値でどのイベントが発生したフラグが入る
ReadFile(handle,inbuff,550,&rs_read,&ovlpd)
    handle=CreateFileのハンドル番号
    inbuff=受信した文字列が入るアドレス値
    550=inbuffのサイズ
    &rs_read=受信した文字数のDWORDのアドレス値(この時の文字数は使わない)
    &ovlpd=同期式はNULLを指定、非同期はオーバーラップ構造体のアドレス値
    戻り値が0なら正常、0以外で失敗
OVERLAPPED ovlpd;
    オーバーラップ構造体
GetOverlappedResult(handle,&ovlpd,&rs_read,FALSE);
    handle=CreateFileのハンドル番号
    &ovlpd=オーバーラップ構造体のアドレス値
    &rs_read=受信した文字数のDWORDのアドレス値(この値を使う)

<送信方法>
受信の場合はいつ受信するかわからないのでスレッド処理しましたが、
送信の場合に任意で送るでスレッド処理しなくてもいいかなと思っています。
大量な文字を送ったり、待ち時間を有効に使うのならスレッド処理してもいいですね。
手順として
  1・WriteFileで送信開始させる
  2・GetLastErrorでERROR_IO_PENDINGならば正常、そうでないときは、失敗
  3・GetOverlappedResultで送信処理が完了したか常時監視する
  4・GetOverlappedResultも戻り値が0以外で送信完了です。

WriteFile(handle,moji,moji_suu,&rs_err,&ovlpd);
    handle=CreateFileのハンドル番号
    moji=送信する文字列のアドレス値
    moji_suu=送信する文字数のDWORDのアドレス値
    &rs_err=エラーのDWORDのアドレス値
    &ovlpd=同期式はNULLを指定、非同期はオーバーラップ構造体のアドレス値
    戻り値が0なら正常、0以外で失敗
OVERLAPPED ovlpd;
    オーバーラップ構造体で受信とは別の構造体を作る
GetOverlappedResult(handle,&ovlpd,&writefile_suu,FALSE);
    handle=CreateFileのハンドル番号
    &ovlpd=オーバーラップ構造体のアドレス値
    &writefile_suu=実際に送信した文字数のDWORDのアドレス値)

<CLOSEの仕方>
CloseHandleでCLOSEさせるが、I/Oイベント駆動で作っている場合、受信がない限り
スレッドを終了させることが出来ない。
よってSetCommMaskよって強制的にWaitCommEventを終了させてスレッドを終了させる
手順として
  1・SetCommMask (handle,EV_RXCHAR);でWaitCommEventからの待機を退避
    させる。
  2・PurgeComm(handle,PURGE_RXCLEAR);バッファをクリアさせる
  3・CloseHandle(handle);でハンドルを閉じる。スレッドのハンドル終了させる

【デバックの方法】



上図のように、受信した内容と送信した内容が表示します。
送信も出来ます。
操作方法は「シリアルはWinで行こう」と同じです。


<受信時>
受信すると以下のように表示します。
1・イベントの発生(WaitCommEvent)で「EV=1,」と表示します。
  1=受信文字がバッファに入った時
2・受信バッファに入った文字数で「InQue=8,」と表示します。
3・API関数ReadFileの戻り値で「ReadFile=0,」と表示します。
4・API関数ReadFileで読んだ文字数で「bytes=8,」と表示します。
5・API関数ReadFileを実行時のGetLastError値で「GetErr =997,」と表示します。
6・API関数GetOverlappedResultを実行時の処理で「IN_OK,」と表示すれば、正常終了です。
  「TimUP,」と表示すれば、正常になるまで待ち続けたがタイムUPで抜けた状態です。
7・API関数GetOverlappedResultの戻り値で「GetOlR=0,」と表示します。
8・API関数GetOverlappedResultを実行時のGetLastError値で「GetErr =996,」と表示。
9・API関数GetOverlappedResultで読んだ文字数で「bytes=8,」と表示します。
10・受信した文字を「”1234567”,」と表示します。

<送信時>
送信すると以下のように表示します。
1・送信文字数で「bytes=8,」と表示します。
2・API関数WriteFileの戻り値で「WriteFile=0,」と表示します。
3・API関数WriteFileで戻り値が0の場合のGetLastError値で「GetErr =997,」と表示。
  997= ERROR_IO_PENDINGです。
4・API関数GetOverlappedResultで送信した文字数で「bytes=8,」と表示します。
5・API関数WriteFileの戻り値が0で、かつ、GetLastError値がERROR_IO_PENDINGで無い時、
「Error,」と表示します。



 ダウンロードページへ 

 

**戻る**