1.16.2013

Atmel Studio for Arduino-guys - Part1 (continued): precompile Arduino libraries


Hi, today we will talk about precompilation of Arduino libraries in Atmel Studio 6 and how to use precompiled libraries in your projects. You should create and cofigure new project, add required files, compile... and that's all! All steps was described in part 1. But I prepared for you quick action list which you could follow to create precompiled Arduino Servo library. When you will be familiar with steps, you could easily create projects for other libraries like Wire and SPI.
  1. Create new project: Ctrl+Shift+N or right click on solution -> Add -> New project..., select 'GCC C++ Static Library Project' and name it Arduino.Precompiled.Servo. Also in 'Solution:' drop down check that 'Add to solution' item selected.

  2. Remove files automatically added to project: select file Arduino.Precompiled.Servo.cpp in solution explorer and press Del or right click on file and select Remove. If asked, press "Delete" button to delete file permanently.

  3. Add required files to project - in our case add as links 2 files Servo.cpp and Servo.h from (SolutionDir)\arduino-1.0.3\libraries\Servo.

  4. Configure project - Build tab: press right click on project, select Properties, goto Build tab. Set "Artifact Name" to libarduinoservo for all build modes.

  5. Configure project - Build events: add post build event to copy resulting library to external folder. It is optional step, but sometimes useful...
    xcopy "$(OutputDirectory)\$(OutputFileName)$(OutputFileExtension)" "$(SolutionDir)$(SolutionName).$(Configuration)\" /f /y
    

  6. Configure project - Toolchain - AVR\GNU C Compiler: as we have only cpp files in our project, we could skip configuration of AVR\GNU C Compiler.

  7. Configure project - Toolchain - AVR\GNU C++ Compiler - Symbols: (both build modes)
    1. F_CPU=16000000L
    2. ARDUINO=103
    3. USB_VID=null
    4. USB_PID=null
    5. __AVR_LIBC_DEPRECATED_ENABLE__

  8. Configure project - Toolchain - AVR\GNU C++ Compiler - Directories: (both build modes)
    1. ../../../arduino-1.0.3/hardware/arduino/variants/mega
    2. ../../../arduino-1.0.3/hardware/arduino/cores/arduino

  9. Configure project - Toolchain - AVR\GNU C++ Compiler - Optimization:
    1. Release build mode: in Other flags textbox add text '-fdata-sections', and check Prepare functions for garbage collection
    2. Debug build mode: no changes

  10. Configure project - Toolchain - AVR\GNU C++ Compiler - Miscellaneous: in Other flags textbox add text '-fno-exceptions' in both build modes.

  11. Configure project - Toolchain - AVR\GNU Linker - Libraries: in this project we can skip it, but usually you should add name of used libraries to 'Libraries' section and path to folder where libraries located to 'Library search path' section. Name of the library should be added without 'lib' prefix like: arduinocore and not libarduinocore. Also do that in both build modes, or you could use different paths\libraries for different build modes.

  12. Configure project - Toolchain - AVR\GNU Linker - Optimization:
    1. Release build mode: check 'Garbage collect unused sections' and 'Relax Branches'
    2. Debug build modes: skip

  13. Also, sometimes you create projects that have dependencies on libraries produced by other project in same solution. In such case you should correctly setup dependencies to prevent situations when dependent project building before depending. To do this right click on project, select 'Project Dependencies...' and check required project(s), so Atmel Studio will have an ability to calculate correct build order.
You are almost done, just build and check existence of libarduinoservo.a in Arduino.Precompiled.Release folder (or in Arduino.Precompiled.Debug folder, depending on what build mode you used). That's it... You created precompiled Arduino Servo library!

Video below provides quick demo about how to use precompiled Arduino Wire library in Atmel Studio 6:

1.07.2013

Atmel Studio for Arduino-guys - Part1: precompile Arduino core

Introduction


Hello everybody!

I'm back to my blog with several interesting articles. Now I'm working on telepresence robot, actually I'm using it from 04/12 and doing improvements all the time. Well.. long story short - my mother survived a stroke and now as a reault she has troubles with health, so I need an ability to stay at home, but I'm working at Betsson Tech in Kiev and it is nearly 400km from home. I love, yeah.. really love, my job so after discussion with management I had an approval to work remotely from home (thank you very much guys!).

It is cool, but new trouble arised - I need an ability to attend daily standups, plannings etc in Betsson Tech in Kiev. That is how idea to create telepresence robot arised. I'll write about the robot with some video and description of social aspects of using such a telebot in one of the future articles.

And today I want to start serie of articles about using Atmel Studio 6 with Arduino Mega 2560 development board. The Plan is to write about:

Part 1. Common project configuration + precompilation of Arduino Core and some Libraries
Part 2. freeRTOS for Arduino
Part 3. Google Protocol Buffers for Arduino + STL
Part 4. NanoPB for Arduino

