2017-11-29 28 views
0

私はUARTインタフェースからデータを読み込むアプリケーションを書いています。データはパケットで送信されます。各パケットには、関連するチャネルがあります。私のアプリケーションは、受信したパケットを仮想チャネル(スレッド)に多重化し、すべてのチャネルが互いに独立して動作できるようにします。私がパケットを受け取ったとき、私はその内容に応じて何かをしなければならず、応答を生成する必要があります。同じUARTインタフェースを使用して応答が返送されます。バイナリデータを静的配列に格納する

送信されるデータは、ほとんどがバイナリです。私がUARTインターフェースから読んでいるとき、私はあらかじめパケットのサイズを知っているので、問題なくメモリをあらかじめ割り当てることができます。

私の問題は、応答を生成することです。私はパケットの最大サイズを知っているので、私は応答を構築するときに静的なバッファを作成することができます。バイナリデータではなくASCII文字で作業する場合は、バッファに格納されているデータの長さを判断するためにNULLターミネータを使用することができます。しかし、私はバイナリデータを扱っているので、NULLバイトを使うことはできません。代わりに、バッファの何バイトがすでに使用されているかを格納する変数を保持する必要があります。私は、バイナリデータを格納するためにカスタムデータ型を使用することを考えていました。

typedef struct { 
    unsigned char buff[2048]; 
    size_t buff_used; 
} binary_data_t; 

これを処理する際のスタンドアロンの方法は何ですか?

+0

そこには「標準」方法ですませんが、珍しいことではありません上で開始したもの。次に、さまざまな種類のデータをバッファに追加する関数のセットを追加します。 –

+0

この種の問題のライブラリはありますか?私は車輪を再発明しているような気がする。 – PoVa

+0

@PoVaもちろん、このサイトではライブラリを推薦するのは話題にはなりません。しかし、ホイールを再発明することは話題になります(モジュロ・ダプス)。 :) – unwind

答えて

1

あなたがパケットを保持するために必要なバイト数を知っているので、ちょうどflexible array memberを使用します。

typedef struct 
{ 
    size_t bytes; 
    unsigned char data[]; 
} binary_data_t; 

(そのidentifiers ending in _t are reserved by POSIXに注意してください、そして、あなたが実際にそれらを使用するべきではありません。)

割り当てと読み取りデータ(ファイルディスクリプタからあなたread()を想定):

binary_data_t *p = malloc(sizeof(*p) + numDataBytes); 
p->bytes = numDataBytes; 
ssize_t bytes_read = read(uartFD, p->data, numDataBytes); 
+0

ありがとう、私は似たようなものを使用して終了しました。 1つの疑問は、フレキシブルアレイメンバーを使用するポイントは何ですか?ポインタを宣言してスペースを確保するのと同じではありませんか? – PoVa

0

あなたの配列のどこに次のバイトを置くべきかへのポインタを格納する方法があります。

typedef struct { 
    unsigned char buff[2048]; 
    char* pData; 
} binary_data_t; 

// at init 
binary_data_t rspMsg; 
rspMsg.pData = rspMsg.buff[0]; 

// at entering data 
*(rspMsg.pData) = data; 
rspMsg.pData++; 

// at sending data you know the length via 
length = rspMsg.pData - &rspMsg.buff[0]; 

これはこれを解決する方法の1つです。 多くの方法で実行できます。

+0

あなたのコードは無効です。構造のフィールドをローカル変数のように扱いますが、これは非常に混乱します。可能であれば、実際のコードを記入してください。 – unwind

+0

いいえ私はそれを変更します – harsmar

関連する問題