Giter VIP home page Giter VIP logo

arduino-cmake's Introduction

Arduino CMake

Arduino is a great development platform, which is easy to use. It has everything a beginner should need. The Arduino IDE simplifies a lot of things for the standard user, but if you are a professional programmer the IDE can feel simplistic and restrictive.

One major drawback of the Arduino IDE is that you cannot do anything without it, which for me is a complete buzz kill. Thats why I created an alternative build system for the Arduino using CMake.

CMake is great corss-platform build system that works on practically any operating system. With it you are not constrained to a single build system. CMake lets you generated the build system that fits your needs, using the tools you like. It can generate any type of build system, from simple Makefiles, to complete projects for Eclipse, Visual Studio, XCode, etc.

The Arduino CMake build system integrates tightly with the Arduino SDK. I'm currently basing on version 0022 of the Arduino SDK.

So if you like to do things from the command line (using make), or to build you're firmware where you're in control, or if you would like to use an IDE such as Eclipse, KDevelop, XCode, CodeBlocks or something similar, then Arduino CMake is the system for you.

Features

  • Integrates with Arduino SDK
  • Supports all Arduino boards.
  • Supports Arduino type libraries
  • Automatic detection of Arduino libraries.
  • Generates firmware images.
  • Generates libraries.
  • Upload support.
  • Supports multiple build system types (Makefiles, Eclipse, KDevelop, CodeBlocks, XCode, etc).
  • Cross-platform: Windows, Linux, Mac
  • Extensible build system, thanks to CMake

Feedback

Arduino CMake is hosted on GitHUB and is availabe at:

https://github.com/queezythegreat/arduino-cmake

Did you find a bug or would like a specific feature, plase report it at:

https://github.com/queezythegreat/arduino-cmake/issues

If you would like to hack on this project, don't hesitate to fork it on GitHub. I will be glad to integrate you'r changes if you send me a Pull Request.

Requirements

Contributors

I would like to thank the follwoing people for contributing to Arduino CMake:

TODO

  • Sketch conversion (PDE files)
  • Test more complex configurations and error handling

