0

UART バッファからデータを読み取る方法についてのアイデアを受け取りたいです。より正確に言うと、バッファ内で何らかの文字列パターンを見つける方法が必要です。問題は、この文字列を検索するのを待つと、バッファが再度書き込まれ、カウンターが変更され、データにパターンがあるかどうかに関係なく発生することです。うーん、この説明はちょっとわかりにくいと思うので、他にもお気軽に聞いてください。

void f(char * buffer) {

char * p;
p = strstr(buffer, "abc");

printf(p);
}

私の場合、UARTは文字単位ではなくブロック単位で書き込まれていると思います。連続ストリームであるため、データが終了したとは言えません。わかりやすく説明すると、これは NMEA プロトコルで GPS データを読み取り、これらのデータから情報を取得しようとするコードです。

よろしくお願いします

4

3 に答える 3

0

あなたの質問は明確ではありませんが、多くの人がバッファの仕組みを誤解しているのを見てきましたので、私がお手伝いできると思います.

あなたが言っていることにより、データをバッファに読み込むことを期待しており、検索文字列と部分的に一致するのではないかと心配しています。その後、残りを読み取るときに、最初のデータ ロットを上書きします。

したがって、これはデータをどのように処理するかにかかっています。毎回メモリの同じ部分を読み込む必要はありません。バッファの要点は、必要に応じていっぱいにし、シャッフルしてから破棄できるスペースを提供することです。

バッファを効果的に使用する方法はたくさんあります。最も効率的ではないかもしれませんが、最も簡単に理解できるものを紹介します。

tailバッファに読み込むとき、最後のバイトがどこにあるかがわかるように、インデックスを維持します (これを と呼びましょう)。バッファのサイズであるNバイトまで読み取ることができます。Nデータの処理に関しては、バイトまでチェックできますtail

すでに処理したものを追跡するには、headインデックスを維持します。さらにデータを読み取る必要があると判断したら、 と の間のすべてを取得してheadtailバッファーの先頭に移動します ( memmoveNOT memcpyを使用します)。head = 0、および を設定しtail = tail-headます。N - tailこれで、より多くのバイトを読み取ることができます。当然、tailインデックスの後から始まるバッファ内の位置に読み込みます。

一致文字列全体を連続したバイトとしてテストできるようにする場合は、これが最も簡単なバッファリング アプローチです。

さらに一歩進んだ場合、データをまったく移動する必要がないことを理解するのに多くの想像力は必要ありません。あちこちhead追いかけるだけです。tailこれは、リング(または循環) バッファーと呼ばれます。これの難しさは、通常の文字列マッチングを使用できないことですが、独自の文字列を作成するのにそれほど時間はかかりません。

これが役に立てば幸いです。

于 2013-04-02T02:03:52.417 に答える
0

すべてのデータを受け取ってから文字列を処理できますか? コードは次のようになっていると思います。

char *p_uart = read_from_uart();

void search_string(char *p_uart)
{
    static char last_remain_char[20];
    char new_data[1000] = {0};
    char *p = NULL;
    int n = 0;

    n = snprintf(new_data, sizeof(new_data), "%s%s", last_remain_char, p_uart);
    p = strstr(new_data, "abc");

    strcpy(last_remain_char, new_data + (n - (strlen("abc") - 1)));
}
于 2013-04-02T01:44:01.813 に答える
0

各文字を受け取り、後で比較するために通常のバッファに蓄積 (コピー) できます。または、より良い方法は、各キャラクターを受け取り、状態変数を保持して、マッチのどこまで進んでいるかを示すことです。

size_t state = 0;
while( c=get_char_uart() ) {
    if (str_to_match[state] == c)  {
        state++;
        if (state == strlen(str_to_match)) {
            /* success */
        }
    }
    else 
        state = 0;
}

文字の繰り返しシーケンス (「abcabd」) を期待している場合は、さらに複雑になります。この場合、 で失敗したd場合は、 を探す必要があるかもしれませんc。注意してください。

于 2013-04-02T01:46:52.933 に答える