シリアルポートのタイムアウト設定

手順

  1. GetCommTimeout関数でパラメータの取得
  2. COMMTIMEOUTS構造体でパラメータの指定
  3. SetCommTimeouts関数でパラメータの設定

ソースコードの例

HANDLE hdSerial;
COMMTIMEOUTS timeout;

GetCommTimeouts( hdSerial, &timeout );        // タイムアウトパラメータを取得

/* タイムアウトパラメータを指定 */
timeout.ReadIntervalTimeout = 20;
timeout.ReadTotalTimeoutMultiplier = 10;
timeout.ReadTotalTimeoutConstant = 100;
timeout.WriteTotalTimeoutMultiplier = 10;
timeout.WriteTotalTimeoutConstant = 100;

SetCommTimeouts( hdSerial, &timeout );        // タイムアウトパラメータを設定

COMMTIMEOUTS構造体

typedef struct _COMMTIMEOUTS {  
    DWORD ReadIntervalTimeout;
    DWORD ReadTotalTimeoutMultiplier;
    DWORD ReadTotalTimeoutConstant;
    DWORD WriteTotalTimeoutMultiplier;
    DWORD WriteTotalTimeoutConstant;
};
  • 受信はインターバル時間とトータル時間を設定できる
  • 送信はトータル時間のみ
  • 単位はミリ秒

トータル時間は計算して求める。以下参照。

  • 受信インターバル時間
    • ReadIntervalTimeoutに設定する
    • ReadFile関数で1文字だけ受信する際には効果なし
    • ゼロに設置すると、受信インターバル時間は使われない
  • 受信トータル時間
    • ReadTotalTimeoutMultiplier * (受信バイト数) + ReadTotalTimeoutConstant
    • ReadTotalTimeoutMultiplier と ReadTotalTimeoutConstant がゼロのとき、受信トータル時間は使われない
  • 送信トータル時間
    • WriteTotalTimeoutMultiplier * (送信バイト数) + WriteTotalTimeoutConstant
    • WriteTotalTimeoutMultiplier と WriteTotalTimeoutConstant がゼロのとき、送信トータル時間は使われない
  • すべてゼロにするとタイムアウトされない
MAXDWORDを使う
timeout.ReadIntervalTimeout = MAXDWORD;
timeout.ReadTotalTimeoutMultiplier = MAXDWORD;
timeout.ReadTotalTimeoutConstant = /* 0 < MAXDWORD */;

このようにすると、

  • 入力バッファが空であれば、ReadFile関数は待機
  • 入力バッファがあれば(データを受信すれば)、入力バッファをデータバッファに格納
  • ReadTotalTimeoutConstantで指定した時間内に文字が到着しない場合はタイムアウトする
timeout.ReadIntervalTimeout = MAXDWORD;
timeout.ReadTotalTimeoutMultiplier = 0;
timeout.ReadTotalTimeoutConstant = 0;

このようにすると、指定したバイト数のデータを受信し終えていなくもReadFile関数は終了する。