Remember the first time you got the Arduino to blink an LED? When you clicked the icon on your desktop, and some little lights on the Arduino board blinked like crazy for a few seconds, and then it just worked? Brace yourself, because we are about to ruin that magic forever and reveal what actually happens behind the scenes!
Preparing the Code
We begin by writing (hopefully) or copy-pasting some code into the Arduino IDE. So far, this is nothing more than using a simple text editor.
Then we click the Upload icon.
First, the IDE takes what we wrote and incorporates it into a pre-made C++ code template. This template is in the file “main.cpp”, somewhere deep in the Arduino directory on your computer. Here’s what’s in it (comments not included):
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
See the “setup()” and “loop()” in there? Those are calls to the functions we wrote earlier. The loop function doesn’t loop itself – if you know a bit of C/C++ you’ll understand that it’s simply called over and over again inside an infinite loop. Don’t worry, I’ll discuss this programming stuff a lot in the future.
Compiling
Now the IDE has the raw code for a complete C++ program. This it hands over to a compiler software, which takes the code, checks whether it’s valid, and if it is, produces a translation of it into the AVR Instruction Set commands, which the Arduino can understand and follow (see here). If there’s an obvious problem with the source code, the error report is sent back to the IDE for displaying.
At this point, the translated code is still on your PC, in a special file with the .HEX suffix. The compiler can do nothing more with it; the IDE therefore invokes a different software (called “AVRDude”) that knows how to send this file to the Arduino via USB.
There is a catch, however. Microcontrollers such as the one on the Arduino are usually programmed using special, relatively expensive devices (“programmers”) that require software drivers of their own and other complexities. Using or even emulating them for the Arduino would have caused it to be too cumbersome and/or costly for the hobbyists. So a different path was taken: a Bootloader.
The Bootloader
The Bootloader is a small program that the Arduino manufacturer put on the microcontroller for you. It sits there, using up some precious FLASH memory space, and it is actually the first to execute when the Arduino is powered up or reset. It listens for a short time to the USB connection, to see if an attempt is being made to upload new code. If not, it simply quits and hands over the control to the “regular” program – the last one that was uploaded successfully.
If the Bootloader does detect an incoming program, it stays active, reads the data being sent and burns it onto a different area on the FLASH memory.
So essentially, AVRDude sends a reset signal to the Arduino, which causes it to reset (obviously) and therefore load the Bootloader. Then, AVRDude transfers the contents of the .HEX file to the active Bootloader, who writes it to the FLASH. Finally, the Bootloader stops and the new program runs.
Many Fans To Hit
This chain of processes from C++ code on the PC to a running Arduino program [text editor -> pre-builder -> compiler -> AVRDude -> Bootloader -> Microcontroller FLASH memory] is not just a technical note; understanding it can help you understand many Arduino errors, and trace bugs and other issues more easily. For instance, if you try to upload a program and get an error message that says “AVRDude [something something]”, you know the problem is somewhere in the communication between AVRDude and the Bootloader: noise/bad connection on the signal lines, wrong Bootloader version (e.g. a different Arduino board than the one you picked in the IDE menu), even corrupt or no Bootloader at all – yes, that too can happen, if the circumstances are right!