ATmega328P Notes

Some notes on first attempts at programming an AVR chip on a breadboard. The first task was to get an Arduino bootloader with an CP2102 USB to Serial without DTR. It took a while to fathom out the necessary bits, so here are some words to jog my memory in future…

The bootloader is essentially a feature of the ATmega328P chip (among many other AVR chips). A configurable (via fuses) amount of flash is reserved at the top of memory, and this area is programmed with the bootloader, typically from a standard Intel format hex file.

The AVR differentiates between bootloader and application (aka skech, in Arduino speak). The bootloader memory can be protected with Lock bits that can, among other things, prevent the bootloader memory area from being overwritten. Similar protection is offered by Lock bits on the application memory.

Looking at the hex files produced for both a sketch vs a bootloader, there are interrupt vectors at the beginning of each (datasheet section 16.1 defines 26 vectors, so 52 words or 104 bytes). The actual vector used during a reset is defined by the fuse BOOTRST which if programmed (i.e. zero, since an unprogrammed flash byte is 0xff) will result in the vector table defined in the bootloader memory area to be used.

In short, this means that if BOOTRST is programmed, a reset will result in the bootloader code handing the reset. If unprogrammed (left as 1), then the application (i.e. sketch) code will run on reset. Typically, this code will look at the cause of the reset and decide how to proceed – if an external reset, then start the upload sequence, otherwise run the application.

When compiling and linking the bootloader, make sure that the hex file generated has the flash content at the right address (e.g. -Wl,-section-start=.text=0x7000). The gcc linker and the hex file generator use byte addresses here, but the AVR addresses its memory in words. In this case, 0x7000 refers to address 0x3800 in the AVR, whereby I’d be using 2K words for the bootloader space, from 0x3800 to 0x3fff (0x7000 to 0x7fff in byte addressing).

The following symbols were defined for compilation when I built from the optiboot source in AtmelStudio


Only the first two are required, the last two were added to help debug or to eliminate some doubts about the code being used. They will be removed.

Leave a Reply

Your email address will not be published. Required fields are marked *