Chapter 5. Memory APIs

Table of Contents
5.1. Program Memory
5.2. Function Reference
5.3. EEPROM
5.4. Function Reference

The AVR family of processors do not use a single address space to map data and code. Since the registers are 8 bits wide, and the registers are used to write to RAM, the static RAM was made 8 bits wide. The program memory, on the other hand, is 16 bits wide. This allows the instructions to represent more operations in a single memory access. In addition, the EEPROM resides in yet another bank of memory.

AVR-GCC places code in the flash ROM and places data in the SRAM, which would be expected. If your program needs to access the EEPROM or place data in the ROM, however, things are a little less intuitive. This chapter shows what support has been provide for these situations.

5.1. Program Memory

Placing data in ROM is very useful to embedded applications: the data is always available and doesn't have to be generated at startup. Even more importantly, the data cannot get corrupted by an errant application, which reduces the number of considerations when debugging.

Since the ROM resides in a different address space, we need a way to tell the compiler to place variables there. We also need a way to access the data (i.e. the compiler has to use the lpm instruction.)

The first detail is provided by the __attribute__ keyword. By tagging a variable with __attribute__((progmem)), you can force it to reside in the ROM. Variables with this attribute cannot be accessed like variables not using the attribute. You need to use the macros described in this section to access the data in ROM. There are a number of data types already defined for the primitive types. These are shown in Table 5-1.

Table 5-1. Primitive types in program memory

Type NameDefinition
prog_voidvoid __attribute__((progmem))
prog_charchar __attribute__((progmem))
prog_ucharunsigned char __attribute__((progmem))
prog_intint __attribute__((progmem))
prog_longlong __attribute__((progmem))
prog_long_longlong long __attribute__((progmem))
PGM_Pprog_char const*
PGM_VOID_Pprog_void const*

The second step, accessing the data, is done using the macros in this section. These macros are found in pgmspace.h.