So, lets start.

Common project configuration + precompilation of Arduino Core


First of all you need to download and install Atmel Studio 6. Then create a solution named Arduino.Precompiled (File -> New project... -> Atmel studio solution -> Blank Solution) and one static library named Arduino.Precompiled.Core (Right click on solution in Solution Explorer -> Add -> New project):

Create new project
Create new project

Then you will be asked to select your device. I'm using Arduino Mega 2560 board with MCU ATmega2560:

Select device
Select device
Press OK and now you have created your first project for AVR MCU in Atmega Studio! Now, lets add Arduino core files. To do this you need to download and unpack Arduino Software package (press on link for Windows). I unzipped package at the same level where Arduino.Precompiled folder located. Now go to Solution Explorer, right click on project and select Add -> Existing Item.. Go to the folder where all core files located: <arduino>\hardware\arduino\cores\arduino\ (see image below):

Add core files
Add core files
Select all files (Ctrl+A) and from drop down menu select Add As Link. When doing so you will add all selected files to your project as links, without physically copying them to project folder as Add does. Now lets do some configuration to our project. Need to say that configuration options I took from logs from Arduino IDE. So, right click on project -> Properties:

Set library name
Set library name
On Build tab you could set file name of your library, I named it libarduinocore. Please don't forget to do this for all configurations. Also, seems like Atmel Studio have some bug with saving properties for all configuration, so please recheck that name was really changed for both configuration by selecting Release and then Debug from drop down and checking actual Artifact Name.

Now go to Build Events tab:

Setting post-build event
Setting post-build event
I configured copy of resulting static library to Arduino.Precompiled.Release or Arduino.Precompiled.Debug folders located in solution folder, depending on build mode. Just to separate concerns...

Now we are ready to configure our Toolchain. Go to Toolchain tab, and select Symbols item for C or C++ compiler:

Configure toolchain: symbols
Configure toolchain: symbols
I configured both C\C++ for all configurations, all symbols I took from Arduino IDE logs:
  1. F_CPU - frequency of MCU you use. In case of Arduino Mega 2560 it is 16MHz or 16,000,000 Hz.
  2. ARDUINO is for version of Arduino framework, as you can see I use 1.0.3. Used for examle in Firmata library. But in our case it is optional and you can skip this definition at all.
  3. USB_VID and USB_PID is for vendor ID and peripheral ID, we are not using it. You can search for actual values in USBCore.cpp.
  4. __AVR_LIBC_DEPRECATED_ENABLE__ - use this definition to prevent compilation errors with Arduino libraries. Sorry, had no time to dig into it...
Next configure include directories (all configurations too):

Configure toolchain: directories
Configure toolchain: directories
In case you use another board, not Mega 2560, choose appropriate subfolder in variants folder.
Now we are ready to configure optimization section for Debug and Release modes separately:

Configure toolchain: optimizations
Configure toolchain: optimizations
And finally in Miscellaneous section add -fno-exceptions option:

Configure toolchain: miscellaneous
Configure toolchain: miscellaneous

With compillers we done, and now we should configure linker. Only in Release mode do next:

Configure toolchain: linker
Configure toolchain: linker
It looks like long and, may be, complicated, but after 2-3 projects you will do this configuration in 2-3 minutes. Description of all compiler and linker options you can find on official GCC site. Also, for AVR specific things you could visit AVR Libc site.

So, we are nearly done. Just remove unneccessary file that Atmel Studio created automagically:

Remove unneccessary file
Remove unneccessary file
When asked, press 'Delete' to permanently delete this file from your disk. Now you can try to compile... If you will see that output file is still named not like libarduinocore.a you can try next:
  1. Right click on project and choose Unload Project
  2. Right click on project and choose Edit Arduino.Precompiled.Core.cppproj
  3. Change your project file as shown on the image below:
Change name of library in project file
Change name of library in project file
After you done, just right click again and choose Reload Project. Thats it, now you have precompiled arduino static library in your Arduino.Precompiled.Release and\or Debug folders:

Library in the folder
Library in the folder
And here is small video that show you how to create project with precompiled Arduino Core library in Atmel Studio 6:


And here is flushing and testing:



Do you noticed memory statistics in the log? It shows how much you program takes in Flash (Program Memory Usage) and in RAM (Data Memory Usage). So make sure that Data Memory Usage is not more than you board can handle. For Arduino Mega it is 8KB.

Also I'm using avrdude to flush program into board, here is contents of flush.cmd:
c:\Users\User1\Downloads\arduino-1.0.1\hardware\tools\avr\bin\avrdude.exe -CC:\Users\User1\Downloads\arduino-1.0.1\hardware\tools\avr\etc\avrdude.conf -p m2560 -c wiring -P COM4 -b 115200 -F -U flash:w:%1%:i
pause

That's all for today. Next article will be about precompiling Arduino Libraries.