Use the global variable address modifier to assign global variables to specific addresses and to access memory-mapped I/O ports. These variables, called absolute variables, have the following syntax:
Declaration = <TypeSpec> <Declarator>[@<Address>|@"<Section>"]
[= <Initializer>];
<TypeSpec> is the type specifier, for example, int, char
<Declarator> is the identifier of the global object, for example, i, glob
<Address> is the absolute address of the object, for example, 0xff04, 0x00+8
<Initializer> is the value to which the global variable is initialized.
The frontend creates a segment for each global object specified with an absolute address. This address must not be inside any address range in the SECTIONS entries of the link parameter file, or a linker error (overlapping segments) occurs. If the specified address has a size greater than that used for addressing the default data page, pointers pointing to this global variable must be __far. The following listing shows an alternate way to assign global variables to specific addresses.
#pragma DATA_SEG [__SHORT_SEG] <segment_name>
This sets the PLACEMENT section in the linker parameter file. An older method of accomplishing this is shown in the following listing.
<segment_name> INTO READ_ONLY <Address> ;
Use the LINEAR attribute to specify linear addresses in extended memory. Since extended memory is Flash memory, use const as the global variable.
const char const_data @ LINEAR 0x01A6AB /*0x06A6AB*/ = 0x30;
Listing: Using the Global Variable Address Modifier shows a correct and incorrect example of using the global variable address modifier and Listing: Corresponding Link Parameter File Settings (PRM file) shows a possible PRM file that corresponds with Listing: Using the Global Variable Address Modifier.
int glob @0x0500 = 10; // OK, global variable "glob" is // at 0x0500, initialized with 10 void g() @0x40c0; // error (the object is a function) void f() { int i @0x40cc; // error (the object is a local variable) }
/* the address 0x0500 of "glob" must not be in any address range of the SECTIONS entries */ SECTIONS MY_RAM = READ_WRITE 0x0800 TO 0x1BFF; MY_ROM = READ_ONLY 0x2000 TO 0xFEFF; MY_STACK = READ_WRITE 0x1C00 TO 0x1FFF; MY_IO_SEG = READ_WRITE 0x0400 TO 0x4ff; END PLACEMENT IO_SEG INTO MY_IO_SEG; DEFAULT_ROM INTO MY_ROM; DEFAULT_RAM INTO MY_RAM; SSTACK INTO MY_STACK; END