Arduino Behind the Scenes

From Interaction Station Wiki
Jump to: navigation, search

In the Arduino Introduction you could read that Arduino is in principle an attempt to make physical computing easier accessible for the average user. It did this by creating a hardware platform (development board) based on the Atmel AVR 8- and 32-bit family of μControllers. You also got introduced to the Wiring[1] language framework Arduino implemented for their hardware platforms and the Integrated Development Environment (IDE) Arduino adapted from the Processing project.

In this section we will go a bit further and see what all these elements are hiding from us.

Have a cappuccino

When we advance in our explorations at some point it is important to realise that making things easier usually means making compromises on other levels. In case of the Arduino and Wiring language framework this specifically means we compromise memory space and execution speed for ease of programming. In many cases this is perfectly fine but there are certain situations where it is important to understand these compromises and their ways around it (on the compromise of ease of use).

In principle Arduino adds a lot of milk and sugar to the μController it is based on. This makes us a nice cappuccino, but what if what we need is an espresso?

Cappuccino vs. espresso

The ingredient to our cappucino is quite close and is revealed by first thing you'll see when starting a new sketch in the Arduino IDE. Each new sketch will start with the standard template:

  1. void setup() {
  2.   // put your setup code here, to run once:
  4. }
  6. void loop() {
  7.   // put your main code here, to run repeatedly:
  8. }

Now this looks easy enough and we all know how what to do here. However, of course there is more to this and to understand what, it is important to know the language we are actually writing our Arduino (Wiring) code in. The language used by the Wiring language (and with that the Arduino language) is C / C++ with an additional sugar topping. Actually this is a combination of the languages C and C++ which can be intermingled. From here on, for brevity, everywhere C is mentioned it can be read as C / C++ unless noted otherwise.

Every program written in C should contain at least a routine called main. This is the main entry point for code execution[2]. The simplest C program that does nothing at all looks like this:

  1. int main(void) {
  2.   // put your code here
  3. }

If Arduino code is just C code, where is the main routine in the above example? It turns out the main routine does exist but is hidden below the surface. When we press the Verify or Upload button in the IDE a lot of things are set in motion to get your code translated into a format the μController on the Arduino board does understand. Later we will see what exactly does happen but for now it is enough to understand that our setup() and loop() routines are added to the main routine.

In the arduino core[3] there exists a file main.cpp[4]. This is the the file where the main entry point resides. If you open this file in your text editor you will see something along these lines[5]

  1. #include <WProgram.h>
  3. int main(void)
  4. {
  5.         init();
  7.         setup();
  9.         for (;;)
  10.                 loop();
  12.         return 0;
  13. }

The names on the highlighted lines 7 & 10 should look familiar. These are the function calls to the setup() and loop() routines in your arduino program. So you can see that, when the μController starts executing its program, it is actually the init() routine that is executed first. This routine takes care of low-level housekeeping, e.g. setting up the timers for keeping track of elapsed timed. Only after all low level initialisations have been done the user setup() routine is called. Once setup() is done the loop() routine is called from within the infinite loop construct for (;;). The last statement on line 12, return 0;, is never reached and is only there to keep the compiler from complaining[6].

Notes & References

  2. The linker will search for this function within the source files. If it can't find it it will fail with an error message like (.text+0x20): undefined reference to `main.
  5. Shown code is from an earlier version. The current version is a bit more complicated. However the overall structure remains the same
  6. The main() routine is declared as returning an integer. If the compiler finds no value being returned on reaching the end of the function definition the compiler will complain with a warning message: control reaches end of non-void function.