Bootloader Support Utilities


Detailed Description

    #include <avr/io.h>
    #include <avr/boot.h>

The macros in this module provide a C language interface to the bootloader support functionality of certain AVR processors. These macros are designed to work with all sizes of flash memory.

Note:
Not all AVR processors provide bootloader support. See your processor datasheet to see if it provides bootloader support.

Todo:
From email with Marek: On smaller devices (all except ATmega64/128), __SPM_REG is in the I/O space, accessible with the shorter "in" and "out" instructions - since the boot loader has a limited size, this could be an important optimization.
API Usage Example
The following code shows typical usage of the boot API.
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    
    void boot_program_page (uint32_t page, uint8_t *buf)
    {
        uint16_t i;
        uint8_t sreg;

        // Disable interrupts.

        sreg = SREG;
        cli();
    
        eeprom_busy_wait ();

        boot_page_erase (page);
        boot_spm_busy_wait ();      // Wait until the memory is erased.

        for (i=0; i<SPM_PAGESIZE; i+=2)
        {
            // Set up little-endian word.

            uint16_t w = *buf++;
            w += (*buf++) << 8;
        
            boot_page_fill (page + i, w);
        }

        boot_page_write (page);     // Store buffer in flash page.
        boot_spm_busy_wait();       // Wait until the memory is written.

        // Reenable RWW-section again. We need this if we want to jump back
        // to the application after bootloading.

        boot_rww_enable ();

        // Re-enable interrupts (if they were ever enabled).

        SREG = sreg;
    }


Defines

#define BOOTLOADER_SECTION   __attribute__ ((section (".bootloader")))
#define boot_spm_interrupt_enable()   (__SPM_REG |= (uint8_t)_BV(SPMIE))
#define boot_spm_interrupt_disable()   (__SPM_REG &= (uint8_t)~_BV(SPMIE))
#define boot_is_spm_interrupt()   (__SPM_REG & (uint8_t)_BV(SPMIE))
#define boot_rww_busy()   (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
#define boot_spm_busy()   (__SPM_REG & (uint8_t)_BV(SPMEN))
#define boot_spm_busy_wait()   do{}while(boot_spm_busy())
#define boot_page_fill(address, data)   __boot_page_fill_normal(address, data)
#define boot_page_erase(address)   __boot_page_erase_normal(address)
#define boot_page_write(address)   __boot_page_write_normal(address)
#define boot_rww_enable()   __boot_rww_enable()
#define boot_lock_bits_set(lock_bits)   __boot_lock_bits_set(lock_bits)
#define boot_page_fill_safe(address, data)   __boot_eeprom_spm_safe (boot_page_fill, address, data)
#define boot_page_erase_safe(address, data)   __boot_eeprom_spm_safe (boot_page_erase, address, data)
#define boot_page_write_safe(address, data)   __boot_eeprom_spm_safe (boot_page_wrte, address, data)
#define boot_rww_enable_safe(address, data)   __boot_eeprom_spm_safe (boot_rww_enable, address, data)
#define boot_lock_bits_set_safe(address, data)   __boot_eeprom_spm_safe (boot_lock_bits_set, address, data)


Define Documentation

 
#define boot_is_spm_interrupt  )     (__SPM_REG & (uint8_t)_BV(SPMIE))
 

Check if the SPM interrupt is enabled.

#define boot_lock_bits_set lock_bits   )     __boot_lock_bits_set(lock_bits)
 

Set the bootloader lock bits.

Parameters:
lock_bits A mask of which Boot Loader Lock Bits to set.
Note:
In this context, a 'set bit' will be written to a zero value.
For example, to disallow the SPM instruction from writing to the Boot Loader memory section of flash, you would use this macro as such:

    boot_lock_bits_set (_BV (BLB12));

And to remove any SPM restrictions, you would do this:

#define boot_lock_bits_set_safe address,
data   )     __boot_eeprom_spm_safe (boot_lock_bits_set, address, data)
 

Same as boot_lock_bits_set() except waits for eeprom and spm operations to complete before setting the lock bits.

#define boot_page_erase address   )     __boot_page_erase_normal(address)
 

Erase the flash page that contains address.

Note:
address is a byte address in flash, not a word address.

#define boot_page_erase_safe address,
data   )     __boot_eeprom_spm_safe (boot_page_erase, address, data)
 

Same as boot_page_erase() except it waits for eeprom and spm operations to complete before erasing the page.

#define boot_page_fill address,
data   )     __boot_page_fill_normal(address, data)
 

Fill the bootloader temporary page buffer for flash address with data word.

Note:
The address is a byte address. The data is a word. The AVR writes data to the buffer a word at a time, but addresses the buffer per byte! So, increment your address by 2 between calls, and send 2 data bytes in a word format! The LSB of the data is written to the lower address; the MSB of the data is written to the higher address.

#define boot_page_fill_safe address,
data   )     __boot_eeprom_spm_safe (boot_page_fill, address, data)
 

Same as boot_page_fill() except it waits for eeprom and spm operations to complete before filling the page.

#define boot_page_write address   )     __boot_page_write_normal(address)
 

Write the bootloader temporary page buffer to flash page that contains address.

Note:
address is a byte address in flash, not a word address.

#define boot_page_write_safe address,
data   )     __boot_eeprom_spm_safe (boot_page_wrte, address, data)
 

Same as boot_page_write() except it waits for eeprom and spm operations to complete before writing the page.

 
#define boot_rww_busy  )     (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
 

Check if the RWW section is busy.

 
#define boot_rww_enable  )     __boot_rww_enable()
 

Enable the Read-While-Write memory section.

#define boot_rww_enable_safe address,
data   )     __boot_eeprom_spm_safe (boot_rww_enable, address, data)
 

Same as boot_rww_enable() except waits for eeprom and spm operations to complete before enabling the RWW mameory.

 
#define boot_spm_busy  )     (__SPM_REG & (uint8_t)_BV(SPMEN))
 

Check if the SPM instruction is busy.

 
#define boot_spm_busy_wait  )     do{}while(boot_spm_busy())
 

Wait while the SPM instruction is busy.

 
#define boot_spm_interrupt_disable  )     (__SPM_REG &= (uint8_t)~_BV(SPMIE))
 

Disable the SPM interrupt.

 
#define boot_spm_interrupt_enable  )     (__SPM_REG |= (uint8_t)_BV(SPMIE))
 

Enable the SPM interrupt.

#define BOOTLOADER_SECTION   __attribute__ ((section (".bootloader")))
 

Used to declare a function or variable to be placed into a new section called .bootloader. This section and its contents can then be relocated to any address (such as the bootloader NRWW area) at link-time.


Automatically generated by Doxygen 1.4.1 on 21 Jul 2005.