2012-02-17 9 views
1

シリアルポートから100hzでデータを100バイト読み取っています。私のバッファは1024バイトなので、私のバッファは完全には使用されません。しかし時には、私はシリアルポートからしゃっくりを取得し、バッファがいっぱいになる。バッファリング不完全高速読み取り

私のデータは、[ヘッダ]データ[チェックサム]として編成されています。バッファがいっぱいになると、シリアルポートからの2回の読み込みでメッセージ/データが分割されることがあります。

これは簡単な問題です。さまざまなアプローチがあります。私は予定より早く、異なるアプローチを研究したいと思います。 2つの読み込みからまとめなければならないかもしれない高速データのバッファリングをカバーするいくつかのパラダイムを挙げることができますか?この問題では、私が行った他のバッファリング(画像取得、tcp/ip)からの主な違いは、完全なパケット/メッセージが保証されていることです。ここで、「パケット」は複数の読み込み間で分割されてもよく、データの解析を開始するとわかります。

はい、読み取りからバッファリングされたデータは解析する必要があります。そのため、単純にするには、データが解析に達したときに連続している必要があります。その後、以前からバイトを超える左後の読み取りでそれを埋める、私の元のバッファに未使用のバイトを超える

  1. キャリー:私が持っていた

    いくつかのアイデアを(プラス私はパーサの責任だとは思いません)読む。 (たとえば、1024バイトを読み込み、最後に24バイトが残っていますが、それらは部分的なメッセージです。read_buffer_の先頭にmemcpy、先頭に24を渡して1024から24まで読み込みます)

  2. 作成データのブロックを取得する自分のクラス。読み取り/書き込みと大きなメモリ(1024 * 4)の2つのポインタがあります。データを渡すと、クラスは書き込みポインタを正しく更新し、最後に到達するとバッファの先頭にラップします。私はリングバッファのように思う?
  3. おそらくstd::vector<unsigned char>を使用していると考えていました。動的メモリ割り当て。連続していることが保証されています。

おかげさまで、

+0

std :: vector は、非常に簡単で効率的なソリューションを提供します。それぞれの読み込みに新しいchar []を割り当てて、それをベクトルに追加してから、それが解析されたら削除してください。 –

+0

'他のバッファリング(画像取得、tcp/ip)は、完全なパケット/メッセージが保証されていることです.' - あなたはTCP/IPの"完全なパケット/メッセージ "を保証していません。 –

+0

ああ、私はいつもいつも運が良かったと思う。私は、TCP/IPパケットが標準サイズであると思って、スライディングウィンドウのようなパケットとアルゴリズムを使って完全なメッセージを構築しました。 TCP/IPの私の唯一の経験は、大学のプロジェクトだったことを告白します。 – Constantin

答えて

1

'[header] data [checksum]'を表す 'APU'アプリケーションプロトコルユニットクラスを定義します。 charパラメータをとり、 '有効な' boolを返す、いくつかの 'add'関数を与えます。シリアル読み取りスレッドでは、APUを作成し、1024バイトのバッファにデータを読み込みます。バッファ内のデータを反復し、APU add()関数がtrueを返すか反復処理が完了するまでAPU add()にpushします。 add()がtrueを返す場合は、完成したAPUがあります。処理のためにキューを待機させ、別のAPUを作成し、残りのバッファバイトをadd()します。反復処理が完了した場合は、ループバックしてシリアルデータをさらに読み取ります。

add()メソッドはステートマシンなどのメカニズムを使用して着信バイトを構築してチェックし、正当性チェックされたデータのセットが正しいチェックサムである場合にのみ 'true'を返します。検査の一部が失敗した場合、APUは「リセット」され、有効なヘッダーの検出を待機します。

APUは、add()データの入力中、add()が 'true'を返す直前、またはおそらく別の 'parse()'メソッドと呼ばれるデータ自体をパースすることができます。後で、おそらく他のAPU処理スレッドによって。

+0

ああ、ジェームスは正しいですか?TCPはシリアルポートのようなバイトストリーミングサービスです。あなたの画像取得アプリには何らかの注意が必要かもしれません TCPプロトコルにはスライドウインドウがありますが、アプリケーションレベルのメッセージとは関係ありません。 –

+0

素晴らしい、私はこのアプローチも好きです、マーティンありがとう!そして、それらは別々のインスタンス、画像取得アプリケーション、TCP/IPでした。私の要点は、そのような場合、私はいつもメッセージのサイズを知っていて、ただ一つのメッセージを読むだけでした。私はまだ多くのこれらのプロトコル(右の単語?)に非常に新しいです。 – Constantin

+0

@コンスタンチン - はい、正しい言葉:私は、完全性のために、新しいAPUインスタンスを継続的に作成することは、「使用済み」インスタンスが「使い果たされた」後に処分されるべきであることを意味する彼らのプール、それはより複雑です)。 –

0

高速でシリアルポートから読み取るときは、通常、データの流れを制御するために何らかの種類のハンドシェイク機構が必要です。これは、ハードウェア(例えば、RTS/CTS)、ソフトウェア(Xon/Xoff)、またはより高いレベルのプロトコルによって制御され得る。ハンドシェークせずに大量のデータを高速で読み取る場合、UARTまたはシリアルコントローラは、データを失わないように、その速度ですべての利用可能なデータを読み取り、バッファできる必要があります。 Windows PC上で見られる16550互換UARTでは、このバッファはわずか14バイトなので、ハンドシェイクやリアルタイムOSが必要です。

関連する問題