5.3. EEPROM

All AVR processors contain a bank of nonvolatile memory. Unfortunately, this memory doesn't reside in the same address space as the static RAM; the architecture requires that the EEPROM cells be accessed through I/O registers. The EEPROM API provides a high-level interface to the hardware, which makes using the nonvolatile memory much easier. To gain access to these functions, include the file eeprom.h.

The routines take an argument representing the address of the cell. Rather than using hard-coded numbers or defined symbols, it would be nice to use actual variables. AVR-GCC allows this by using the __attribute__ keyword. Example 5-1 shows a function that returns a checksum value from the EEPROM. The example allocates space in the .eeprom section to hold the variable, but doesn't specify the actual address. By taking this approach, the linker will properly fix-up the address references.

Example 5-1. Proper use of EEPROM variables

    static uint8_t checksum __attribute__((section (".eeprom"))) = 0;
    
    uint8_t getChecksum(void)
    {
        return eeprom_rb(&checksum);
    }

The amount of nonvolatile memory varies from device to device. The linker "knows" the limits of the sections, so by letting the compiler and linker reserve the space for variables, you can get diagnostic messages if you exceed the size of the bank. This can also come in handy if you need to switch device types in a project.