DOBON.NET DOBON.NETプログラミング掲示板過去ログ

RS232CのSerialXXX_DataReceivedについて

環境/言語:[Windows 7/Vista MS2010 C# Winアプリ]
分類:[.NET]

お世話になります。

RS232CのSerialXXX_DataReceivedについて教えてください。

try
{
// 受信データを読み込む.
string data = SerialCounter1.serialPort1.ReadExisting();
// 受信したデータをテキストボックスに書き込む.
Invoke(new Delegate_RcvDataToTextBox(Counter1_Text), new Object[] { data });

}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
public void Counter1_Text(string data)
{
// 受信データをテキストボックスの最後に追記する.
if (data != null)
{
       :
}
}
このような形で受信データを処理していますが、上記の処理中に次のデータがやってきた場合、DataReceivedが何度となく呼び出されると思いますが、処理が完全に終わってから次が呼ばれてもいいようにする必要はないのでしょうか?

ググってみてもそこに触れた記述やサンプルは見当たりません。
なければいいのかもしれませんが、なくてもいい仕様になっているのでしょうか?

教えてください。
> このような形で受信データを処理していますが、上記の処理中に次のデータがや
> ってきた場合、DataReceivedが何度となく呼び出されると思いますが、処理が完
> 全に終わってから次が呼ばれてもいいようにする必要はないのでしょうか?

  ええ〜と、オーバーフローエラーしない限り受信バッファに溜まり
  ますが、そういう事態があるならば、そういう事態に対処した構造
  のプログラムにする必要があります。

  また受信バッファとは、正確には2種類あります。
  ハードウェア(RS-232Cのチップ内)の受信バッファと、デバイスド
  ライバー側の受信バッファに別れます。一般的にはハードウェア側
  の受信バッファ数に対して受信割り込みを何時行わせるか設定する
  ことになってます。
  ドライバー内の受信バッファは大抵はどの程度用意されているかを
  含め明記されてませんが、いくばかりかは存在します。
  (ハードウェア側バッファを一括転送できるだけはあるはず)

  その受信バッファがオーバーフローするまでアプリ側の処理が遅く
  重い場合は、受信割り込みルーチンでは、とりあえずアプリ内の、
  独自バッファを作ってそこに読み出すだけ読み出し、別スレッドで
  順次そこから読み出して処理を行う・・・と言うような処理になり
  ます。

  ただ、受信した内容に応答が必要な場合(同期応答)そこで待ち合
  わせる為の時間がどの程度になるかで、外部器機?のタイムアウト
  が発生してしまう可能性もあります。
  しかしながら現在のCPUの処理性能を考えますと、よほど処理性
  能の悪いプログラムを作らないと、そうそうオーバーフローは発生
  しない・・・と思いますが。

※ ハードウェアフロー等のハンドシェーク機能をつかって、受信バッ
  ファがオーバーフローしそうになったら受信を止めるという方法も
  あります。が、外部器機がフロー制御を持っていない場合は、使え
  ません。ご注意ください。

以上。参考まで
オショウ様、お世話になります。

>   ええ〜と、オーバーフローエラーしない限り受信バッファに溜まり
>   ますが、そういう事態があるならば、そういう事態に対処した構造
>   のプログラムにする必要があります。
オーバーフローになるかどうかは、パソコン側の受信バッファーによると思いますが、通常どれだけ割り当てられるものか知りません。パソコン同士つないだ状態では、問題なくうまくいっているので、今回の疑問は、たぶんOKと考えたいと思います。
また、ハードウェア(RS-232Cのチップ内)の受信バッファも添付資料によると96バイトとあります。この量は、ちょっと少ないですが、こんなもんなんでしょう。

> ただ、受信した内容に応答が必要な場合(同期応答)そこで待ち合
> わせる為の時間がどの程度になるかで、外部器機?のタイムアウト
> が発生してしまう可能性もあります。
については、今回は、いわゆる垂れ流しにしてありますので問題なしと判断しております。
> また、ハードウェア(RS-232Cのチップ内)の受信バッファも添付資料によると96バイトとあります。この量は、ちょっと少ないですが、こんなもんなんでしょう。

  昔?は16バイトが一般的でした。
  ひどいものだと、1バイトしか無いPCもありました。

  インターフェース社のボード等では、ボード上に4Kもの受信バッファ
  が搭載されているものもありますので、ハードフロー制御の機能を持っ
  ていない機器で、高速に垂れ流しするデータを取りこぼしなく受信する
  ならば、巨大な受信バッファを持っているボードをお使いになる必要が
  あります。

以上。参考まで
■No31040に返信(オショウさんの記事)
>   昔?は16バイトが一般的でした。
>   ひどいものだと、1バイトしか無いPCもありました。

このスレッドで質問しても良いか迷ったのですが
関連があるため、質問させて頂きます。

System.IO.Ports.SerialPortのReadBufferSizeプロパティが存在することから
.NETライブラリ上?にハードウェアバッファとは別に
受信バッファがあるのではないかと理解していましたが
間違った理解でしょうか?

疑問に思ったので質問させて頂きました。
> System.IO.Ports.SerialPortのReadBufferSizeプロパティが存在することから
> .NETライブラリ上?にハードウェアバッファとは別に
> 受信バッファがあるのではないかと理解していましたが
> 間違った理解でしょうか?

  ちゃんとヘルプに、4096バイトのバッファがあると
  書かれてます。(デフォルト設定で)

  バッファサイズは変更できますが、その必要はない
  と思います。

以上。

>   ちゃんとヘルプに、4096バイトのバッファがあると
>   書かれてます。(デフォルト設定で)
>   バッファサイズは変更できますが、その必要はない
>   と思います。

もちろん通常はこのバッファサイズを変更する必要はありませんが、
フロー制御なしの垂れ流しの場合に、取りこぼしを気にするのであれば、
このバッファサイズを充分な値に変更すれば良いと思いました。
あくまでも理論で、検証したわけではないので間違っていたらすみません。
> もちろん通常はこのバッファサイズを変更する必要はありませんが、
> フロー制御なしの垂れ流しの場合に、取りこぼしを気にするのであれば、
> このバッファサイズを充分な値に変更すれば良いと思いました。
> あくまでも理論で、検証したわけではないので間違っていたらすみません。

  間違ってはいませんが・・・
  確実にハードバッファから.NET側バッファに組みだされて
  いるのかについては、未確認と言うか未検証です。
  検証された方がよいでしょう。

以上。
バッファサイズが、4096バイトが標準で用意されているということは、今回の処理では十分なサイズと思います。

垂れ流しとはいえ、機械の都合上垂れ流し間隔が、1分以上あるようです。
また1回に吐き出されるバイト数も、256バイトかその倍の512バイト程度なので今回は、問題なさそうですね。

ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板