(*(Volatile unsigned int *))詳細な説明
Detailed Explanation
32ビットプロセッサを使用して、32ビットメモリアドレスにアクセスするには、次のように定義できます。
#define RAM_ADDR(*(volatile unsigned long *)0x00000000)
次に、C言語を使用してこのメモリアドレスの読み取りと書き込みを行うことができます
読み取り:tmp = RAM_ADDR
書き込み:RAM_ADDR = 0x55
volatileの意味は、この変数が他のプログラムまたはこのプログラムの他のスレッドによって変更される可能性があるため、コンパイラーがそれを最適化できず、読み取られるたびにアドレスから取得されることを意味します。このように宣言されていない場合、コンパイラはそれをレジスタにバッファリングできるため、他のプログラムがそれを変更しますが、レジスタの値は元の値であり、望ましくない結果が得られます。上記の3つのケースはすべて、このプログラムまたはこのスレッドの外部で変更される可能性があるため、追加してください。
いくつかの点に注意してください:
1.(volatile unsigned long *)0x00000000は、それがポインター型であることを示し、アドレスは0x00000000にあります。
2. *の前に、このアドレスを指すコンテンツを示します。
3.全体の外側にブラケットを追加する習慣を身に付けます。
転載住所: http://blog.sina.com.cn/s/blog_6d8f724b0100mq3a.html
最初に例を見てください:
*(volatile unsigned int *)0x500 = 0x10
- 1
①(unsigned int *)0x500:アドレス0x500を強制的にintポインタに変換します
②(unsigned int)0x500 = 0x10:アドレス0x500に0x10を割り当てます
volatileキーワードには、次の用途があります。
同じものが異なるストレージメディアに複数のコピーを持っている可能性があるため、同期に使用されます、場合によっては、これらのコピーの値が異なるため、許可されていないため、単にvolatileを使用して唯一、他にコピーがないため、非同期の問題は発生しません。
たとえば、volatileは、ソースコードをプログラミングするときにこの変数に最適化を使用しないようにコンパイラーに指示することを意味します。 A
次のような一般的なプログラミング:int *a int bb = (*a) * (*a)
この場合、コンパイラーは通常、コードを最適化してメモリーの読み取りおよび書き込み時間を短縮します。int *a int b int c
If put
c = *ab = c * cint *a
Tovolatile int* a
コンパイラーは自動的にコードを最適化しません。 。操作プロセス全体で、変数* aの値が再度読み取られます。この期間中に変数* aの値が変化するために、プログラムの結果が正しくないことを防ぎます。コンパイラの最適化によって特定のステートメントが削除されないようにする
私は腕のレジスターが非常に奇妙であるのを見ました、
割り込みが発生すると、対応する位置は1になり、0をクリアしてもこの人に0を書き込むことはできません。この人に1を書き込むと、割り込みをクリアするために1になります(0をクリア)。
// 0x560012300がレジスタアドレスであると想定します#define INTPAND *(volatile unsigned int *)0x560012300
INTPAND = INTPAND //割り込みをクリア
コンパイラーがINTPAND = INTPANDを認識した場合、この一見役に立たない操作です。揮発性の説明がない場合、コンパイラーはINTPAND = INTPANDの実際に有用なものを削除する可能性がありますが、コンパイラーは役に立たないものと見なされます。最適化失われました。アドレスがioポートの場合、このアドレスの読み取りと書き込みではキャッシュできません。これは、一部の組み込みアドレスに関連しています。キャッシュありこれだけ。
たとえば、このioポートを書き込むときに、そのような揮発性がない場合、コンパイラの最適化により、値が最初にバッファに書き込まれる可能性があります。
データを時間内にioポートに書き込めないように、ioポートに再度書き込みます。揮発性の記述の後、それはキャッシュを通過せず、バッファを書き込みますが、ioポートに直接書き込みます。ioポートの読み取りと書き込みの遅延を回避します。