Next:Attributes Specific to GCC, Previous:Array, Union, and Struct Extensions, Up:Extensions to the C Language Family [Contents][Index]
As an extension, GNU C supports named address spaces asdefined in the N1275 draft of ISO/IEC DTR 18037. Support for namedaddress spaces in GCC will evolve as the draft technical reportchanges. Calling conventions for any target might also change. Atpresent, only the AVR, M32C, PRU, RL78, and x86 targets supportaddress spaces other than the generic address space.
Address space identifiers may be used exactly like any other C typequalifier (e.g.,const orvolatile). See the N1275document for more details.
On the AVR target, there are several address spaces that can be usedin order to put read-only data into the flash memory and access thatdata by means of the special instructionsLPM orELPMneeded to read from flash.
Devices belonging toavrtiny andavrxmega3 can accessflash memory by means ofLD* instructions because the flashmemory is mapped into the RAM address space. There isno needfor language extensions like__flash or attributeprogmem.The default linker description files for these devices cater for thatfeature and.rodata stays in flash: The compiler just generatesLD* instructions, and the linker script adds core specificoffsets to all.rodata symbols:0x4000 in the case ofavrtiny and0x8000 in the case ofavrxmega3.SeeAVR Options for a list of respective devices.
For devices not inavrtiny oravrxmega3,any data including read-only data is located in RAM (the genericaddress space) because flash memory is not visible in the RAM addressspace. In order to locate read-only data in flash memoryandto generate the right instructions to access this data withoutusing (inline) assembler code, special address spaces are needed.
__flash ¶The__flash qualifier locates data in the.progmem.data section. Data is read using theLPMinstruction. Pointers to this address space are 16 bits wide.
__flash1 ¶__flash2__flash3__flash4__flash5These are 16-bit address spaces locating data in section.progmemN.data whereN refers toaddress space__flashN.The compiler sets theRAMPZ segment register appropriately before reading data by means of theELPM instruction.
__flashx ¶This is a 24-bit flash address space locating data in section.progmemx.data.The compiler sets theRAMPZ segment register appropriately before reading data by means of theELPM instruction.
__memx ¶This is a 24-bit address space that linearizes flash and RAM:If the high bit of the address is set, data is read fromRAM using the lower two bytes as RAM address.If the high bit of the address is clear, data is read from flashwithRAMPZ set according to the high byte of the address.See__builtin_avr_flash_segment.
Objects in this address space are located in.progmemx.data.
Example
char my_read (const __flash char ** p){ /* p is a pointer to RAM that points to a pointer to flash. The first indirection of p reads that flash pointer from RAM and the second indirection reads a char from this flash address. */ return **p;}/* Locate array[] in flash memory */const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };int i = 1;int main (void){ /* Return 17 by reading from flash memory */ return array[array[i]];}For each named address space supported by avr-gcc there is an equallynamed but uppercase built-in macro defined. The purpose is to facilitate testing if respective address spacesupport is available or not:
#ifdef __FLASHconst __flash int var = 1;int read_var (void){ return var;}#else#include <avr/pgmspace.h> /* From AVR-LibC */const int var PROGMEM = 1;int read_var (void){ return (int) pgm_read_word (&var);}#endif /* __FLASH */Notice that attributeprogmemlocates data in flash butaccesses to these data read from generic address space, i.e.from RAM,so that you need special accessors likepgm_read_bytefromAVR-LibCtogether with attributeprogmem.
Limitations and Caveats
__flash or__flashN address spacesis not supported. The only address spaces thatsupport reading across the 64 KiB flash segment boundaries are__memx and__flashx.__flashN address spacesyou must arrange your linker script to locate the.progmemN.data sections according to your needs.For an example, see theavr-gcc wikiconst, i.e. as read-only data.This still applies if the data in one of these addressspaces like software version number or calibration lookup table are intended tobe changed after load time by, say, a boot loader. In this casethe right qualification isconstvolatile so that the compilermust not optimize away known values or insert themas immediates into operands of instructions.pfoolocated in static storage with a 24-bit address:extern const __memx char foo;const __memx void *pfoo = &foo;
progmem is supported but works differently,seeAVR Variable Attributes.On the M32C target, with the R8C and M16C CPU variants, variablesqualified with__far are accessed using 32-bit addresses inorder to access memory beyond the first 64 Ki bytes. If__far is used with the M32CM or M32C CPU variants, it has noeffect.
On the PRU target, variables qualified with__regio_symbol arealiases used to access the special I/O CPU registers. They must bedeclared asextern because such variables will not be allocated inany data memory. They must also be marked asvolatile, and canonly be 32-bit integer types. The only names those variables can haveare__R30 and__R31, representing respectively theR30 andR31 special I/O CPU registers. Hence the followingexample is the only valid usage of__regio_symbol:
extern volatile __regio_symbol uint32_t __R30;extern volatile __regio_symbol uint32_t __R31;
On the RL78 target, variables qualified with__far are accessedwith 32-bit pointers (20-bit addresses) rather than the default 16-bitaddresses. Non-far variables are assumed to appear in the topmost64 KiB of the address space.
On the x86 target, variables may be declared as being relativeto the%fs or%gs segments.
__seg_fs ¶__seg_gsThe object is accessed with the respective segment override prefix.
The respective segment base must be set via some method specific tothe operating system. Rather than require an expensive system callto retrieve the segment base, these address spaces are not consideredto be subspaces of the generic (flat) address space. This means thatexplicit casts are required to convert pointers between these addressspaces and the generic address space. In practice the applicationshould cast touintptr_t and apply the segment base offsetthat it installed previously.
The preprocessor symbols__SEG_FS and__SEG_GS aredefined when these address spaces are supported.
Next:Attributes Specific to GCC, Previous:Array, Union, and Struct Extensions, Up:Extensions to the C Language Family [Contents][Index]