7

C および C++ コード、特に組み込みシステムのコードでは、次のような形をとる代入によく出くわします。

A |= B;
A &= B;

関連するかどうかはわかりませんが、A と B はここに登録されています。ここで例を参照してください: http://processors.wiki.ti.com/index.php/Interrupt_Nesting_on_C28x#Example_Code 次の行が表示されます。

IER |= 0x002;
IER &= 0x002;

ただし、これらの後続の割り当ては、単一の割り当てと同じように見えます

A = B;

理論的には、前者は場合によっては両方の行の間で中断される可能性があるという事実を除いて、これはほとんどのコードで重要な役割を果たしているようには見えません。

後者よりも前者を使用する利点はありますか、それとも私が見落としている別の違いはありますか?

4

4 に答える 4

6

もちろん、次の 2 つのコマンドのシーケンス:

A |= 0x02;
A &= 0x02;

以下と同一です:

A = 0x02;

Aが変数ではなく、ハードウェア レジスタでない限り。この場合、MCU/CPU (またはマッピングされたペリフェラル) のマニュアルを参照して、このシーケンスが正確に必要な理由を確認する必要があります。


アップデート

変数 vs ハードウェア レジスタ

上記のコメントで、OP は変数とレジスタを区別する方法を尋ねました。

これは非常に簡単です。あなたがする必要があるのは、定義を見ることだけです。典型的な変数は次のように定義されますが:

unsigned char A;

ハードウェア レジスタの定義は次のようになります。

#define A (*(volatile uint16_t *)(0x1234))

ここで、Aはハードウェア レジスタの値として定義され、 のアドレスにマップされます0x1234。すべてのマイクロコントローラーまたは CPU には独自のハードウェア レジスタ セットがあり、アーキテクチャやモデルの種類異なるだけでなく、製造元によっても異なります。ソース コードが十分に文書化されていない場合、特定のハードウェア レジスタが何であるかを知る唯一の方法は、ハードウェア データシートを調べることです。また、一部の高度なアーキテクチャでは、一部のペリフェラルのハードウェア レジスタを CPU アドレス空間にマップできるため、外部コンポーネントのハードウェア レジスタに同じ方法でアクセスできます。

volatileキーワードに注意してください。ウィキから:

このキーワードは、最適化コンパイラが後続の読み取りまたは書き込みを最適化して、古い値を誤って再利用したり、書き込みを省略したりするのを防ぎます。揮発性の値は、主にハードウェア アクセス (メモリ マップド I/O) で発生します。この場合、メモリからの読み取りまたはメモリへの書き込みが周辺デバイスとの通信に使用されます。スレッド化では、別のスレッドが値を変更した可能性があります。

于 2016-11-16T10:56:27.607 に答える
1

ハードウェア レジスタには、特定のビット シーケンスが「特別な」動作をする必要がある場合がありますが、この特定のインスタンスでそれが何であるかを確認するのは困難です。

たとえそれがチップ ベンダーのサイトからのものであっても、インターネット上で見つけたコードがナンセンスである可能性を過小評価しないでください。ドキュメントを見ると、著者がこれを読んだ可能性が高いようです。

ここに画像の説明を入力

また、OR IER/AND IER への参照によって混乱しています。これらは割り込みを有効および無効にしますが、MOV IER 命令もアトミックに行います。これは、直接割り当てが行うことです。

同じページに後の例があります。

IER |= M_INT2;
IER &= MINT2;                         // Set "global" priority

オペランドが異なる場合。したがって、おそらく著者は単純に一般化されたパターンを持っており、それに固執しています。

于 2016-11-17T16:51:48.470 に答える