Eclipse Luna with AVR Plugin for Arduino Development
When starting with the Arduino, we usually take the Arduino IDE that is available on the net as it is so easy to use and works well for the first tests. However, those of us who write programs more often quickly recognize the downside of this simple IDE. For example, we are used to more powerful editors with code completion, automatic source code formatting, tweaking the compiler flags and so on.
Many users are familiar with Eclipse and the CDT plugin for writing C/C++ programs and the question of how to configure Eclipse to program the Arduino quickly pops up. There are many tutorials on the net, some of them work, some are outdated. When you have found one that finally works, you have a lot of stuff to configure and quickly miss some of the nice features of the Arduino IDE, like the library concept: Simply put code into a folder and you can use it out of the box.
In this document, I write down my experience getting the latest Eclipse version (Luna) up and running on my Ubuntu 12.04 laptop.
2 First Installation Setup
In the following subsections, you will find all required steps to install the toolchain to develop Arduino applications in Eclipse. In the next section, we will then use this toolchain to setup the projects to build the Arduino applications.
2.1 Install the AVR ToolChain
On Ubuntu, this is easily achieved by executing sudo apt-get install avrdude binutils-avr gcc-avr avr-libc gdb-avr.
However, this installs an old tool chain that has known bugs, e.g., when linking with the -mrelax option. If you want to use the latest or at least a recent toolchain, you should build the binutils, gcc and avr-libc yourself. To do this, install only the following components from the Ubuntu world: sudo apt-get install avrdude gdb-avr. Then follow the guide at http://www.nongnu.org/avr-libc/user-manual/install_tools.html to install your own binutils, gcc and libc for AVR. As suggested in the guide, use a directory like/usr/local/avr to host the tools. Remember to add the directory /usr/local/avr/bin to your PATH variable and the directory /usr/local/avr/lib to your LD_LIBRARY_PATH variable.
2.2 Download and Extract the Arduino SDK
Download the Arduino SDK. I used the stable version 1.0.6 in my tests. Extract the SDK into a directory of your choice. For example, you might want to put everything into one directory called ArduinoEclipse, so your Arduino SDK would go intoArduinoEclipse/arduino-1.0.6.
2.3 Installing Eclipse Luna
2.3.1 Install and Enable Java 7
Eclipse Luna requires at least Java 7 to work properly. So you may need to install Java 7 first. On Ubuntu, execute sudo apt-get install openjdk-7-jdk openjdk-7-jre. If you have multiple Java Versions installed, you might need to switch to Java 7 by executingsudo update-alternatives --config java and selecting the correct Java version.
2.3.2 Change the GTK+ Theme in KDE
If you are using KDE, you have to change the GTK+ theme to not use the Oxygen theme. Apparently this theme has some issues that cause Eclipse to crash very often. So open the KDE System Settings and select the item Application Appearance. On the left side, there is a category called GTK+ Appearance. Select it and choose a Widget style other than oxygen-gtk.
2.3.3 Download and Extract Eclipse Luna
Download Eclipse Luna from the Eclipse homepage. Use the Eclipse IDE for C/C++ Developers that comes with the CDT plugin. Then extract it somewhere in your file system. I’ve used the home directory for my tests, but it should work from every other directory as well, e.g., ArduinoEclipse/eclipse.
2.3.4 Install the AVR Plugin
Start Eclipse by entering the eclipse directory and execute ./eclipse. You will be first asked for a workspace location. Again, you are free to choose whatever you want, e.g., ArduinoEclipse/workspace.
Now it is time to install the AVR plugin. In the Help menu, choose the Install New Software... item. In the text field labeled Work with you should enter the URL http://avr-eclipse.sourceforge.net/updatesite and click on the Add button. You can now give this site a name like AVR Plugin. After selecting this site, you should see the item AVR Eclipse Plugin. Check it and click on Next to install it. You will be asked to accept the license and after the installation are asked to restart Eclipse.
After the restart, the AVR plugin can be seen by looking into the menu. Here, you should have a new entry labeled AVR.
2.3.5 Global AVR Configuration
Open the Window menu and select Preferences. Then select the AVR -> Paths section. As you have installed the AVR toolchain in system directories, the paths should all be detected and valid. The entry Atmel Part Description Files can be ignored.
Now select the AVR -> AVRDude section. Here, you should select Use custom configuration file for AVRDude and click on the Browse button. Select the file <Arduino SDK>/hardware/tools/avrdude.conf from your Arduino SDK installation.
Then you should add a new Programmer configuration. Click on the Add button and enter a name and description for the entry, e.g., Arduino Nano. Select Arduino in the Programmer Hardware list, set your port in the Override default port field (/dev/ttyUSB0for Arduino Nano, /dev/ttyACM0 for Arduino Uno), and set the baud rate to 57600 in the Override default baudrate field.
After setting these preferences, click OK to close the Preferences window.
3 Software Organisation
The original Arduino IDE somehow pickes all the required elements and builds them into one flashable image. So parts of the Arduino Core Library, the individual custom libraries and the application code are compiled and linked into one ELF file. This is all controlled by the Arduino IDE itself, no Makefile is used and when it comes to rebuilding the application after a restart of the Arduino IDE, all the elements are compiled again.
On the other hand, a standard software structure contains libraries and applications, where each element is only built when its sources are changed. The idea is to reuse not only source code, but also object code (in the form of libraries) and to keep the compilation steps to a minimum.
Our software organisation is as follows: One static library called ArduinoCore to hold the basic Arduino software layer, one static library to contain all the additional stuff that is called “library” in the Arduino IDE, and finally the custom application that links against both libraries. Since the linker is able to include only those object files in an application that are actually used, the application will not be larger than an Arduino IDE result.
However, we need to keep one thing in mind: When we change the Arduino variant in the Arduino IDE and rebuild the project, all relevant parts of the core library, the custom libraries and the application are build with the correct environment (that is the correct set of defines and include paths to support the different variants, compiler flags regarding optimization options, etc.). When we want to switch to a different variant in the proposed Eclipse software structure, we have to adjust the environment in all software components. Eclipse gives us a maximum flexibility by defining them on a build configuration level for each project. However, this means we have to configure items over and over again, since there is no native concept of inheritance between build configurations. But we can optimize this process by using Names for the build configurations that include all relevant information and use the export/import functionality of the path settings.
3.1 The Arduino Core Library
The Arduino core library contains the basis for the Arduino programs, like all the helper functions and classes like serial communication etc. It is shipped as part of the Arduino SDK and the relevant files are located in the directory <Arduino SDK>/hardware/arduino/cores/arduino. In addition, the pin layout is kept in header files organized in the <Arduino SDK>/hardware/arduino/variants directory. Since the pin layout might be different on Arduino variants that share the same processor, we will name our build configurations like ArduinoNanoV3_Release.
So let us start by creating the Eclipse project for the core library. Create a new C++ Project by right clicking into the projects list or selecting New from the File menu. Open the AVR Cross Target Static Library section and select Empty Project. Name the project ArduinoCore and click on Next.
Usually, we don’t want to build debug versions of the core library, so deselect Debug and click on Next. We will configure the build configuration later.
Now you need to specify the MCU Type, e.g., ATmega328P for the Arduino Nano V3, and the MCU Frequency, e.g., 16000000. Then click Finish to complete the wizard.
You will now see the project on the left side in the Project Explorer. To avoid cluttering the project we create first a folder called src to host all the sources of the core library. Now right click on the newly created folder and select Import. Choose General -> File System and click Next. Select the directory <Arduino SDK>/hardware/arduino/cores/arduino and select all files. If you want to, you can create links instead of copying the files directly. Click Finish to copy the files resp. create the links. Now repeat this procedure with the variants directory found in <Arduino SDK>/hardware/arduino/variants, but use the destination directory src/variants. Now we have all the source files available and we need to specify the build configuration.
Right click on the project and select Build Configurations -> Manage. Rename the Release build configuration to a name of your choice, e.g., ArduinoNanoV3_Release. Close the management window and open the Project Properties. On the AVR category, click on Enable individual settings for Build Configurations. This will allow us to create different build configurations for different processor types. Since you have already specified the initial MCU settings, we don’t need to modify them.
Now open the C/C++ General -> Paths and Symbols category. Here, we have to add a new include path to the src directory: Click on Add and on Workspace to select the directory. Then check Add to all languages and click OK. The next include path depends on your actual Arduino variant. For the Arduino Nano V3, it is src/variants/eightanaloginputs. For the Arduino Uno, it should be src/variants/standard. Again, add this path to all languages. Besides the include paths, we should also add some defines. For the Arduino Nano V3, add ARDUINO=106, USB_PID=null, USB_VID=null (to all languages). [A] After setting all these paths and symbols, click on Apply.
Now select the C/C++ Build section. Under Behaviour, you can enable the parallel build which makes compiling obviously faster. If you want to tweak the compiler options, you can open the subsection Settings and change the appropriate entries in the Tool Settings. For the core library, the defaults usually work fine.
After closing the Properties window, you can build the configuration right away. If everything works fine, you should see the static library libArduinoCore.a in the folder named after your build configuration.
Before we continue with the next library, let us first describe the steps required to add another variant. Right click on the project and select Build Configurations -> Manage again. Click on the New button and give it a name, e.g., ArduinoUnoV3_Release. Select Copy settings from Existing configuration. Then edit the project Properties and modify the include path for the variant, e.g., set it to src/variants/standard. You have now created a second configuration and are able to switch between both configurations as you like. You can also simply build both configurations by using the Build All menu item, so you don’t have to worry about what configuration you have last build.
3.2 The Arduino Extras Library
The libraries directory of the Arduino SDK contains additional modules from various sources. These can be either put into separate libraries, or you can put them into one single library called ArduinoLibrary. Here, we put all modules of interest into a single library. The steps are similar to the Arduino Core library. When importing the files, you should exclude all the examples folders, as they are not part of the library. You also have to define many additional include paths, one for every module and eventually one for the utility subdirectory of the modules. Of course, you also need the include paths to the ArduinoCore library and the defines for your Arduino Variant as previously described. If you are lazy, you can start by copying the build configurations from the ArduinoCore library and extend these afterwards by adding all the include directories.
3.3 The Arduino Application
In the final application all libraries and the Arduino program come together to form the final application. Create a new project, but this time select AVR Cross Target Application. Again, you have to select the build configurations you want to keep and configure the MCU.
When it comes to the build configurations, you have to add the symbols and include paths you know already from the ArduinoCore and ArduinoLibrary. In addition, you have to specify the libraries in the project Properties -> C/C++ General -> Paths and Symbols section in the Libraries tab. Don’t use absolute paths here, but simply the names of the libraries, e.g., ArduinoLibrary, ArduinoCore, m. The order of the libraries is of importance. Specify a library A that is used by another library B after the library B. The library m (aka libm) might be required if you use mathematical functions. The Arduino SDK adds it always to the linker command. In addition, you have to specify the library paths in the Properties -> C/C++ Build -> Settings section. Here you have to adjust the Tool Settings of the AVR C++ Linker in the subsection Libraries. You can and should use paths relative to the workspace to simplify portability.
You should also configure the AVRDude in the project properties. Here, you have to select the Programmer that you have configured earlier in the global preferences and tune the options if you want to.
When working with multiple build configurations, you have to keep an eye on the AVR settings, especially the MCU type and frequency.