Data placement at an absolute location
The @ operator, alternatively the #pragma location directive, can be used for placing global and static variables at absolute addresses.
To place a variable at an absolute address, the argument to the @ operator and the #pragma location directive should be a literal number, representing the actual address. The absolute location must fulfill the alignment requirement for the variable that should be located.
Note
All declarations of __no_init variables placed at an absolute address are tentative definitions. Tentatively defined variables are only kept in the output from the compiler if they are needed in the module being compiled. Such variables will be defined in all modules in which they are used, which will work as long as they are defined in the same way. The recommendation is to place all such declarations in header files that are included in all modules that use the variables.
Other variables placed at an absolute address use the normal distinction between declaration and definition. For these variables, you must provide the definition in only one module, normally with an initializer. Other modules can refer to the variable by using an extern declaration, with or without an explicit address.
Examples
In this example, a __no_init declared variable is placed at an absolute address. This is useful for interfacing between multiple processes, applications, etc:
__no_init volatile char alpha @ 0x2000; /* OK */ The next example contains a const declared object which is not initialized. The object is placed in ROM. This is useful for configuration parameters, which are accessible from an external interface.
#pragma location=0x2004
__no_init const int beta; /* OK */
The actual value must be set by other means. The typical use is for configurations where the values are loaded to ROM separately, or for special function registers that are read-only.
This shows incorrect usage:
__no_init int epsilon @ 0x2007; /* Error, misaligned. */C++ considerations
In C++, module scoped const variables are static (module local), whereas in C they are global. This means that each module that declares a certain const variable will contain a separate variable with this name. If you link an application with several such modules that all contain (via a header file), for instance, the declaration:
const __no_init int x @ 0x100; /* Bad in C++ */
the linker will report that more than one variable is located at address 0x100.
To avoid this problem and make the process the same in C and C++, you should declare these variables extern, for example:
/* The extern keyword makes x public. */ extern const __no_init int x @ 0x100;
Note that volatile content does not get internal linkage, so if the variable had been declared const volatile, it would not have had to be declared extern.