Contents

  1. Getting Started
  2. Using Arduino CMake
    1. Creating firmware images
    2. Creating libraries
    3. Arduino Libraries
    4. Compiler and Linker Flags
  3. Linux Enviroment Setup
    1. Serial Namming
    2. `Serial Terminal`_
  4. Mac OS X Enviroment Setup
    1. Serial Namming
    2. `Serial Terminal`_
  5. Windows Enviroment Setup
    1. CMake Generators
    2. Serial Namming
    3. `Serial Terminal`_
  6. Eclipse Enviroment
  7. Troubleshooting
    1. undefined reference to `__cxa_pure_virtual'
    2. Arduino Mega 2560 image does not work
  8. Resources

Getting Started

The following instructions are for *nix type systems, specifically this is a Linux example.

In short you can get up and running using the follwoing commands:

mkdir build
cd build
cmake ..
make
make upload              # to upload all firmware images             [optional]
make wire_reader-serial  # to get a serial terminal to wire_serial   [optional]

For a more detailed explanation, please read on...

  1. Toolchain file

    In order to build firmware for the Arduino you have to specify a toolchain file to enable cross-compilation. There are two ways of specifying the file, either at the command line or from within the CMakeLists.txt configuration files. The bundled example uses the second approche like so:

    set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/toolchains/Arduino.cmake)
    

    Please note that this must be before the project(...) command.

    If you would like to specify it from the command line, heres how:

    cmake -DCMAKE_TOOLCHAIN_FILE=../path/to/toolchain/file.cmake PATH_TO_SOURCE_DIR
    
  2. Creating a build directory

    The second order of business is creating a build directory. CMake has a great feature called out-of-source builds, what this means is the building is done in a completely separate directory, than where the sources are. The benefits of this is you don't have any clutter in you source directory and you won't accidentally commit something in, that is auto-generated.

    So lets create that build directory:

    mkdir build
    cd build
    
  3. Creating the build system

    Now lets create the build system that will create our firmware:

    cmake ..
    

    To specify the build system type, use the -G option, for example:

    cmake -G"Eclipse CDT4 - Unix Makefiles" ..
    

    If you rather use a GUI, use:

    cmake-gui ..
    
  4. Building

    Next we will build everything:

    make
    
  5. Uploading

    Once everything built correctly we can upload. Depending on your Arduino you will have to update the serial port used for uploading the firmware. To change the port please edit the following variable in CMakeLists.txt:

    set(${FIRMWARE_NAME}_PORT /path/to/device)
    

    Ok lets do a upload of all firmware images:

    make upload
    
  6. Serial output

    If you have some serial output, you can launch a serial terminal from the build system. The command used for executing the serial terminal is user configurable by the following setting:

    set(${FIRMWARE_NAME}_SERIAL serial command goes here)
    

    In order to get access to the serial port use the following in your command:

    @INPUT_PORT@
    

    That constant will get replaced with the actual serial port used (see uploading). In the case of our example configuration we can get the serial terminal by executing the following:

    make wire_reader-serial
    

Using Arduino CMake

The first step in generating Arduino firmware is including the Arduino CMake module package. This easily done with:

find_package(Arduino)

To have a specific minimal version of the Arduino SDK, you can specify the version like so:

find_package(Arduino 22)

That will require an Arduino SDK version 0022 or newer. To ensure that the SDK is detected you can add the REQUIRED keyword:

find_package(Arduino 22 REQUIRED)

Creating firmware images

Once you have the Arduino CMake package loaded you can start defining firmware images.

To create Arduino firmware in CMake you use the generate_arduino_firmware command. This function only accepts a single argument, the target name. To configure the target you need to specify a list of variables of the following format before the command:

${TARGET_NAME}${OPTION_SUFFIX}

Where ${TARGET_NAME} is the name of you target and ${OPTIONS_SUFFIX} is one of the following option suffixes:

_SRCS           # Target source files
_HDRS           # Target Headers files (for project based build systems)
_SKETCHES       # Target sketch files
_LIBS           # Libraries to linked against target (sets up dependency tracking)
_BOARD          # Board name (such as uno, mega2560, ...)
_PORT           # Serial port, for upload and serial targets [OPTIONAL]
_SERIAL         # Serial command for serial target           [OPTIONAL]
_NO_AUTOLIBS    # Disables Arduino library detection (default On)
_AFLAGS         # Overide global avrdude flags for target

So to create a target (firmware image) called blink, composed of blink.h and blink.cpp source files for the Arduino Uno, you write the following:

set(blink_SRCS  blink.cpp)
set(blink_HDRS  blink.h)
set(blink_BOARD uno)

generate_arduino_firmware(blink)

Upload Firmware

To enable firmware upload functionality, you need to add the _PORT settings:

set(blink_PORT /dev/ttyUSB0)

Once defined there will be two target availabe for uploading, ${TARGET_NAME}-upload and a global upload target (which will depend on all other upload targets defined in the build):

  • blink-upload - will upload just the blink firmware
  • upload - upload all firmware images registered for uploading

Serial Termial

To enable serial terminal, add the _SERIAL setting (@INPUT_PORT@ will be replaced with the blink_PORT setting):

set(blink_PORT picocom @INPUT_PORT@ -b 9600 -l)

This will create a target named ${TARGET_NAME}-serial (in this example: blink-serial).

Creating libraries

Creating libraries is very similar to defining a firmware image, except we use the generate_arduino_library command. The syntax of the settings is the same except we have a different list of settings:

_SRCS           # Library Sources
_HDRS           # Library Headers
_LIBS           # Libraries to linked in (sets up dependency tracking)
_BOARD          # Board name (such as uno, mega2560, ...)
_NO_AUTOLIBS    # Disables Arduino library detection

Lets define a simple library called blink_lib, with two sources files for the Arduino Uno:

set(blink_lib_SRCS  blink_lib.cpp)
set(blink_lib_HDRS  blink_lib.h)
set(blink_lib_BOARD uno)

generate_arduino_firmware(blink_lib)

Once that library is defined we can use it in our other firmware images... Lets add blink_lib to the blink firmware:

set(blink_SRCS  blink.cpp)
set(blink_HDRS  blink.h)
set(blink_LIBS  blink_lib)
set(blink_BOARD uno)

generate_arduino_firmware(blink)

CMake has automatic dependency tracking, so when you build the blink target, blink_lib will automatically get build in the right order.

Arduino Libraries

Libraries are one of the more powerfull features which the Arduino offers to users. Instead of rewriting code, people bundle their code in libraries and share them with others. The structure of libraries is very simple, which makes them easy to create.

An Arduino library is any directory which contains a header named after the directory, simple. Any source files contained within that directory is part of the library. Here is a example of library a called ExampleLib:

ExampleLib/
  |-- ExampleLib.h
  |-- ExampleLib.cpp
  `-- OtherLibSource.cpp

Now because the power of Arduino lies within those user created libraries, support for them is built right into Arduino CMake. The Arduino SDK comes with a large number of default libraries, adding new libraries is simple.

