トップ回答者
シリアル通信に関して

質問
-
何時もお世話になっております。
現在、デジタルオシロとシリアル通信を行って波形データを取得しているのですが、
万が一オシロが壊れたとかで、通信不可能になった場合に、関しての質問です。
以下のコードで、問題なく動いているのですが、
bRet = ReadFile(hCom, cRWBuf, sizeof(cRWBuf), &siz, NULL);
の部分で、オシロが不具合を起こした場合に、無限に待ち続けるのが心配で、タイムオーバーや受信イベントなどで、だんまりを未然に防止する方法は、あるのでしょうか?
開発環境は、VC++2005/MFCです。
宜しくお願い致します。
hCom = CreateFile(ComNo, // ファイル名
GENERIC_READ | GENERIC_WRITE, // アクセスモード
0, // 共有モード
NULL, // セキュリティ記述子
OPEN_EXISTING, // 作成方法
FILE_ATTRIBUTE_NORMAL, // ファイル属性
NULL); // テンプレートファイルのハンドル
if(hCom == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);MessageBox((LPCTSTR)lpMsgBuf,"LEGraph",MB_OK + MB_ICONWARNING+MB_TOPMOST);
return;
}memset(cRWBuf,NULL,sizeof(cRWBuf));
sprintf_s(cRWBuf,sizeof(cRWBuf),"*idn?\n");
len = (DWORD)strlen(cRWBuf);
bRet = WriteFile(hCom, cRWBuf, len, &siz, NULL);
if(!bRet)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);MessageBox((LPCTSTR)lpMsgBuf,"LEGraph",MB_OK + MB_ICONWARNING+MB_TOPMOST);
}Sleep( 3 );
memset(cRWBuf,NULL,sizeof(cRWBuf));
bRet = ReadFile(hCom, cRWBuf, sizeof(cRWBuf), &siz, NULL);
if(!bRet)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);MessageBox((LPCTSTR)lpMsgBuf,"LEGraph",MB_OK + MB_ICONWARNING+MB_TOPMOST);
}this->mLblSikibetu.SetWindowText(cRWBuf);
回答
-
# ReadFile って扱いが難しそうなAPIですね。
ReadFile のヘルプを見ると、
> 通信デバイスからデータを読み取っているとき、ReadFile 関数の動作は、現在の通信タイムアウト値の影響を受けます。
> SetCommTimeouts と GetCommTimeouts の各関数は、この通信タイムアウト値の設定と取得を行います。
> タイムアウト値の設定を怠ると、予測できない結果が生じることがあります。
> 通信タイムアウトの詳細については、MSDN ライブラリの「COMMTIMEOUTS」構造体を参照してください。
とあります。
この通信タイムアウトを適切に設定すれば「無限に待ち続ける」という心配がなくなるのではないでしょうか。
また、CreateFile に FILE_FLAG_OVERLAPPED フラグを指定すれば非同期通信が可能となります。
これなら(たぶん今よりももっと難しくなると思いますが)ReadFile で処理が止まることは無くなるはずです。
すべての返信
-
# ReadFile って扱いが難しそうなAPIですね。
ReadFile のヘルプを見ると、
> 通信デバイスからデータを読み取っているとき、ReadFile 関数の動作は、現在の通信タイムアウト値の影響を受けます。
> SetCommTimeouts と GetCommTimeouts の各関数は、この通信タイムアウト値の設定と取得を行います。
> タイムアウト値の設定を怠ると、予測できない結果が生じることがあります。
> 通信タイムアウトの詳細については、MSDN ライブラリの「COMMTIMEOUTS」構造体を参照してください。
とあります。
この通信タイムアウトを適切に設定すれば「無限に待ち続ける」という心配がなくなるのではないでしょうか。
また、CreateFile に FILE_FLAG_OVERLAPPED フラグを指定すれば非同期通信が可能となります。
これなら(たぶん今よりももっと難しくなると思いますが)ReadFile で処理が止まることは無くなるはずです。