3

私のISRには、USARTから詰め込まれるバッファがあるので、バッファを揮発性として宣言しました。

volatile uint8_t RxBuffer1[BUFFER_LENGTH];

はい、問題ありません。それが標準的な習慣だと思います。

main()のどこかで、その配列の一部をコピーする必要があります。これは、配列が循環バッファーであり、将来的には消去されるためです。

strncpy(Data, RxBuffer1, len);

ああ、でもこれはノーノーです!私のコンパイラは忠実に私に言います:

'strncpy'の引数2を渡すと、ポインタターゲットタイプから'volatile'修飾子が破棄されます

strncpyは「s2」をconstcharにするため*

私は、標準的な慣行として行われていないことをしているとは思いません。これを正しく行うにはどうすればよいですか?

4

3 に答える 3

2

この場合、memcpyを使用する方が良いと思います。Strcpyとstrncpyは、文字列(char配列)用に最適化されています。

構文はstrncpyに似ています。

void* memcpy (void* dest, void* src, size_t bytes);

あなたの場合:

memcpy (Data, RxBuffer1, sizeof(uint8_t) * len);

(sizeof(uint8_t)は1なので省略できます)。

于 2012-01-20T15:24:59.537 に答える
2

渡された引数をキャストしますconst char *

于 2012-01-20T17:06:13.553 に答える
-1

揮発性物質を捨てることはほぼ確実に安全ですが、技術的にはコンパイラ固有です。

Volatileは、一部のメモリのコピーをレジスタに配置する最適化を適用しないようにコンパイラに指示し、毎回戻ってメモリを読み取るのではなく、それを使用します。

あなたが話しているアプリケーションでは、memcpyはバッファを再読み取りしていないため、前回呼び出したときと同じデータを返さないようにする必要があります。ただし、実際には、そのように実装される可能性は非常に低くなります。これは、コンパイラが関数呼び出し全体でレジスタにデータを格納することを意味するためです。理論的には可能ですが、あまり意味がありません。

そして、memcpyへの1回の呼び出しで、memcpyが同じメモリの後続のコピーを最適化することをほぼ確実に気にしません。

于 2013-10-04T10:44:11.587 に答える