To incorporate a library into your firmaware, you can do one of three things:

  1. Place the library next to the default Arduino libraries (located at ${ARDUINO_SDK}/libraries)

  2. Place the library next to the firmware configuration file (same directory as the CMakeLists.txt)

  3. Place the library in a seperate folder and tell Arduino CMake the path to that directory.

    To tell CMake where to search for libraries use the link_directories command. The comand has to be used before defining any firmware or libraries requiring those libraries.

    For example:

    link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libraries)
    link_directories(/home/username/arduino_libraries)
    

If a library contains nested sources, a special option must be defined to enable recursion. For example to enable recusion for the Arduino Wire library use:

set(Wire_RECURSE True)

The option name should be ${LIBRARY_NAME}_RECURSE, where in this case LIBRARY_NAME is equal to Wire.

Compiler and Linker Flags

The default compiler and linker flags should be fine for most projects. If you required specific compiler/linker flags, use the following options to change them:

  • ARDUINO_C_FLAGS - C compiler flags
  • ARDUINO_CXX_FLAGS - C++ compiler flags
  • ARDUINO_LINKER_FLAGS - Linker flags

Set these option either before the project() like so:

set(ARDUINO_C_FLAGS      "-ffunction-sections -fdata-sections")
set(ARDUINO_CXX_FLAGS    "${ARDUINO_C_FLAGS} -fno-exceptions")
set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections")
project(ArduinoExample C CXX)

or when configuring the project:

cmake -D"ARDUINO_C_FLAGS=-ffunction-sections -fdata-sections" ../path/to/sources/

Linux Enviroment Setup

Running the Arduino SDK on Linux is a little bit more involved, because not everything is bundled with the SDK. The AVR GCC toolchain is not distributed alongside the Arduino SDK, so it has to be installed seperately.

To get Arduino CMake up and running follow these steps:

  1. Install the following packages using your package manager:

    • gcc-avr - AVR GNU GCC compiler
    • binutils-avr - AVR binary tools
    • avr-libc - AVR C library
    • avrdude - Firmware uploader
  2. Install the Arduino SDK.

    Depending on your distribution, the Arduino SDK may or may not be available.

    If it is available please install it using your packages manager otherwise do:

    1. Download the Arduino SDK
    2. Extract it into /usr/share

    NOTE: Arduino version 0022 or newer is required!

  3. Install CMake:

    NOTE: CMake version 2.8 or newer is required!

Serial Naming

On Linux the Arduino serial device is named as follows (where X is the device number):

/dev/ttyUSBX
/dev/ttyACMX

Where /dev/ttyACMX is for the new Uno and Mega Arduino's, while /dev/ttyUSBX is for the old ones.

CMake configuration example:

set(${FIRMWARE_NAME}_PORT /dev/ttyUSB0)

Serial Terminal

On Linux a wide range on serial terminal are availabe. Here is a list of a couple:

  • minicom
  • picocom
  • gtkterm
  • screen

Mac OS X Enviroment Setup

The Arduino SDK, as on Windows, is self contained and has everything needed for building. To get started do the following:

  1. Install the Arduino SDK

    1. Download Arduino SDK
    2. Copy Arduino into Applications
    3. Install FTDIUSBSerialDrviver* (for FTDI USB Serial)
  2. Install CMake

    1. Download CMake

    2. Install cmake-*.pkg

      NOTE: Make sure to click on `Install Command Line Links`

Serial Naming

When specifying the serial port name on Mac OS X, use the following names (where XXX is a unique ID):

/dev/tty.usbmodemXXX
/dev/tty.usbserialXXX

Where tty.usbmodemXXX is for new Uno and Mega Arduinos, while tty.usbserialXXX are the older ones.

CMake configuration example:

set(${FIRMWARE_NAME}_PORT /dev/tty.usbmodem1d11)

Serial Terminal

On Mac the easiest way to get a Serial Terminal is to use the screen terminal emulator. To start a screen serial session:

screen /dev/tty.usbmodemXXX

Where /dev/tty.usbmodemXXX is the terminal device. To exit press C-a C-\.

CMake configuration example:

set(${FIRMWARE_NAME}_SERIAL screen @INPUT_PORT@)

Windows Enviroment Setup

