IDEには、いくつかのリンカーファイルを介して利用可能なメモリマップがあります。プログラム内のすべてのアドレスが含まれます。MCUのマニュアルを読んで、目的に有効なメモリがどのアドレスにあるかを確認し、そのメモリの一部を変数用に予約します。特定の開発プラットフォームのドキュメントを読む必要があります。
次に、変数がハードウェアレジスタであるか、フラッシュまたはEEPROMに存在する不揮発性変数でない限り、特定のアドレスに変数をマップすることはあまり意味がないことに注意してください。
そのようなメモリ位置の内容が実行中に変更される場合、それがレジスタであるため、またはプログラムにNVMメモリセルを変更するブートローダー/ NVMプログラミングアルゴリズムが含まれている場合、変数は揮発性として宣言する必要があります。そうしないと、コンパイラは最適化時にコードを完全に破壊します。
特定のコンパイラには、#pragmaや、場合によっては奇妙な非標準の@
演算子など、特定のアドレスに変数を割り当てる非標準の方法がある可能性があります。標準Cの固定位置に変数を割り当てることができる唯一の賢明な方法は、次のとおりです。
#define MY_REGISTER (*(volatile uint8_t*)0x12345678u)
ここで、0x12345678は、その1バイトが配置されているアドレスです。このようなマクロ宣言を作成したら、それを変数であるかのように使用できます。
void func (void)
{
MY_REGISTER = 1; // write
int var = MY_REGISTER; // read
}
ほとんどの場合、これらの種類の変数をグローバル名前空間、つまりマクロに配置する必要があります。ただし、何らかの理由で変数のスコープを縮小したい場合は、マクロをスキップして、コード内のアドレスに手動でアクセスしてください。
void func (void)
{
*(volatile uint8_t*)0x12345678u = 1; // write
int var = *(volatile uint8_t*)0x12345678u; // read
}