Almost all microcontroller (and microprocessor) development systems use some form of a bootloader. Often called firmware, mistakenly, the Arduino bootloader is one example. Since it is a rather popular platform, let’s use it as an example. Let’s talk about what a bootloader does and how it works.
When a microcontroller turns on, it only knows how to do one thing. Typically, that one thing is to run an instruction found at a specific memory location. Often this location address 0x0000, but not always. Usually, this memory location will contain a jump instruction to another place in memory, which is the start of the user program. The bootloader, however, exists in a slightly separate memory space from the user program.
On power-up or reset, a bootloader is a section of program memory that runs before the main code runs. It can be used to setup the microcontroller or provide limited ability to update the main program’s code.
How the Arduino Bootloader works
The Arduino bootloader supports re-programming the program memory (or Flash) over serial. Without it, you would need a dedicated hardware programmer, like the USBtiny, to change the code in the Uno’s ATmega328p.
Like many microcontrollers, the ATmega328p dedicates a portion of its program memory for bootloading code. In the case of the Uno, the Arduino bootloader waits a short time while watching the UART pins. If the bootloader does not receive a particular sequence of bytes over the serial port, then the processor jumps to the “user” program section to load whatever is already in program memory. This jump loads your program (or sketch).
If the pre-defined sequence is received, the Arduino bootloader pretends to be an AVR programmer. In the case of the Uno, a unique programming protocol called “arduino” is used. This “special protocol” is a variant of the stk500 hardware programmer. Other Arduino boards have other programmer types they emulate.
At this point avrdude will begin sending your program’s binary data with a protocol over the virtual serial port. The program memory (PROGMEM) of the ATmega328p stores the incoming byte stream. Once completed, the chip resets and starts the new code.
Re-programming the FLASH, without a dedicated programmer, is only possible when the code is running during the “bootload” phase. The idea is to prevent malicious (or buggy) code from changing the contents of Flash.
- The Arduino bootloader is always the first stuff to run.
- If the bootloader receives a unique sequence, then the byte stream is programmed into FLASH
- Else, the bootloader turns control over to the existing user code.
Leonardo Bootloader Note
On the AVR 32u4 based Leonardo and Micro boards, the bootloader works differently than the serial-based Arduino. For a detailed explanation of the boot sequence, read this Leonardo product page. They still use a bootloader, but it works different from the 328p and Mega2560 variants.
At a higher level, bootloaders can be used to either pre-configure a microcontroller/microprocessor or, in the case of the Arduino bootloader, allow “field programming” of an end device. While you might use the Arduino bootloader to test and develop code in your project, you could also use the bootloader to update code in a shipping product.
While bootloaders offer incredible advantages, there are some aspects you should consider if you keep a bootloader installed on a finished project.
Looking back at how the Arduino bootloader works, remember that it delays executing the “real” program code. That fact means there is a delay before for your code runs at start-up.
If you have bootloader code, that is less memory space for your program. The Uno’s optiboot bootloader takes up 508 bytes (512-byte block minus the remaining 4 bytes). Keep in mind that with 32k of Flash memory, regaining an extra 512 bytes might not mean much.
Since the Arduino bootloader runs before your code, it might set some of the registers differently than expected. For example, some people had trouble with the watchdog timer on early versions of the Arduino bootloader. Fortunately, the optiboot bootloader, which is more common today, solves the watchdog timer issue.
- Bootloader Page on Arduino.cc
- Bootloader Tip, Tricks, and Techniques from Adafruit
- USB Tiny, dedicated programmer, from Adafruit
- Optiboot Source on Github
- Detailed Optiboot information from Arduino Forum
The Arduino bootloader makes programming a board like the Uno a piece of cake. Bootloaders are not perfect and take some resources you might need for your project. However, the trade-offs are usually worth it!