On Windows the Arduino SDK is self contained and has everything needed for building. To setup the environment do the following:

  1. Place the Arduino SDK either

    • into Program Files, or
    • onto the System Path

    NOTE: Don't change the default Arduino SDK directory name, otherwise auto detection will no work properly!

  2. Add to the System Path: ${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin

  3. Install CMake 2.8

    NOTE: Make sure you check the option to add CMake to the System Path.

CMake Generators

Once installed, you can start using CMake the usual way, just make sure to chose either a MSYS Makefiles or Unix Makefiles type generator:

MSYS Makefiles              = Generates MSYS makefiles.
Unix Makefiles              = Generates standard UNIX makefiles.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
Eclipse CDT4 - Unix Makefiles
                            = Generates Eclipse CDT 4.0 project files.

If you want to use a MinGW Makefiles type generator, you must generate the build system the following way:

  1. Remove ${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin from the System Path

  2. Generate the build system using CMake with the following option set (either throug the GUI or from the command line):

    CMAKE_MAKE_PROGRAM=${ARDIUNO_SDK_PATH}/hardware/tools/avr/utils/bin/make.exe
    
  3. Then build the normal way

The reason for doing this is the MinGW generator cannot have the sh.exe binary on the System Path during generation, otherwise you get an error.

Serial Namming

When specifying the serial port name on Windows, use the following names:

com1 com2 ... comN

CMake configuration example:

set(${FIRMWARE_NAME}_PORT com3)

Serial Terminal

Putty is a great multi-protocol terminal, which supports SSH, Telnet, Serial, and many more... The latest development snapshot supports command line options for launching a serial terminal, for example:

putty -serial COM3 -sercfg 9600,8,n,1,X

CMake configuration example (assuming putty is on the System Path):

set(${FIRMWARE_NAME}_SERIAL putty -serial @INPUT_PORT@)

Putty - http://tartarus.org/~simon/putty-snapshots/x86/putty-installer.exe

Eclipse Enviroment

Eclipse is a great IDE which has a lot of functionality and is much more powerfull than the Arduino IDE. In order to use Eclipse you will need the following:

  1. Eclipse
  2. Eclipse CDT extension (for C/C++ development)

On most Linux distribution you can install Eclipse + CDT using your package manager, otherwise you can download the Eclipse IDE for C/C++ Developers bundle.

Once you have Eclipse, here is how to generate a project using CMake:

  1. Create a build directory that is next to your source directory, like this:

    build_directory/
    source_directory/
    
  2. Run CMake with the Eclipse CDT4 - Unix Makefiles generator, inside the build directory:

    cd build_directory/
    cmake -G"Eclipse CDT4 - Unix Makefiles" ../source_directory
    
  3. Open Eclipse and import the project from the build directory.

    1. File > Import
    2. Select Existing Project into Workspace, and click Next
    3. Select Browse, and select the build directoy.
    4. Select the project in the Projects: list
    5. Click Finish

Troubleshooting

The following section will outline some solutions to common problems that you may encounter.

undefined reference to `__cxa_pure_virtual'

When linking you'r firmware image you may encounter this error on some systems. An easy fix is to add the following to your firmware source code:

extern "C" void __cxa_pure_virtual(void);
void __cxa_pure_virtual(void) { while(1); }

The contents of the __cxa_pure_virtual function can be any error handling code; this function will be called whenever a pure virtual function is called.

Arduino Mega 2560 image does not work

If you are working on Linux, and have avr-gcc >= 4.5 you might have a unpatched version gcc which has the C++ constructor bug. This bug affects the Atmega2560 when using classes which causes the Arduino firmware to crash.

If you encounter this problem either downgrade avr-gcc to 4.3 or rebuild gcc with the following patch:

--- gcc-4.5.1.orig/gcc/config/avr/libgcc.S  2009-05-23 17:16:07 +1000
+++ gcc-4.5.1/gcc/config/avr/libgcc.S   2010-08-12 09:38:05 +1000
@@ -802,7 +802,9 @@
    mov_h   r31, r29
    mov_l   r30, r28
    out     __RAMPZ__, r20
+   push    r20
    XCALL   __tablejump_elpm__
+   pop r20
 .L__do_global_ctors_start:
    cpi r28, lo8(__ctors_start)
    cpc r29, r17
@@ -843,7 +845,9 @@
    mov_h   r31, r29
    mov_l   r30, r28
    out     __RAMPZ__, r20
+   push    r20
    XCALL   __tablejump_elpm__
+   pop r20
 .L__do_global_dtors_start:
    cpi r28, lo8(__dtors_end)
    cpc r29, r17

Resources

Here are some resources you might find usefull in getting started.

  1. CMake:
  1. Arduino:

arduino-cmake's People

Contributors

jgoppert avatar kernald avatar queezythegreat avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.