none
シリアル通信に関して RRS feed

  • 質問

  • 何時もお世話になっております。

     

    現在、デジタルオシロとシリアル通信を行って波形データを取得しているのですが、

    万が一オシロが壊れたとかで、通信不可能になった場合に、関しての質問です。

     

    以下のコードで、問題なく動いているのですが、

        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);

    2008年2月7日 8:03

回答

  •  yo1 さんからの引用

        bRet = ReadFile(hCom, cRWBuf, sizeof(cRWBuf), &siz, NULL);
    の部分で、オシロが不具合を起こした場合に、無限に待ち続けるのが心配で、

    通信中にケーブル引っこ抜いたらどうなるか、自身で確かめてみようという気はないのですか?

    2008年2月7日 8:26
  • 外池と申します。

     

    二つの側面から考えてみてください。

     

    一つは、yo1さんが仰るとおり、何が起こるか、やってみて自分で確かめる。

     

    もう一つ、「無限に待ち続けるのが心配」とのことですが、不具合が発生したとして、実際のところ、測定担当者としてはどんな対処ができれば満足なのでしょうか? ときどき様子を見に来てアプリの様子がダンマリになっているのを見つけて対処できればOKなら、無限に待ち続ける状態に陥っていても問題ないでしょう? それとも、不具合の発生を警告音を出すとか電子メールで発信して知らせるような機能が欲しいのでしょうか?

    2008年2月7日 10:04
  • # ReadFile って扱いが難しそうなAPIですね。

    ReadFile のヘルプを見ると、

    > 通信デバイスからデータを読み取っているとき、ReadFile 関数の動作は、現在の通信タイムアウト値の影響を受けます。
    > SetCommTimeouts と GetCommTimeouts の各関数は、この通信タイムアウト値の設定と取得を行います。
    > タイムアウト値の設定を怠ると、予測できない結果が生じることがあります。
    > 通信タイムアウトの詳細については、MSDN ライブラリの「COMMTIMEOUTS」構造体を参照してください。

    とあります。

    この通信タイムアウトを適切に設定すれば「無限に待ち続ける」という心配がなくなるのではないでしょうか。

    また、CreateFile に FILE_FLAG_OVERLAPPED フラグを指定すれば非同期通信が可能となります。
    これなら(たぶん今よりももっと難しくなると思いますが)ReadFile で処理が止まることは無くなるはずです。

    2008年2月7日 11:34
  • 回答、有難う御座います。

     

    Tom Yama

    既にテスト済みです。質問の背景を伝える為に、この様な文書になってしまいました。

    わかりづらくてすみません。

     

    外池 様

    目的的には、気づいた時点で対処で良いのですが、プログラムを強制終了(タスクマネージャー)するのがスマートで無いと思っています。

     

    zakio 様

    アドバイス有難う御座います。

    SetCommTimeouts 関数で、無事解決出来ました。

    本当に有難う御座います。

     

    2008年2月8日 4:55

すべての返信

  •  yo1 さんからの引用

        bRet = ReadFile(hCom, cRWBuf, sizeof(cRWBuf), &siz, NULL);
    の部分で、オシロが不具合を起こした場合に、無限に待ち続けるのが心配で、

    通信中にケーブル引っこ抜いたらどうなるか、自身で確かめてみようという気はないのですか?

    2008年2月7日 8:26
  • 外池と申します。

     

    二つの側面から考えてみてください。

     

    一つは、yo1さんが仰るとおり、何が起こるか、やってみて自分で確かめる。

     

    もう一つ、「無限に待ち続けるのが心配」とのことですが、不具合が発生したとして、実際のところ、測定担当者としてはどんな対処ができれば満足なのでしょうか? ときどき様子を見に来てアプリの様子がダンマリになっているのを見つけて対処できればOKなら、無限に待ち続ける状態に陥っていても問題ないでしょう? それとも、不具合の発生を警告音を出すとか電子メールで発信して知らせるような機能が欲しいのでしょうか?

    2008年2月7日 10:04
  • # ReadFile って扱いが難しそうなAPIですね。

    ReadFile のヘルプを見ると、

    > 通信デバイスからデータを読み取っているとき、ReadFile 関数の動作は、現在の通信タイムアウト値の影響を受けます。
    > SetCommTimeouts と GetCommTimeouts の各関数は、この通信タイムアウト値の設定と取得を行います。
    > タイムアウト値の設定を怠ると、予測できない結果が生じることがあります。
    > 通信タイムアウトの詳細については、MSDN ライブラリの「COMMTIMEOUTS」構造体を参照してください。

    とあります。

    この通信タイムアウトを適切に設定すれば「無限に待ち続ける」という心配がなくなるのではないでしょうか。

    また、CreateFile に FILE_FLAG_OVERLAPPED フラグを指定すれば非同期通信が可能となります。
    これなら(たぶん今よりももっと難しくなると思いますが)ReadFile で処理が止まることは無くなるはずです。

    2008年2月7日 11:34
  • 回答、有難う御座います。

     

    Tom Yama

    既にテスト済みです。質問の背景を伝える為に、この様な文書になってしまいました。

    わかりづらくてすみません。

     

    外池 様

    目的的には、気づいた時点で対処で良いのですが、プログラムを強制終了(タスクマネージャー)するのがスマートで無いと思っています。

     

    zakio 様

    アドバイス有難う御座います。

    SetCommTimeouts 関数で、無事解決出来ました。

    本当に有難う御座います。

     

    2008年2月8日 4:55