• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ClearCommError呼び出し時のCE_OVERRUN対処策)

ClearCommError呼び出し時のCE_OVERRUN対処策

このQ&Aのポイント
  • C++にてシリアル受信プログラムを作成中の方へ、ClearCommError()を呼び出してデータサイズを取得する際に発生するCE_OVERRUNエラーの対処法をご紹介します。
  • CE_OVERRUNエラーの対処策として、ClearCommError()をもう一度呼び出してエラーをクリアし、再度受信処理を行う方法や、一度に受信するデータサイズを小さくする方法がありますが、どちらも効果は得られない場合があります。
  • CE_OVERRUNエラーが発生するのは、シリアル受信しながら別の処理をしている場合に必ず起こるため、CE_OVERRUNエラーの対応や回避策は限られています。詳細な対応策を知りたい場合は、Visual Studio 2005 のC++環境に関する情報を提供しているサイトやフォーラムを参考にすると良いでしょう。

質問者が選んだベストアンサー

  • ベストアンサー
  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.2

書いてある受信部のプログラムをスレッドなどで実行してますか? スレッド化していないのであればオーバラン出る可能性は高いでしょう (特に相手側がデータ垂れ流しにしてる場合) >シリアル通信でのフロー制御を実装したことがないのですが、これは >DCBのfOutxCtsFlowやfOutxDsrFlowをtrueにするだけでよいのでしょうか? RTS/CTS制御の時にはそれでいいはずです >それともハード的に変更しなければならないのでしょうか? 一口にフロー制御といっても手法が2種類あります 1.XON/XOFF データ送受信による制御 2.RTS/CTS 信号ラインによる制御 3.1と2両方使用 使ってる通信のデータ内容によっては1は使えないこともあります (送受信データにXON/XOFFキャラクターが含まれる場合) が既に通信できているならならハード的な変更は不要です 2・3を行う場合配線がちゃんと行われてる必要があります (特に自作で手抜きの折り返しケーブル使っている場合は注意) 相手が何でどのような通信データのやり取りなのかも不明なのですが 本当に垂れ流しデータなのでしょうか? (何らかのコマンドの応答が帰ってきてるだけなら送信側処理を見直すべきです) 後、当たり前ですが相手側がフロー制御対応してる必要があります (自分の方だけがやればいいって話ではありません) 使ってる機器に合わせてください (通信相手側の情報が無いので其処は私には分かりません)

fujtomo
質問者

お礼

>書いてある受信部のプログラムをスレッドなどで実行してますか? >スレッド化していないのであればオーバラン出る可能性は高いでしょう >(特に相手側がデータ垂れ流しにしてる場合) 受信処理は別スレッドで呼び出しております。逆に、別スレッドにしないで呼び出したほうがオーバーランエラーは発生しないようです。 >相手が何でどのような通信データのやり取りなのかも不明なのですが >本当に垂れ流しデータなのでしょうか? >(何らかのコマンドの応答が帰ってきてるだけなら送信側処理を見直 >すべきです) データは、こちら側から相手側へ要求コマンドを送ってから、相手側からデータを受けるといった形です。 >後、当たり前ですが相手側がフロー制御対応してる必要があります >(自分の方だけがやればいいって話ではありません) >使ってる機器に合わせてください >(通信相手側の情報が無いので其処は私には分かりません) やはりそうですよね。相手側の仕様変更変更や、配線の変更等も必要となってくるわけですね。 相手側とその点を確認して、仕様について考えたいと思います。 参考となるご意見大変ありがとうございました。

その他の回答 (1)

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

どのような受信処理を書いているのか分かりませんが 受信データがあるのに受信しないからオーバランが発生するという原理はお分かりでしょうか? (送信側は受信側のことを気にせずデータを送り続けている) 対処するためには2種類の方法しかありません ・フロー制御を行う ・通信速度を下げる どちらかとなります 根本の受信処理のつくりが悪いだけって可能性もあります

fujtomo
質問者

お礼

koi1234様、ご回答ありがとうございます。 受信処理のプログラム記載していなかった為、分かりづらくなってしまい申し訳ございません。 受信処理としては以下のようになっております。 シリアルポートの設定 //シリアルポートの設定 DCB dcb; GetCommState(m_hComm,&dcb); dcb.BaudRate = 38400; dcb.ByteSize = 8; dcb.Parity = false; dcb.StopBits = ONESTOPBIT; dcb.fOutxCtsFlow = false; dcb.fOutxDsrFlow = false; dcb.fDsrSensitivity = false; SetCommState(m_hComm,&dcb); //シリアル受信処理 unsigned char recv[512]; unsigned char recv_data[512]; DWORD dwCount; DWORD dwRead; DWORD dwErrors; CMSTAT ComStat; int count = 0; while(1){ if(要求バイト分受信出来れば) break; ClearCommError(m_hComm,&dwErrors,&ComStat); dwCount = ComStat.cbInQue; if(dwCount == 0){ Sleep(10); continue; } ::ReadFile(m_hComm,recv,dwCount,&dwRead,NULL); if(dwRead == 0){ Sleep(10); continue; } for(int i=0 ; i<dwRead ; i++){ recv_data[count++] = recv[i]; } } のような処理となっております。このなかのClearCommErrorでの dwErrorsにCE_OVERRRUNが発生し、受信エラーとなります。 教えて頂いた対処のほうのなかで、通信速度については決定している ため、フロー制御をしてみようかなと思っております。 シリアル通信でのフロー制御を実装したことがないのですが、これは DCBのfOutxCtsFlowやfOutxDsrFlowをtrueにするだけでよいのでしょうか? それともハード的に変更しなければならないのでしょうか?