LUFA Library - CDC Class Bootloader
CDC Class USB AVR Bootloader

Demo Compatibility:

The following list indicates what microcontrollers are compatible with this demo.

  • Series 7 USB AVRs (AT90USBxxx7)
  • Series 6 USB AVRs (AT90USBxxx6)
  • Series 4 USB AVRs (ATMEGAxxU4)
  • Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2)

USB Information:

The following table gives a rundown of the USB utilization of this demo.

USB Mode: Device
USB Class: Communications Device Class (CDC)
USB Subclass: Abstract Control Model (ACM)
Relevant Standards: USBIF CDC Class Standard
Supported USB Speeds: Full Speed Mode

Project Description:

This bootloader enumerates to the host as a CDC Class device (virtual serial port), allowing for AVR109 protocol compatible programming software to load firmware onto the AVR.

Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.

When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the bootloader from the normal user application.

Warning
THIS BOOTLOADER IS NOT SECURE. Malicious entities can recover written data, even if the device lockbits are set.

Driver Installation

After running this bootloader for the first time on a new computer, you will need to supply the .INF file located in this bootloader project's directory as the device's driver when running under Windows. This will enable Windows to use its inbuilt CDC drivers, negating the need for custom drivers for the device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers.

Host Controller Application

This bootloader is compatible with the open source application AVRDUDE, Atmel's AVRPROG, or other applications implementing the AVR109 protocol, which is documented on the Atmel website as an application note.

AVRDUDE (Windows, Mac, Linux)

AVRDude is a free, cross-platform and open source command line programmer for Atmel and third party AVR programmers. It is available on the the Windows platform as part of the "WinAVR" package, or on other systems either from a build from the official source code, or in many distributions as a precompiled binary package.

To load a new HEX file with AVRDude, specify "AVR109" as the programmer, with the allocated COM port. On Windows platforms this will be a COMx port name:

avrdude -c AVR109 -p at90usb1287 -P COM0 -U flash:w:Mouse.hex

On Linux systems, this will typically be a /dev/ttyACMx port name:

avrdude -c AVR109 -p at90usb1287 -P /dev/ttyACM0 -U flash:w:Mouse.hex

Refer to the AVRDude project documentation for additional usage instructions.

User Application API

Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader, allowing the user application to call into the bootloader at runtime to read and write FLASH data.

By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the following layout:

#define BOOTLOADER_API_TABLE_SIZE 32
#define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
#define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
#define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
#define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
#define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
#define BOOTLOADER_CDC_SIGNATURE 0xDF00
#define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
#define BOOTLOADER_ADDRESS_LENGTH 4

From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader can be determined by reading the FLASH memory bytes located at address BOOTLOADER_CLASS_SIGNATURE_START and comparing them to the value BOOTLOADER_CDC_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH memory starting from address BOOTLOADER_ADDRESS_START.

Device Memory Map

The following illustration indicates the final memory map of the device when loaded with the bootloader.

*  +----------------------------+ 0x0000
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |      User Application      |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  |                            |
*  +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
*  |                            |
*  |   Bootloader Application   |
*  | (Not User App. Accessible) |
*  |                            |
*  +----------------------------+ FLASHEND - 96
*  |   API Table Trampolines    |
*  | (Not User App. Accessible) |
*  +----------------------------+ FLASHEND - 32
*  |    Bootloader API Table    |
*  |   (User App. Accessible)   |
*  +----------------------------+ FLASHEND - 8
*  |   Bootloader ID Constants  |
*  |   (User App. Accessible)   |
*  +----------------------------+ FLASHEND
*  

Known Issues:

On Linux machines, the CDC bootloader is unstable or inaccessible.
A change to the ModemManager module in many Linux distributions causes this module to try to take control over inserted CDC devices, corrupting the datastream. A UDEV rule is required to prevent this. See here for resolution steps.
On Linux machines, the CDC bootloader is inaccessible.
On many Linux systems, non-root users do not have automatic access to newly inserted CDC devices. Root privileges or a UDEV rule is required to gain access. See here for resolution steps.
After loading an application, it is not run automatically on startup.
Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader to run automatically when the device is reset. In most cases, the BOOTRST fuse should be disabled and the HWBE fuse used instead to run the bootloader when needed.

Project Options

The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.

Define Name: Location: Description:
NO_BLOCK_SUPPORT AppConfig.h Define to disable memory block read/write support in the bootloader, requiring all reads and writes to be made using the byte-level commands.
NO_EEPROM_BYTE_SUPPORT AppConfig.h Define to disable EEPROM memory byte read/write support in the bootloader, requiring all EEPROM reads and writes to be made using the block-level commands.
NO_FLASH_BYTE_SUPPORT AppConfig.h Define to disable FLASH memory byte read/write support in the bootloader, requiring all FLASH reads and writes to be made using the block-level commands.
NO_LOCK_BYTE_WRITE_SUPPORT AppConfig.h Define to disable lock byte write support in the bootloader, preventing the lock bits from being set programmatically.