[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.16.1 AVR Named Address Spaces
On the AVR target, there are several address spaces that can be used
in order to put read-only data into the flash memory and access that
data by means of the special instructions LPM
or ELPM
needed to read from flash.
Per default, any data including read-only data is located in RAM (the generic address space) so that non-generic address spaces are needed to locate read-only data in flash memory and to generate the right instructions to access this data without using (inline) assembler code.
__flash
-
The
__flash
qualifier locates data in the.progmem.data
section. Data is read using theLPM
instruction. Pointers to this address space are 16 bits wide. __flash1
__flash2
__flash3
__flash4
__flash5
-
These are 16-bit address spaces locating data in section
.progmemN.data
where N refers to address space__flashN
. 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 from RAM using the lower two bytes as RAM address. If the high bit of the address is clear, data is read from flash with
RAMPZ
set according to the high byte of the address. See section__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 equally named but uppercase built-in macro defined. The purpose is to facilitate testing if respective address space support is available or not:
#ifdef __FLASH const __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 attribute progmem
locates data in flash but
accesses to these data read from generic address space, i.e.
from RAM,
so that you need special accessors like pgm_read_byte
from http://nongnu.org/avr-libc/user-manual/">AVR-LibC
together with attribute progmem
.
Limitations and caveats
-
Reading across the 64 KiB section boundary of
the
__flash
or__flashN
address spaces shows undefined behavior. The only address space that supports reading across the 64 KiB flash segment boundaries is__memx
. -
If you use one of the
__flashN
address spaces you must arrange your linker script to locate the.progmemN.data
sections according to your needs. -
Any data or pointers to the non-generic address spaces must
be qualified as
const
, i.e. as read-only data. This still applies if the data in one of these address spaces like software version number or calibration lookup table are intended to be changed after load time by, say, a boot loader. In this case the right qualification isconst
volatile
so that the compiler must not optimize away known values or insert them as immediates into operands of instructions. -
The following code initializes a variable
pfoo
located in static storage with a 24-bit address:extern const __memx char foo; const __memx void *pfoo = &foo;
Such code requires at least binutils 2.23, see PR13503.
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on October 19, 2013 using texi2html 5.0.