├── .gitignore ├── CMakeLists.txt ├── README.rst ├── cmake ├── ArduinoToolchain.cmake └── Platform │ └── Arduino.cmake ├── configure ├── configure.bat └── example ├── Blink ├── Blink.ino └── config.h ├── CMakeLists.txt ├── blink.cpp ├── blink_lib.cpp └── blink_lib.h /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # Author: QueezyTheGreat # 3 | # Date: 26.04.2011 # 4 | # # 5 | # Description: Arduino CMake example # 6 | # # 7 | #=============================================================================# 8 | set(CMAKE_TOOLCHAIN_FILE cmake/ArduinoToolchain.cmake) # Arduino Toolchain 9 | 10 | 11 | cmake_minimum_required(VERSION 2.8) 12 | #====================================================================# 13 | # Setup Project # 14 | #====================================================================# 15 | project(ArduinoExample C CXX) 16 | 17 | print_board_list() 18 | print_programmer_list() 19 | 20 | add_subdirectory(example) #add the example directory into build 21 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============= 2 | Arduino CMake 3 | ============= 4 | 5 | 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. 6 | 7 | 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. 8 | 9 | CMake is great cross-platform build system that works on practically any operating system. With it you are not constrained to a single build system. CMake lets you generate 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. 10 | 11 | The **Arduino CMake** build system integrates tightly with the *Arduino SDK*. 12 | 13 | *Arduino SDK* version **0.19** or higher is required. 14 | 15 | So if you like to do things from the command line (using make), or to build your 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. 16 | 17 | Features 18 | -------- 19 | 20 | * Integrates with *Arduino SDK* 21 | * Supports all Arduino boards. 22 | * Supports Arduino type libraries 23 | * Automatic detection of Arduino libraries. 24 | * Generates firmware images. 25 | * Generates libraries. 26 | * Sketch support. 27 | * Upload support. 28 | * Hardware Platform support. 29 | * Programmer support (with bootloader upload). 30 | * Supports multiple build system types (Makefiles, Eclipse, KDevelop, CodeBlocks, XCode, etc). 31 | * Cross-platform: Windows, Linux, Mac 32 | * Extensible build system, thanks to CMake 33 | 34 | 35 | Feedback 36 | -------- 37 | 38 | **Arduino CMake** is hosted on GitHub and is available at: 39 | 40 | https://github.com/queezythegreat/arduino-cmake 41 | 42 | Did you find a bug or would like a specific feature, please report it at: 43 | 44 | https://github.com/queezythegreat/arduino-cmake/issues 45 | 46 | If you would like to hack on this project, don't hesitate to fork it on GitHub. 47 | I will be glad to integrate your changes if you send me a ``Pull Request``. 48 | 49 | 50 | Requirements 51 | ------------ 52 | 53 | * Base requirements: 54 | 55 | - ``CMake`` - http://www.cmake.org/cmake/resources/software.html 56 | - ``Arduino SDK`` - http://www.arduino.cc/en/Main/Software 57 | 58 | * Linux requirements: 59 | 60 | - ``gcc-avr`` - AVR GNU GCC compiler 61 | - ``binutils-avr`` - AVR binary tools 62 | - ``avr-libc`` - AVR C library 63 | - ``avrdude`` - Firmware uploader 64 | 65 | 66 | Contributors 67 | ------------ 68 | 69 | I would like to thank the following people for contributing to **Arduino CMake**: 70 | 71 | * Marc Plano-Lesay (`Kernald`_) 72 | * James Goppert (`jgoppert`_) 73 | * Matt Tyler (`matt-tyler`_) 74 | * Andrew Stromme (`astromme`_) 75 | * `johnyb`_ 76 | * `arunh`_ 77 | * Sebastian Herp (`sebastianherp`_) 78 | * Michael Daffin (`james147`_) 79 | * Pavel Ilin (`PIlin`_) 80 | * Igor Mikolic-Torreira (`igormiktor`_) 81 | * Claudio Henrique Fortes Felix (`chffelix`_) 82 | * Alexandre Tuleu (`atuleu`_) 83 | * `getSurreal`_ 84 | * Sebastian Zaffarano (`szaffarano`_) 85 | * `cheshirekow`_ 86 | * Logan Engstrom (`meadowstream`_) 87 | * Francisco Ramírez (`franramirez688`_) 88 | * Brendan Shillingford (`bshillingford`_) 89 | * Mike Purvis (`mikepurvis`_) 90 | * Steffen Hanikel (`hanikesn`_) 91 | 92 | .. _Kernald: https://github.com/Kernald 93 | .. _jgoppert: https://github.com/jgoppert 94 | .. _matt-tyler: https://github.com/matt-tyler 95 | .. _astromme: https://github.com/astromme 96 | .. _johnyb: https://github.com/johnyb 97 | .. _arunh: https://github.com/arunh 98 | .. _sebastianherp: https://github.com/sebastianherp 99 | .. _james147: https://github.com/james147 100 | .. _PIlin: https://github.com/PIlin 101 | .. _igormiktor: https://github.com/igormiktor 102 | .. _chffelix: https://github.com/chffelix 103 | .. _atuleu: https://github.com/atuleu 104 | .. _getSurreal: https://github.com/getSurreal 105 | .. _szaffarano: https://github.com/szaffarano 106 | .. _cheshirekow: https://github.com/cheshirekow 107 | .. _meadowstream: https://github.com/meadowstream 108 | .. _franramirez688: https://github.com/franramirez688 109 | .. _bshillingford: https://github.com/bshillingford 110 | .. _mikepurvis: https://github.com/mikepurvis 111 | .. _hanikesn: https://github.com/hanikesn 112 | 113 | License 114 | ------- 115 | This Source Code Form is subject to the terms of the Mozilla Public 116 | License, v. 2.0. If a copy of the MPL was not distributed with this file, 117 | You can obtain one at http://mozilla.org/MPL/2.0/. 118 | 119 | TODO 120 | ---- 121 | 122 | * Test more complex configurations and error handling 123 | 124 | Contents 125 | -------- 126 | 127 | 1. `Getting Started`_ 128 | 2. `Using Arduino CMake`_ 129 | 130 | 1. `Creating firmware images`_ 131 | 2. `Creating libraries`_ 132 | 3. `Arduino Sketches`_ 133 | 4. `Arduino Libraries`_ 134 | 5. `Arduino Library Examples`_ 135 | 6. `Compiler and Linker Flags`_ 136 | 7. `Programmers`_ 137 | 8. `Pure AVR Development`_ 138 | 9. `Advanced Options`_ 139 | 10. `Miscellaneous Functions`_ 140 | 11. `Bundling Arduino CMake`_ 141 | 142 | 3. `Linux Environment`_ 143 | 144 | 1. `Linux Serial Naming`_ 145 | 2. `Linux Serial Terminals`_ 146 | 147 | 4. `Mac OS X Environment`_ 148 | 149 | 1. `Mac Serial Naming`_ 150 | 2. `Mac Serial Terminals`_ 151 | 152 | 5. `Windows Environment`_ 153 | 154 | 1. `CMake Generators`_ 155 | 2. `Windows Serial Naming`_ 156 | 3. `Windows Serial Terminals`_ 157 | 158 | 6. `Eclipse Environment`_ 159 | 7. `Troubleshooting`_ 160 | 161 | 1. `undefined reference to `__cxa_pure_virtual'`_ 162 | 2. `Arduino Mega 2560 image does not work`_ 163 | 3. `Library not detected automatically`_ 164 | 4. `error: attempt to use poisoned "SIG_USART0_RECV"`_ 165 | 166 | 8. `Resources`_ 167 | 168 | 169 | 170 | 171 | 172 | 173 | Getting Started 174 | --------------- 175 | 176 | 177 | The following instructions are for **\*nix** type systems, specifically this is a Linux example. 178 | 179 | In short you can get up and running using the following commands:: 180 | 181 | mkdir build 182 | cd build 183 | cmake .. 184 | make 185 | make upload # to upload all firmware images [optional] 186 | make blink-serial # to get a serial terminal to wire_serial [optional] 187 | 188 | For a more detailed explanation, please read on... 189 | 190 | 1. Toolchain file 191 | 192 | 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 approach like so:: 193 | 194 | set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake) 195 | 196 | Please note that this must be before the ``project(...)`` command. 197 | 198 | If you would like to specify it from the command line, heres how:: 199 | 200 | cmake -DCMAKE_TOOLCHAIN_FILE=../path/to/toolchain/file.cmake PATH_TO_SOURCE_DIR 201 | 202 | 2. Creating a build directory 203 | 204 | 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 from where the sources are. The benefit of this is you don't have any clutter in you source directory and you won't accidentally commit something that is auto-generated. 205 | 206 | So let's create that build directory:: 207 | 208 | mkdir build 209 | cd build 210 | 211 | 3. Creating the build system 212 | 213 | Now let's create the build system that will create our firmware:: 214 | 215 | cmake .. 216 | 217 | To specify the build system type, use the ``-G`` option, for example:: 218 | 219 | cmake -G"Eclipse CDT4 - Unix Makefiles" .. 220 | 221 | If you rather use a GUI, use:: 222 | 223 | cmake-gui .. 224 | 225 | 4. Building 226 | 227 | Next we will build everything:: 228 | 229 | make 230 | 231 | 5. Uploading 232 | 233 | 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*:: 234 | 235 | set(${FIRMWARE_NAME}_PORT /path/to/device) 236 | 237 | Ok lets do a upload of all firmware images:: 238 | 239 | make upload 240 | 241 | If you have an upload sync error then try resetting/ power cycling the board before starting the upload process. 242 | 243 | 6. Serial output 244 | 245 | 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:: 246 | 247 | set(${FIRMWARE_NAME}_SERIAL serial command goes here) 248 | 249 | In order to get access to the serial port use the following in your command:: 250 | 251 | @SERIAL_PORT@ 252 | 253 | 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:: 254 | 255 | make blink-serial 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | Using Arduino CMake 267 | ------------------- 268 | 269 | In order to use **Arduino CMake** just include the toolchain file, everything will get set up for building. You can set the toolchain 270 | in `CMakeList.txt` like so:: 271 | 272 | set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake) 273 | 274 | Please note that this must be before the ``project(...)`` command. 275 | 276 | You can also specify it at build configuration time:: 277 | 278 | cmake -DCMAKE_TOOLCHAIN_FILE=../path/to/toolchain/file.cmake PATH_TO_SOURCE_DIR 279 | 280 | 281 | Creating firmware images 282 | ~~~~~~~~~~~~~~~~~~~~~~~~ 283 | 284 | Once you have the **Arduino CMake** loaded you can start defining firmware images. 285 | 286 | To create Arduino firmware in CMake you use the ``generate_arduino_firmware`` command. The full syntax of the command is:: 287 | 288 | generate_arduino_firmware(target_name 289 | [BOARD board_id] 290 | [SKETCH sketch_path | SRCS src1 src2 ... srcN] 291 | [HDRS hdr1 hdr2 ... hdrN] 292 | [LIBS lib1 lib2 ... libN] 293 | [PORT port] 294 | [SERIAL serial_cmd] 295 | [PROGRAMMER programmer_id] 296 | [AFLAGS flags] 297 | [NO_AUTOLIBS]) 298 | 299 | 300 | The options are: 301 | 302 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 303 | | **Name** | **Description** | **Required** | 304 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 305 | | **BOARD** | Board ID *(such as uno, mega2560, ...)* | **REQUIRED** | 306 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 307 | | **SKETCH** | Sketch path (see `Arduino Sketches`_) | **SKETCH or SRCS are REQUIRED** | 308 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 309 | | **SRCS** | Source files | **SKETCH or SRCS are REQUIRED** | 310 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 311 | | **HDRS** | Headers files *(for project based build systems)* | | 312 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 313 | | **LIBS** | Libraries to link (see `Creating libraries`_) | | 314 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 315 | | **PORT** | Serial port, for upload and serial targets (see `Upload Firmware`_) | | 316 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 317 | | **SERIAL** | Serial command for serial target (see `Serial Terminal`_) | | 318 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 319 | | **PROGRAMMER** | Programmer ID, enables programmer burning (see `Programmers`_). | | 320 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 321 | | **ARDLIBS** | Manual list of Arduino type libraries, common use case is when the | | 322 | | | library header name does not match the librarie's directory name. | | 323 | | | **ADVANCED OPTION!** Can be used in conjuction with **NO_AUTOLIBS**. | | 324 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 325 | | **AFLAGS** | avrdude flags for target | | 326 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 327 | | **NO_AUTOLIBS** | Disable Arduino library detection *(default On)* | | 328 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 329 | | **MANUAL** | Disable Arduino Core (enables pure AVR development) | | 330 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 331 | 332 | You can specify the options in two ways, either as the command arguments or as variables. When specifying the options as variables they must be named:: 333 | 334 | ${TARGET_NAME}_${OPTION_NAME} 335 | 336 | Where **${TARGET_NAME}** is the name of you target and **${OPTION_NAME}** is the name of the option. 337 | 338 | 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:: 339 | 340 | set(blink_SRCS blink.cpp) 341 | set(blink_HDRS blink.h) 342 | set(blink_BOARD uno) 343 | 344 | generate_arduino_firmware(blink) 345 | 346 | The previous example can be rewritten as:: 347 | 348 | generate_arduino_firmware(blink 349 | SRCS blink.cpp 350 | HDRS blink.h 351 | BOARD uno) 352 | 353 | Upload Firmware 354 | _______________ 355 | 356 | To enable firmware upload functionality, you need to add the ``PORT`` option:: 357 | 358 | set(blink_SRCS blink.cpp) 359 | set(blink_HDRS blink.h) 360 | set(blink_PORT /dev/ttyUSB0) 361 | set(blink_BOARD uno) 362 | 363 | generate_arduino_firmware(blink) 364 | 365 | Or:: 366 | 367 | generate_arduino_firmware(blink 368 | SRCS blink.cpp 369 | HDRS blink.h 370 | PORT /dev/ttyUSB0 371 | BOARD uno) 372 | 373 | Once defined there will be two targets available for uploading, ``${TARGET_NAME}-upload`` and a global ``upload`` target (which will depend on all other upload targets defined in the build): 374 | 375 | * ``blink-upload`` - will upload just the ``blink`` firmware 376 | * ``upload`` - upload all firmware images registered for uploading 377 | 378 | Serial Terminal 379 | _______________ 380 | To enable serial terminal, use the ``SERIAL`` option (``@SERIAL_PORT@`` will be replaced with the ``PORT`` option):: 381 | 382 | set(blink_SRCS blink.cpp) 383 | set(blink_HDRS blink.h) 384 | set(blink_PORT /dev/ttyUSB0) 385 | set(blink_SERIAL picocom @SERIAL_PORT@ -b 9600 -l) 386 | set(blink_BOARD uno) 387 | 388 | generate_arduino_firmware(blink) 389 | 390 | Alternatively:: 391 | 392 | generate_arduino_firmware(blink 393 | SRCS blink.cpp 394 | HDRS blink.h 395 | PORT /dev/ttyUSB0 396 | SERIAL picocom @SERIAL_PORT@ -b 9600 -l 397 | BOARD uno) 398 | 399 | This will create a target named ``${TARGET_NAME}-serial`` (in this example: blink-serial). 400 | 401 | 402 | 403 | 404 | Creating libraries 405 | ~~~~~~~~~~~~~~~~~~ 406 | 407 | Creating libraries is very similar to defining a firmware image, except we use the ``generate_arduino_library`` command. This command creates static libraries, and are not to be confused with `Arduino Libraries`_. The full command syntax:: 408 | 409 | generate_arduino_library(name 410 | [BOARD board_id] 411 | [SRCS src1 src2 ... srcN] 412 | [HDRS hdr1 hdr2 ... hdrN] 413 | [LIBS lib1 lib2 ... libN] 414 | [NO_AUTOLIBS]) 415 | 416 | The options are: 417 | 418 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 419 | | **Name** | **Description** | **Required** | 420 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 421 | | **BOARD** | Board ID *(such as uno, mega2560, ...)* | **REQUIRED** | 422 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 423 | | **SRCS** | Source files | **REQUIRED** | 424 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 425 | | **HDRS** | Headers files *(for project based build systems)* | | 426 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 427 | | **LIBS** | Libraries to link *(sets up dependency tracking)* | | 428 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 429 | | **NO_AUTOLIBS** | Disable Arduino library detection *(default On)* | | 430 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 431 | | **MANUAL** | Disable Arduino Core (enables pure AVR development) | | 432 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 433 | 434 | You can specify the options in two ways, either as the command arguments or as variables. When specifying the options as variables they must be named:: 435 | 436 | ${TARGET_NAME}_${OPTION_NAME} 437 | 438 | Where **${TARGET_NAME}** is the name of you target and **${OPTION_NAME}** is the name of the option. 439 | 440 | Let's define a simple library called ``blink_lib`` with two sources files for the *Arduino Uno*:: 441 | 442 | set(blink_lib_SRCS blink_lib.cpp) 443 | set(blink_lib_HDRS blink_lib.h) 444 | set(blink_lib_BOARD uno) 445 | 446 | generate_arduino_library(blink_lib) 447 | 448 | The other way of defining the same thing is:: 449 | 450 | generate_arduino_library(blink_lib 451 | SRCS blink_lib.cpp 452 | HDRS blink_lib.h 453 | BOARD uno) 454 | 455 | Once that library is defined we can use it in our other firmware images... Let's add ``blink_lib`` to the ``blink`` firmware:: 456 | 457 | set(blink_SRCS blink.cpp) 458 | set(blink_HDRS blink.h) 459 | set(blink_LIBS blink_lib) 460 | set(blink_BOARD uno) 461 | 462 | generate_arduino_firmware(blink) 463 | 464 | CMake has automatic dependency tracking, so when you build the ``blink`` target, ``blink_lib`` will automatically get built, in the right order. 465 | 466 | 467 | 468 | Arduino Sketches 469 | ~~~~~~~~~~~~~~~~ 470 | 471 | To build a Arduino sketch use the **SKETCH** option (see `Creating firmware images`_). For example:: 472 | 473 | set(blink_SKETCH ${ARDUINO_SDK_PATH}/examples/1.Basics/Blink) # Path to sketch directory 474 | set(blink_BOARD uno) 475 | 476 | generate_arduino_firmware(blink) 477 | 478 | This will build the **blink** example from the **Arduino SDK**. 479 | 480 | Note: When specifying the sketch directory path, arduino-cmake is expecting to find a sketch file named after the directory (with a extension of .pde or .ino). 481 | 482 | You can also specify the path to the main sketch file, then the parent directory of that sketch will be search for additional sketch files. 483 | 484 | Arduino Libraries 485 | ~~~~~~~~~~~~~~~~~ 486 | 487 | Libraries are one of the more powerful features which the Arduino offers to users. Instead of rewriting code, people bundle their code in libraries and share them with others. 488 | The structure of these libraries is very simple, which makes them easy to create. 489 | 490 | An Arduino library is **any directory which contains a header named after the directory**, simple. 491 | Any source files contained within that directory are part of the library. Here is a example of library a called ExampleLib:: 492 | 493 | ExampleLib/ 494 | |-- ExampleLib.h 495 | |-- ExampleLib.cpp 496 | `-- OtherLibSource.cpp 497 | 498 | 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 and adding new libraries is simple. 499 | 500 | To incorporate a library into your firmware, you can do one of three things: 501 | 502 | 1. Place the library next to the default Arduino libraries (located at **${ARDUINO_SDK}/libraries**) 503 | 2. Place the library next to the firmware configuration file (same directory as the **CMakeLists.txt**) 504 | 3. Place the library in a separate folder and tell **Arduino CMake** the path to that directory. 505 | 506 | To tell CMake where to search for libraries use the `link_directories` command. The command has to be used before defining any firmware or libraries requiring those libraries. 507 | 508 | For example:: 509 | 510 | link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libraries) 511 | link_directories(/home/username/arduino_libraries) 512 | 513 | 514 | If a library contains nested sources, a special option must be defined to enable recursion. For example to enable recursion for the Arduino Wire library use:: 515 | 516 | set(Wire_RECURSE True) 517 | 518 | The option name should be **${LIBRARY_NAME}_RECURSE**, where in this case **LIBRARY_NAME** is equal to *Wire*. 519 | 520 | 521 | Arduino Libraries are not to be confused with normal static libraries (for exmaple *system libraries* or libraries created using generate_arduino_library). The **LIBS** option only accepts static libraries, so do not list the Arduino Libraries in that option (as you will get an error). 522 | 523 | 524 | Arduino Library Examples 525 | ~~~~~~~~~~~~~~~~~~~~~~~~ 526 | 527 | Most Arduino libraries have examples bundled with them. If you would like to generate and upload some of those examples you can use the `generate_arduino_example` command. The syntax of the command is:: 528 | 529 | generate_arduino_example(target_name 530 | LIBRARY library_name 531 | EXAMPLE example_name 532 | [BOARD board_id] 533 | [PORT port] 534 | [SERIAL serial command] 535 | [PORGRAMMER programmer_id] 536 | [AFLAGS avrdude_flags]) 537 | 538 | The options are: 539 | 540 | 541 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 542 | | **Name** | **Description** | **Required** | 543 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 544 | | **LIBRARY** | Library name. | **REQUIRED** | 545 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 546 | | **EXAMPLE** | Example name. | **REQUIRED** | 547 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 548 | | **BOARD** | Board ID *(such as uno, mega2560, ...)* | **REQUIRED** | 549 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 550 | | **PORT** | Serial port, for upload and serial targets (see `Upload Firmware`_) | | 551 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 552 | | **SERIAL** | Serial command for serial target (see `Serial Terminal`_) | | 553 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 554 | | **PROGRAMMER** | Programmer ID, enables programmer burning (see `Programmers`_). | | 555 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 556 | | **AFLAGS** | avrdude flags for target | | 557 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 558 | 559 | To generate a target for the **master_writer** example from the **Wire** library for the **Uno**:: 560 | 561 | generate_arduino_example(wire_example 562 | LIBRARY Wire 563 | EXAMPLE master_writer 564 | BOARD uno 565 | PORT /dev/ttyUSB0) 566 | 567 | You can also rewrite the previous like so:: 568 | 569 | set(wire_example_LIBRARY Wire) 570 | set(wire_example_EXAMPLE master_writer) 571 | set(wire_example_BOARD uno) 572 | set(wire_example_PORT /dev/ttyUSB0) 573 | 574 | generate_arduino_example(wire_example) 575 | 576 | The previous example will generate the following two target:: 577 | 578 | wire_example 579 | wire_example-upload 580 | 581 | Compiler and Linker Flags 582 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 583 | 584 | 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: 585 | 586 | +--------------------------+----------------------+ 587 | | **Name** | **Description** | 588 | +--------------------------+----------------------+ 589 | | **ARDUINO_C_FLAGS** | C compiler flags | 590 | +--------------------------+----------------------+ 591 | | **ARDUINO_CXX_FLAGS** | C++ compiler flags | 592 | +--------------------------+----------------------+ 593 | | **ARDUINO_LINKER_FLAGS** | Linker flags | 594 | +--------------------------+----------------------+ 595 | 596 | 597 | Set these option either before the `project()` like so:: 598 | 599 | set(ARDUINO_C_FLAGS "-ffunction-sections -fdata-sections") 600 | set(ARDUINO_CXX_FLAGS "${ARDUINO_C_FLAGS} -fno-exceptions") 601 | set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections") 602 | 603 | project(ArduinoExample C CXX) 604 | 605 | or when configuring the project:: 606 | 607 | cmake -D"ARDUINO_C_FLAGS=-ffunction-sections -fdata-sections" ../path/to/sources/ 608 | 609 | 610 | Programmers 611 | ~~~~~~~~~~~ 612 | 613 | **Arduino CMake** fully supports programmers for burning firmware and bootloader images directly onto the Arduino. 614 | If you have a programmer that is supported by the *Arduino SDK*, everything should work out of the box. 615 | As of version 1.0 of the *Arduino SDK*, the following programmers are supported: 616 | 617 | +--------------------+---------------------+ 618 | | **Programmer ID** | **Description** | 619 | +--------------------+---------------------+ 620 | | **avrisp** | AVR ISP | 621 | +--------------------+---------------------+ 622 | | **avrispmkii** | AVRISP mkII | 623 | +--------------------+---------------------+ 624 | | **usbtinyisp** | USBtinyISP | 625 | +--------------------+---------------------+ 626 | | **parallel** | Parallel Programmer | 627 | +--------------------+---------------------+ 628 | | **arduinoisp** | Arduino as ISP | 629 | +--------------------+---------------------+ 630 | 631 | The programmers.txt file located in `${ARDUINO_SDK_PATH}/hardware/arduino/` lists all supported programmers by the *Arduino SDK*. 632 | 633 | In order to enable programmer support, you have to use the **PROGRAMMER** option (see `Creating firmware images`_):: 634 | 635 | set(${TARGET_NAME}_PROGRAMMER programmer_id) 636 | 637 | where `programmer_id` is the name of the programmer supported by the *Arduino SDK*. 638 | 639 | Once you have enabled programmer support, two new targets are available in the build system: 640 | 641 | * **${TARGET_NAME}-burn** - burns the firmware image via the programmer 642 | * **${TARGET_NAME}-burn-bootloader** - burns the original **Arduino bootloader** image via the programmer 643 | 644 | If you need to restore the original **Arduino bootloader** onto your Arduino, so that you can use the traditional way of uploading firmware images via the bootloader, use **${TARGET_NAME}-burn-bootloader** to restore it. 645 | 646 | 647 | Pure AVR Development 648 | ~~~~~~~~~~~~~~~~~~~~ 649 | 650 | For those developers who don't want any Arduino magic, but still want to utilize the hardware platform you are in luck. This section will outline the `generate_avr_firmware()` and `generate_avr_library()` commands, which enables 651 | you to compile sources for the given Arduino board. 652 | 653 | No Arduino Core or Arduino libraries will get generated, this is for manual compilation of sources. These commands are for people that know what they are doing, or have done pure AVR development. 654 | People starting out, or just familiar with Arduino should not use these commands. 655 | 656 | The `generate_avr_firmware()` command:: 657 | 658 | generate_avr_firmware(name 659 | [BOARD board_id] 660 | [SRCS src1 src2 ... srcN] 661 | [HDRS hdr1 hdr2 ... hdrN] 662 | [LIBS lib1 lib2 ... libN] 663 | [PORT port] 664 | [SERIAL serial_cmd] 665 | [PROGRAMMER programmer_id] 666 | [AFLAGS flags]) 667 | 668 | This will compile the sources for the specified Arduino board type. 669 | 670 | The options: 671 | 672 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 673 | | **Name** | **Description** | **Required** | 674 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 675 | | **BOARD** | Board ID *(such as uno, mega2560, ...)* | **REQUIRED** | 676 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 677 | | **SRCS** | Source files | **REQUIRED** | 678 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 679 | | **HDRS** | Headers files *(for project based build systems)* | | 680 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 681 | | **LIBS** | Libraries to link *(sets up dependency tracking)* | | 682 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 683 | | **BOARD** | Board ID *(such as uno, mega2560, ...)* | **REQUIRED** | 684 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 685 | | **PORT** | Serial port, for upload and serial targets (see `Upload Firmware`_) | | 686 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 687 | | **SERIAL** | Serial command for serial target (see `Serial Terminal`_) | | 688 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 689 | | **PROGRAMMER** | Programmer ID, enables programmer burning (see `Programmers`_). | | 690 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 691 | | **AFLAGS** | avrdude flags for target | | 692 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 693 | 694 | You can specify the options in two ways, either as the command arguments or as variables. When specifying the options as variables they must be named:: 695 | 696 | ${TARGET_NAME}_${OPTION_NAME} 697 | 698 | Where **${TARGET_NAME}** is the name of you target and **${OPTION_NAME}** is the name of the option. 699 | 700 | 701 | The `generate_avr_library()` command:: 702 | 703 | generate_avr_library(name 704 | [BOARD board_id] 705 | [SRCS src1 src2 ... srcN] 706 | [HDRS hdr1 hdr2 ... hdrN] 707 | [LIBS lib1 lib2 ... libN]) 708 | 709 | This will compile a static library for the specified Arduino board type. 710 | 711 | The options: 712 | 713 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 714 | | **Name** | **Description** | **Required** | 715 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 716 | | **BOARD** | Board ID *(such as uno, mega2560, ...)* | **REQUIRED** | 717 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 718 | | **SRCS** | Source files | **REQUIRED** | 719 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 720 | | **HDRS** | Headers files *(for project based build systems)* | | 721 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 722 | | **LIBS** | Libraries to link *(sets up dependency tracking)* | | 723 | +--------------------+----------------------------------------------------------------------+------------------------------------+ 724 | 725 | You can specify the options in two ways, either as the command arguments or as variables. When specifying the options as variables they must be named:: 726 | 727 | ${TARGET_NAME}_${OPTION_NAME} 728 | 729 | Where **${TARGET_NAME}** is the name of you target and **${OPTION_NAME}** is the name of the option. 730 | 731 | Advanced Options 732 | ~~~~~~~~~~~~~~~~ 733 | 734 | The following options control how **Arduino CMake** is configured: 735 | 736 | +---------------------------------+-----------------------------------------------------+ 737 | | **Name** | **Description** | 738 | +---------------------------------+-----------------------------------------------------+ 739 | | **ARDUINO_SDK_PATH** | Full path to the **Arduino SDK** | 740 | +---------------------------------+-----------------------------------------------------+ 741 | | **ARDUINO_AVRDUDE_PROGRAM** | Full path to `avrdude` programmer | 742 | +---------------------------------+-----------------------------------------------------+ 743 | | **ARDUINO_AVRDUDE_CONFIG_PATH** | Full path to `avrdude` configuration file | 744 | +---------------------------------+-----------------------------------------------------+ 745 | | **ARDUINO_DEFAULT_BOARD** | Default Arduino Board ID, when not specified. | 746 | +---------------------------------+-----------------------------------------------------+ 747 | | **ARDUINO_DEFAULT_PORT** | Default Arduino port, when not specified. | 748 | +---------------------------------+-----------------------------------------------------+ 749 | | **ARDUINO_DEFAULT_SERIAL** | Default Arduino Serial command, when not specified. | 750 | +---------------------------------+-----------------------------------------------------+ 751 | | **ARDUINO_DEFAULT_PROGRAMMER** | Default Arduino Programmer ID, when not specified. | 752 | +---------------------------------+-----------------------------------------------------+ 753 | 754 | To force a specific version of **Arduino SDK**, configure the project like so:: 755 | 756 | cmake -DARDUINO_SDK_PATH=/path/to/arduino_sdk ../path/to/sources 757 | 758 | Note: You must create a new build system if you change **ARDUINO_SDK_PATH**. 759 | 760 | 761 | When **Arduino CMake** is configured properly, these options are defined: 762 | 763 | +---------------------------------+-----------------------------------------------------+ 764 | | **Name** | **Description** | 765 | +---------------------------------+-----------------------------------------------------+ 766 | | **ARDUINO_FOUND** | Set to True when the **Arduino SDK** is detected | 767 | | | and configured. | 768 | +---------------------------------+-----------------------------------------------------+ 769 | | **ARDUINO_SDK_VERSION** | Full version of the **Arduino SDK** (ex: 1.0.0) | 770 | +---------------------------------+-----------------------------------------------------+ 771 | | **ARDUINO_SDK_VERSION_MAJOR** | Major version of the **Arduino SDK** (ex: 1) | 772 | +---------------------------------+-----------------------------------------------------+ 773 | | **ARDUINO_SDK_VERSION_MINOR** | Minor version of the **Arduino SDK** (ex: 0) | 774 | +---------------------------------+-----------------------------------------------------+ 775 | | **ARDUINO_SDK_VERSION_PATCH** | Patch version of the **Arduino SDK** (ex: 0) | 776 | +---------------------------------+-----------------------------------------------------+ 777 | 778 | 779 | During compilation, you can enable the following environment variables. 780 | 781 | +---------------------------------+-----------------------------------------------------+ 782 | | **Name** | **Description** | 783 | +---------------------------------+-----------------------------------------------------+ 784 | | **VERBOSE** | Enables verbose compilation, displays commands | 785 | | | being executed. (Non empty value) | 786 | +---------------------------------+-----------------------------------------------------+ 787 | | **VERBOSE_SIZE** | Enables full/verbose output from avr-size. | 788 | | | (Non empty value) | 789 | +---------------------------------+-----------------------------------------------------+ 790 | 791 | Miscellaneous Functions 792 | ~~~~~~~~~~~~~~~~~~~~~~~ 793 | 794 | This section will outlines some of the additional miscellaneous functions available to the user. 795 | 796 | * **print_board_list()**: 797 | 798 | Print list of detected Arduino Boards. 799 | * **print_programmer_list()**: 800 | 801 | Print list of detected Programmers. 802 | * **print_programmer_settings(PROGRAMMER)**: 803 | 804 | *PROGRAMMER* - programmer id 805 | 806 | Print the detected Programmer settings. 807 | * **print_board_settings(BOARD_ID)**: 808 | 809 | *BOARD_ID* - Board ID 810 | 811 | Print the detected Arduino board settings. 812 | * **register_hardware_platform(HARDWARE_PLATFORM_PATH)**: 813 | 814 | *HARDWARE_PLATFORM_PATH* - Hardware platform path 815 | 816 | Registers a ``Hardware Platform`` path. See: `Arduino Platforms PRE 1.5`_ and `Arduino Platforms 1.5`_. 817 | 818 | A Hardware Platform is a directory containing the following:: 819 | 820 | HARDWARE_PLATFORM_PATH/ 821 | |-- bootloaders/ 822 | |-- cores/ 823 | |-- variants/ 824 | |-- boards.txt 825 | `-- programmers.txt 826 | 827 | This enables you to register new types of hardware platforms such as the 828 | Sagnuino, without having to copy the files into your Arduino SDK. 829 | 830 | The ``board.txt`` describes the target boards and bootloaders. While 831 | ``programmers.txt`` the programmer defintions. 832 | 833 | A good example of a *Hardware Platform* is in the Arduino SDK: ``${ARDUINO_SDK_PATH}/hardware/arduino/`` 834 | 835 | 836 | .. _Arduino Platforms PRE 1.5: http://code.google.com/p/arduino/wiki/Platforms 837 | .. _Arduino Platforms 1.5: http://code.google.com/p/arduino/wiki/Platforms1 838 | Bundling Arduino CMake 839 | ~~~~~~~~~~~~~~~~~~~~~~ 840 | 841 | Using **Arduino CMake** in your own project is simple, you just need a single directory called **cmake**. Just copy that entire directory into you project and you are set. 842 | 843 | Copying the **cmake** directory, although simple is not the best solution. If you are using GIT for source code versioning, the best solution is using a submodule. The submodule gives you the power of updating to the latest version of **Arduino CMake** without any effort. To add a submodule do:: 844 | 845 | git submodule add git://github.com/queezythegreat/arduino-cmake.git arduino-cmake 846 | 847 | Then just set the CMAKE_TOOLCHAIN_FILE variable:: 848 | 849 | set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/arduino-cmake/cmake/ArduinoToolchain.cmake) 850 | 851 | For more information on GIT submodules please read: `GIT Book - Submodules`_ 852 | 853 | .. _GIT Book - Submodules: http://book.git-scm.com/5_submodules.html 854 | 855 | Linux Environment 856 | ----------------- 857 | 858 | 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. 859 | 860 | To get **Arduino CMake** up and running follow these steps: 861 | 862 | 1. Install the following packages using your package manager: 863 | 864 | * ``gcc-avr`` - AVR GNU GCC compiler 865 | * ``binutils-avr`` - AVR binary tools 866 | * ``avr-libc`` - AVR C library 867 | * ``avrdude`` - Firmware uploader 868 | 869 | 2. Install the *Arduino SDK*. 870 | 871 | Depending on your distribution, the *Arduino SDK* may or may not be available. 872 | 873 | If it is available please install it using your packages manager otherwise do: 874 | 875 | 1. Download the `Arduino SDK`_ 876 | 2. Extract it into ``/usr/share`` 877 | 878 | NOTE: Arduino version **0.19** or newer is required! 879 | 880 | 3. Install CMake: 881 | 882 | * Using the package manager or 883 | * Using the `CMake installer`_ 884 | 885 | NOTE: CMake version 2.8 or newer is required! 886 | 887 | 888 | 889 | Linux Serial Naming 890 | ~~~~~~~~~~~~~~~~~~~ 891 | 892 | On Linux the Arduino serial device is named as follows (where **X** is the device number):: 893 | 894 | /dev/ttyUSBX 895 | /dev/ttyACMX 896 | 897 | Where ``/dev/ttyACMX`` is for the new **Uno** and **Mega** Arduino's, while ``/dev/ttyUSBX`` is for the old ones. 898 | 899 | CMake configuration example:: 900 | 901 | set(${FIRMWARE_NAME}_PORT /dev/ttyUSB0) 902 | 903 | 904 | Linux Serial Terminals 905 | ~~~~~~~~~~~~~~~~~~~~~~ 906 | 907 | On Linux a wide range on serial terminal are availabe. Here is a list of a couple: 908 | 909 | * ``minicom`` 910 | * ``picocom`` 911 | * ``gtkterm`` 912 | * ``screen`` 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | Mac OS X Environment 925 | -------------------- 926 | 927 | The *Arduino SDK*, as on Windows, is self contained and has everything needed for building. To get started do the following: 928 | 929 | 1. Install the *Arduino SDK* 930 | 931 | 1. Download `Arduino SDK`_ 932 | 2. Copy ``Arduino`` into ``Applications`` 933 | 3. Install ``FTDIUSBSerialDrviver*`` (for FTDI USB Serial) 934 | 935 | 2. Install CMake 936 | 937 | 1. Download `CMake`_ 938 | 2. Install ``cmake-*.pkg`` 939 | 940 | NOTE: Make sure to click on **`Install Command Line Links`** 941 | 942 | Mac Serial Naming 943 | ~~~~~~~~~~~~~~~~~ 944 | 945 | When specifying the serial port name on Mac OS X, use the following names (where XXX is a unique ID):: 946 | 947 | /dev/tty.usbmodemXXX 948 | /dev/tty.usbserialXXX 949 | 950 | Where ``tty.usbmodemXXX`` is for new **Uno** and **Mega** Arduino's, while ``tty.usbserialXXX`` are the older ones. 951 | 952 | CMake configuration example:: 953 | 954 | set(${FIRMWARE_NAME}_PORT /dev/tty.usbmodem1d11) 955 | 956 | Mac Serial Terminals 957 | ~~~~~~~~~~~~~~~~~~~~ 958 | 959 | On Mac the easiest way to get a Serial Terminal is to use the ``screen`` terminal emulator. To start a ``screen`` serial session:: 960 | 961 | screen /dev/tty.usbmodemXXX 962 | 963 | Where ``/dev/tty.usbmodemXXX`` is the terminal device. To exit press ``C-a C-\``. 964 | 965 | CMake configuration example:: 966 | 967 | set(${FIRMWARE_NAME}_SERIAL screen @SERIAL_PORT@) 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | Windows Environment 980 | ------------------- 981 | 982 | On Windows the *Arduino SDK* is self contained and has everything needed for building. To setup the environment do the following: 983 | 984 | 1. Place the `Arduino SDK`_ either 985 | 986 | * into **Program Files**, or 987 | * onto the **System Path** 988 | 989 | NOTE: Don't change the default *Arduino SDK* directory name, otherwise auto detection will no work properly! 990 | 991 | 2. Add to the **System Path**: ``${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin`` 992 | 3. Install `CMake 2.8`_ 993 | 994 | NOTE: Make sure you check the option to add CMake to the **System Path**. 995 | 996 | 997 | CMake Generators 998 | ~~~~~~~~~~~~~~~~ 999 | 1000 | Once installed, you can start using CMake the usual way, just make sure to chose either a **MSYS Makefiles** or **Unix Makefiles** type generator:: 1001 | 1002 | MSYS Makefiles = Generates MSYS makefiles. 1003 | Unix Makefiles = Generates standard UNIX makefiles. 1004 | CodeBlocks - Unix Makefiles = Generates CodeBlocks project files. 1005 | Eclipse CDT4 - Unix Makefiles 1006 | = Generates Eclipse CDT 4.0 project files. 1007 | 1008 | If you want to use a **MinGW Makefiles** type generator, you must generate the build system the following way: 1009 | 1010 | 1. Remove ``${ARDUINO_SDK_PATH}/hardware/tools/avr/utils/bin`` from the **System Path** 1011 | 2. Generate the build system using CMake with the following option set (either through the GUI or from the command line):: 1012 | 1013 | CMAKE_MAKE_PROGRAM=${ARDIUNO_SDK_PATH}/hardware/tools/avr/utils/bin/make.exe 1014 | 1015 | 3. Then build the normal way 1016 | 1017 | 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. 1018 | 1019 | Windows Serial Naming 1020 | ~~~~~~~~~~~~~~~~~~~~~ 1021 | 1022 | When specifying the serial port name on Windows, use the following names:: 1023 | 1024 | com1 com2 ... comN 1025 | 1026 | CMake configuration example:: 1027 | 1028 | set(${FIRMWARE_NAME}_PORT com3) 1029 | 1030 | Windows Serial Terminals 1031 | ~~~~~~~~~~~~~~~~~~~~~~~~ 1032 | 1033 | 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:: 1034 | 1035 | putty -serial COM3 -sercfg 9600,8,n,1,X 1036 | 1037 | CMake configuration example (assuming putty is on the **System Path**):: 1038 | 1039 | set(${FIRMWARE_NAME}_SERIAL putty -serial @SERIAL_PORT@) 1040 | 1041 | Putty - http://tartarus.org/~simon/putty-snapshots/x86/putty-installer.exe 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | Eclipse Environment 1053 | ------------------- 1054 | 1055 | Eclipse is a great IDE which has a lot of functionality and is much more powerful than the *Arduino IDE*. In order to use Eclipse you will need the following: 1056 | 1057 | 1. Eclipse 1058 | 2. Eclipse CDT extension (for C/C++ development) 1059 | 1060 | 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. 1061 | 1062 | Once you have Eclipse, here is how to generate a project using CMake: 1063 | 1064 | 1. Create a build directory that is next to your source directory, like this:: 1065 | 1066 | build_directory/ 1067 | source_directory/ 1068 | 1069 | 2. Run CMake with the `Eclipse CDT4 - Unix Makefiles` generator, inside the build directory:: 1070 | 1071 | cd build_directory/ 1072 | cmake -G"Eclipse CDT4 - Unix Makefiles" ../source_directory 1073 | 1074 | 3. Open Eclipse and import the project from the build directory. 1075 | 1076 | 1. **File > Import** 1077 | 2. Select `Existing Project into Workspace`, and click **Next** 1078 | 3. Select *Browse*, and select the build directoy. 1079 | 4. Select the project in the **Projects:** list 1080 | 5. Click **Finish** 1081 | 1082 | 1083 | 1084 | .. _Eclipse IDE for C/C++ Developers: http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliossr2 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | Troubleshooting 1097 | --------------- 1098 | 1099 | The following section will outline some solutions to common problems that you may encounter. 1100 | 1101 | undefined reference to `__cxa_pure_virtual' 1102 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1103 | 1104 | 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:: 1105 | 1106 | extern "C" void __cxa_pure_virtual(void); 1107 | void __cxa_pure_virtual(void) { while(1); } 1108 | 1109 | 1110 | 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. 1111 | 1112 | * `What is the purpose of `cxa_pure_virtual``_ 1113 | 1114 | .. _What is the purpose of `cxa_pure_virtual`: http://stackoverflow.com/questions/920500/what-is-the-purpose-of-cxa-pure-virtual 1115 | 1116 | Arduino Mega 2560 image does not work 1117 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1118 | 1119 | 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. 1120 | 1121 | If you encounter this problem either downgrade ``avr-gcc`` to **4.3** or rebuild gcc with the following patch:: 1122 | 1123 | --- gcc-4.5.1.orig/gcc/config/avr/libgcc.S 2009-05-23 17:16:07 +1000 1124 | +++ gcc-4.5.1/gcc/config/avr/libgcc.S 2010-08-12 09:38:05 +1000 1125 | @@ -802,7 +802,9 @@ 1126 | mov_h r31, r29 1127 | mov_l r30, r28 1128 | out __RAMPZ__, r20 1129 | + push r20 1130 | XCALL __tablejump_elpm__ 1131 | + pop r20 1132 | .L__do_global_ctors_start: 1133 | cpi r28, lo8(__ctors_start) 1134 | cpc r29, r17 1135 | @@ -843,7 +845,9 @@ 1136 | mov_h r31, r29 1137 | mov_l r30, r28 1138 | out __RAMPZ__, r20 1139 | + push r20 1140 | XCALL __tablejump_elpm__ 1141 | + pop r20 1142 | .L__do_global_dtors_start: 1143 | cpi r28, lo8(__dtors_end) 1144 | cpc r29, r17 1145 | 1146 | * `AVR GCC Bug 45263 Report`_ 1147 | * `The global constructor bug in avr-gcc`_ 1148 | 1149 | .. _AVR GCC Bug 45263 Report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45263 1150 | .. _The global constructor bug in avr-gcc: http://andybrown.me.uk/ws/2010/10/24/the-major-global-constructor-bug-in-avr-gcc/ 1151 | 1152 | 1153 | 1154 | Library not detected automatically 1155 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1156 | 1157 | When a Arduino library does not get detected automatically, it usually means CMake cannot find it (obvious). 1158 | 1159 | One common reason why the library is not detected, is because the directory name of the library does not match the header. 1160 | If I'm including a library header like so:: 1161 | 1162 | #include "my_library.h" 1163 | 1164 | Based on this include, **Arduino CMake** is expecting to find a library that has a directory name **my_libray**. 1165 | If the directory name does not match the header, it won't be consider a Arduino Library (see `Arduino Libraries`_). 1166 | 1167 | 1168 | When a library being used is located in a non-standard location (not in the **Arduino SDK** or next to the firmware), then that directory must be registered. 1169 | To register a non-standard directory containing Arduino libraries, use the following:: 1170 | 1171 | link_directories(path_to_directory_containing_libraries) 1172 | 1173 | Remember to **use this command before defining the firmware**, which requires the library from that directory. 1174 | 1175 | 1176 | error: attempt to use poisoned "SIG_USART0_RECV" 1177 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1178 | 1179 | If you get the following error:: 1180 | 1181 | /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:91:41: error: attempt to use poisoned "SIG_USART0_RECV" 1182 | /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:101:15: error: attempt to use poisoned "SIG_USART0_RECV" 1183 | /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:132:15: error: attempt to use poisoned "SIG_USART1_RECV" 1184 | /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:145:15: error: attempt to use poisoned "SIG_USART2_RECV" 1185 | /usr/share/arduino/hardware/arduino/cores/arduino/HardwareSerial.cpp:158:15: error: attempt to use poisoned "SIG_USART3_RECV" 1186 | 1187 | You probably recently upgraded `avr-libc` to the latest version, which has deperecated the use of these symbols. There is a `Arduino Patch`_ which 1188 | fixes these error, you can read more about this bug here: `Arduino Bug ISSUE 955`_. 1189 | 1190 | .. _Arduino Bug ISSUE 955: http://code.google.com/p/arduino/issues/detail?id=955 1191 | .. _Arduino Patch: http://arduino.googlecode.com/issues/attachment?aid=9550004000&name=sig-patch.diff&token=R2RWB0LZXQi8OpPLsyAdnMATDNU%3A1351021269609 1192 | 1193 | Resources 1194 | --------- 1195 | 1196 | Here are some resources you might find useful in getting started. 1197 | 1198 | 1. CMake: 1199 | 1200 | * `Offical CMake Tutorial`_ 1201 | * `CMake Tutorial`_ 1202 | * `CMake Reference`_ 1203 | 1204 | .. _Offical CMake Tutorial: http://www.cmake.org/cmake/help/cmake_tutorial.html 1205 | .. _CMake Tutorial: http://mathnathan.com/2010/07/11/getting-started-with-cmake/ 1206 | .. _CMake Reference: http://www.cmake.org/cmake/help/cmake-2-8-docs.html 1207 | 1208 | 2. Arduino: 1209 | 1210 | * `Getting Started`_ - Introduction to Arduino 1211 | * `Playground`_ - User contributed documentation and help 1212 | * `Arduino Forums`_ - Official forums 1213 | * `Arduino Reference`_ - Official reference manual 1214 | 1215 | .. _Getting Started: http://www.arduino.cc/en/Guide/HomePage 1216 | .. _Playground: http://www.arduino.cc/playground/ 1217 | .. _Arduino Reference: http://www.arduino.cc/en/Reference/HomePage 1218 | .. _Arduino Forums: http://www.arduino.cc/forum/ 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | .. _CMake 2.8: http://www.cmake.org/cmake/resources/software.html 1228 | .. _CMake: http://www.cmake.org/cmake/resources/software.html 1229 | .. _CMake Installer: http://www.cmake.org/cmake/resources/software.html 1230 | .. _Arduino SDK: http://www.arduino.cc/en/Main/Software 1231 | 1232 | -------------------------------------------------------------------------------- /cmake/ArduinoToolchain.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # Author: Tomasz Bogdal (QueezyTheGreat) 3 | # Home: https://github.com/queezythegreat/arduino-cmake 4 | # 5 | # This Source Code Form is subject to the terms of the Mozilla Public 6 | # License, v. 2.0. If a copy of the MPL was not distributed with this file, 7 | # You can obtain one at http://mozilla.org/MPL/2.0/. 8 | #=============================================================================# 9 | set(CMAKE_SYSTEM_NAME Arduino) 10 | 11 | set(CMAKE_C_COMPILER avr-gcc) 12 | set(CMAKE_CXX_COMPILER avr-g++) 13 | 14 | # Add current directory to CMake Module path automatically 15 | if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/Platform/Arduino.cmake) 16 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}) 17 | endif() 18 | 19 | #=============================================================================# 20 | # System Paths # 21 | #=============================================================================# 22 | if(UNIX) 23 | include(Platform/UnixPaths) 24 | if(APPLE) 25 | list(APPEND CMAKE_SYSTEM_PREFIX_PATH ~/Applications 26 | /Applications 27 | /Developer/Applications 28 | /sw # Fink 29 | /opt/local) # MacPorts 30 | endif() 31 | elseif(WIN32) 32 | include(Platform/WindowsPaths) 33 | endif() 34 | 35 | 36 | #=============================================================================# 37 | # Detect Arduino SDK # 38 | #=============================================================================# 39 | if(NOT ARDUINO_SDK_PATH) 40 | set(ARDUINO_PATHS) 41 | 42 | foreach(DETECT_VERSION_MAJOR 1) 43 | foreach(DETECT_VERSION_MINOR RANGE 5 0) 44 | list(APPEND ARDUINO_PATHS arduino-${DETECT_VERSION_MAJOR}.${DETECT_VERSION_MINOR}) 45 | foreach(DETECT_VERSION_PATCH RANGE 3 0) 46 | list(APPEND ARDUINO_PATHS arduino-${DETECT_VERSION_MAJOR}.${DETECT_VERSION_MINOR}.${DETECT_VERSION_PATCH}) 47 | endforeach() 48 | endforeach() 49 | endforeach() 50 | 51 | foreach(VERSION RANGE 23 19) 52 | list(APPEND ARDUINO_PATHS arduino-00${VERSION}) 53 | endforeach() 54 | 55 | if(UNIX) 56 | file(GLOB SDK_PATH_HINTS /usr/share/arduino* 57 | /opt/local/arduino* 58 | /opt/arduino* 59 | /usr/local/share/arduino*) 60 | elseif(WIN32) 61 | set(SDK_PATH_HINTS "C:\\Program Files\\Arduino" 62 | "C:\\Program Files (x86)\\Arduino" 63 | ) 64 | endif() 65 | list(SORT SDK_PATH_HINTS) 66 | list(REVERSE SDK_PATH_HINTS) 67 | endif() 68 | 69 | find_path(ARDUINO_SDK_PATH 70 | NAMES lib/version.txt 71 | PATH_SUFFIXES share/arduino 72 | Arduino.app/Contents/Resources/Java/ 73 | ${ARDUINO_PATHS} 74 | HINTS ${SDK_PATH_HINTS} 75 | DOC "Arduino SDK path.") 76 | 77 | if(ARDUINO_SDK_PATH) 78 | list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${ARDUINO_SDK_PATH}/hardware/tools/avr) 79 | list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${ARDUINO_SDK_PATH}/hardware/tools/avr/utils) 80 | else() 81 | message(FATAL_ERROR "Could not find Arduino SDK (set ARDUINO_SDK_PATH)!") 82 | endif() 83 | 84 | -------------------------------------------------------------------------------- /cmake/Platform/Arduino.cmake: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # generate_arduino_firmware(name 3 | # [BOARD board_id] 4 | # [SKETCH sketch_path | 5 | # SRCS src1 src2 ... srcN] 6 | # [HDRS hdr1 hdr2 ... hdrN] 7 | # [LIBS lib1 lib2 ... libN] 8 | # [PORT port] 9 | # [SERIAL serial_cmd] 10 | # [PROGRAMMER programmer_id] 11 | # [AFLAGS flags] 12 | # [NO_AUTOLIBS] 13 | # [MANUAL]) 14 | # 15 | #=============================================================================# 16 | # 17 | # generaters firmware and libraries for Arduino devices 18 | # 19 | # The arguments are as follows: 20 | # 21 | # name # The name of the firmware target [REQUIRED] 22 | # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] 23 | # SKETCH # Arduino sketch [must have SRCS or SKETCH] 24 | # SRCS # Sources [must have SRCS or SKETCH] 25 | # HDRS # Headers 26 | # LIBS # Libraries to link 27 | # ARDLIBS # Arduino libraries to link (Wire, Servo, SPI, etc) 28 | # PORT # Serial port (enables upload support) 29 | # SERIAL # Serial command for serial target 30 | # PROGRAMMER # Programmer id (enables programmer support) 31 | # AFLAGS # Avrdude flags for target 32 | # NO_AUTOLIBS # Disables Arduino library detection 33 | # MANUAL # (Advanced) Only use AVR Libc/Includes 34 | # 35 | # Here is a short example for a target named test: 36 | # 37 | # generate_arduino_firmware( 38 | # NAME test 39 | # SRCS test.cpp 40 | # test2.cpp 41 | # HDRS test.h test2.h 42 | # BOARD uno) 43 | # 44 | # Alternatively you can specify the option by variables: 45 | # 46 | # set(test_SRCS test.cpp test2.cpp) 47 | # set(test_HDRS test.h test2.h 48 | # set(test_BOARD uno) 49 | # 50 | # generate_arduino_firmware(test) 51 | # 52 | # All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). 53 | # 54 | #=============================================================================# 55 | # generate_avr_firmware(name 56 | # [BOARD board_id] 57 | # SRCS src1 src2 ... srcN] 58 | # [HDRS hdr1 hdr2 ... hdrN] 59 | # [LIBS lib1 lib2 ... libN] 60 | # [PORT port] 61 | # [SERIAL serial_cmd] 62 | # [PROGRAMMER programmer_id] 63 | # [AFLAGS flags]) 64 | #=============================================================================# 65 | # 66 | # generaters firmware and libraries for AVR devices 67 | # it simply calls generate_arduino_firmware() with NO_AUTOLIBS and MANUAL 68 | # 69 | # The arguments are as follows: 70 | # 71 | # name # The name of the firmware target [REQUIRED] 72 | # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] 73 | # SRCS # Sources [REQUIRED] 74 | # HDRS # Headers 75 | # LIBS # Libraries to link 76 | # PORT # Serial port (enables upload support) 77 | # SERIAL # Serial command for serial target 78 | # PROGRAMMER # Programmer id (enables programmer support) 79 | # AFLAGS # Avrdude flags for target 80 | # 81 | # Here is a short example for a target named test: 82 | # 83 | # generate_avr_firmware( 84 | # NAME test 85 | # SRCS test.cpp 86 | # test2.cpp 87 | # HDRS test.h test2.h 88 | # BOARD uno) 89 | # 90 | # Alternatively you can specify the option by variables: 91 | # 92 | # set(test_SRCS test.cpp test2.cpp) 93 | # set(test_HDRS test.h test2.h 94 | # set(test_BOARD uno) 95 | # 96 | # generate_avr_firmware(test) 97 | # 98 | # All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). 99 | # 100 | #=============================================================================# 101 | # generate_arduino_library(name 102 | # [BOARD board_id] 103 | # [SRCS src1 src2 ... srcN] 104 | # [HDRS hdr1 hdr2 ... hdrN] 105 | # [LIBS lib1 lib2 ... libN] 106 | # [NO_AUTOLIBS] 107 | # [MANUAL]) 108 | #=============================================================================# 109 | # generaters firmware and libraries for Arduino devices 110 | # 111 | # The arguments are as follows: 112 | # 113 | # name # The name of the firmware target [REQUIRED] 114 | # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] 115 | # SRCS # Sources [REQUIRED] 116 | # HDRS # Headers 117 | # LIBS # Libraries to link 118 | # NO_AUTOLIBS # Disables Arduino library detection 119 | # MANUAL # (Advanced) Only use AVR Libc/Includes 120 | # 121 | # Here is a short example for a target named test: 122 | # 123 | # generate_arduino_library( 124 | # NAME test 125 | # SRCS test.cpp 126 | # test2.cpp 127 | # HDRS test.h test2.h 128 | # BOARD uno) 129 | # 130 | # Alternatively you can specify the option by variables: 131 | # 132 | # set(test_SRCS test.cpp test2.cpp) 133 | # set(test_HDRS test.h test2.h 134 | # set(test_BOARD uno) 135 | # 136 | # generate_arduino_library(test) 137 | # 138 | # All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). 139 | # 140 | #=============================================================================# 141 | # generate_avr_library(name 142 | # [BOARD board_id] 143 | # [SRCS src1 src2 ... srcN] 144 | # [HDRS hdr1 hdr2 ... hdrN] 145 | # [LIBS lib1 lib2 ... libN]) 146 | #=============================================================================# 147 | # generaters firmware and libraries for AVR devices 148 | # it simply calls generate_arduino_library() with NO_AUTOLIBS and MANUAL 149 | # 150 | # The arguments are as follows: 151 | # 152 | # name # The name of the firmware target [REQUIRED] 153 | # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] 154 | # SRCS # Sources [REQUIRED] 155 | # HDRS # Headers 156 | # LIBS # Libraries to link 157 | # 158 | # Here is a short example for a target named test: 159 | # 160 | # generate_avr_library( 161 | # NAME test 162 | # SRCS test.cpp 163 | # test2.cpp 164 | # HDRS test.h test2.h 165 | # BOARD uno) 166 | # 167 | # Alternatively you can specify the option by variables: 168 | # 169 | # set(test_SRCS test.cpp test2.cpp) 170 | # set(test_HDRS test.h test2.h 171 | # set(test_BOARD uno) 172 | # 173 | # generate_avr_library(test) 174 | # 175 | # All variables need to be prefixed with the target name (${TARGET_NAME}_${OPTION}). 176 | # 177 | #=============================================================================# 178 | # generate_arduino_example(name 179 | # LIBRARY library_name 180 | # EXAMPLE example_name 181 | # [BOARD board_id] 182 | # [PORT port] 183 | # [SERIAL serial command] 184 | # [PORGRAMMER programmer_id] 185 | # [AFLAGS avrdude_flags]) 186 | #=============================================================================# 187 | # 188 | # name - The name of the library example [REQUIRED] 189 | # LIBRARY - Library name [REQUIRED] 190 | # EXAMPLE - Example name [REQUIRED] 191 | # BOARD - Board ID 192 | # PORT - Serial port [optional] 193 | # SERIAL - Serial command [optional] 194 | # PROGRAMMER - Programmer id (enables programmer support) 195 | # AFLAGS - Avrdude flags for target 196 | # 197 | # Creates a example from the specified library. 198 | # 199 | # 200 | #=============================================================================# 201 | # print_board_list() 202 | #=============================================================================# 203 | # 204 | # Print list of detected Arduino Boards. 205 | # 206 | #=============================================================================# 207 | # print_programmer_list() 208 | #=============================================================================# 209 | # 210 | # Print list of detected Programmers. 211 | # 212 | #=============================================================================# 213 | # print_programmer_settings(PROGRAMMER) 214 | #=============================================================================# 215 | # 216 | # PROGRAMMER - programmer id 217 | # 218 | # Print the detected Programmer settings. 219 | # 220 | #=============================================================================# 221 | # print_board_settings(ARDUINO_BOARD) 222 | #=============================================================================# 223 | # 224 | # ARDUINO_BOARD - Board id 225 | # 226 | # Print the detected Arduino board settings. 227 | # 228 | #=============================================================================# 229 | # register_hardware_platform(HARDWARE_PLATFORM_PATH) 230 | #=============================================================================# 231 | # 232 | # HARDWARE_PLATFORM_PATH - Hardware platform path 233 | # 234 | # Registers a Hardware Platform path. 235 | # See: http://code.google.com/p/arduino/wiki/Platforms 236 | # 237 | # This enables you to register new types of hardware platforms such as the 238 | # Sagnuino, without having to copy the files into your Arduion SDK. 239 | # 240 | # A Hardware Platform is a directory containing the following: 241 | # 242 | # HARDWARE_PLATFORM_PATH/ 243 | # |-- bootloaders/ 244 | # |-- cores/ 245 | # |-- variants/ 246 | # |-- boards.txt 247 | # `-- programmers.txt 248 | # 249 | # The board.txt describes the target boards and bootloaders. While 250 | # programmers.txt the programmer defintions. 251 | # 252 | # A good example of a Hardware Platform is in the Arduino SDK: 253 | # 254 | # ${ARDUINO_SDK_PATH}/hardware/arduino/ 255 | # 256 | #=============================================================================# 257 | # Configuration Options 258 | #=============================================================================# 259 | # 260 | # ARDUINO_SDK_PATH - Arduino SDK Path 261 | # ARDUINO_AVRDUDE_PROGRAM - Full path to avrdude programmer 262 | # ARDUINO_AVRDUDE_CONFIG_PATH - Full path to avrdude configuration file 263 | # 264 | # ARDUINO_C_FLAGS - C compiler flags 265 | # ARDUINO_CXX_FLAGS - C++ compiler flags 266 | # ARDUINO_LINKER_FLAGS - Linker flags 267 | # 268 | # ARDUINO_DEFAULT_BOARD - Default Arduino Board ID when not specified. 269 | # ARDUINO_DEFAULT_PORT - Default Arduino port when not specified. 270 | # ARDUINO_DEFAULT_SERIAL - Default Arduino Serial command when not specified. 271 | # ARDUINO_DEFAULT_PROGRAMMER - Default Arduino Programmer ID when not specified. 272 | # 273 | # 274 | # ARDUINO_FOUND - Set to True when the Arduino SDK is detected and configured. 275 | # ARDUINO_SDK_VERSION - Set to the version of the detected Arduino SDK (ex: 1.0) 276 | 277 | #=============================================================================# 278 | # Author: Tomasz Bogdal (QueezyTheGreat) 279 | # Home: https://github.com/queezythegreat/arduino-cmake 280 | # 281 | # This Source Code Form is subject to the terms of the Mozilla Public 282 | # License, v. 2.0. If a copy of the MPL was not distributed with this file, 283 | # You can obtain one at http://mozilla.org/MPL/2.0/. 284 | #=============================================================================# 285 | cmake_minimum_required(VERSION 2.8.5) 286 | include(CMakeParseArguments) 287 | 288 | 289 | 290 | 291 | 292 | 293 | #=============================================================================# 294 | # User Functions 295 | #=============================================================================# 296 | 297 | #=============================================================================# 298 | # [PUBLIC/USER] 299 | # 300 | # print_board_list() 301 | # 302 | # see documentation at top 303 | #=============================================================================# 304 | function(PRINT_BOARD_LIST) 305 | foreach(PLATFORM ${ARDUINO_PLATFORMS}) 306 | if(${PLATFORM}_BOARDS) 307 | message(STATUS "${PLATFORM} Boards:") 308 | print_list(${PLATFORM}_BOARDS) 309 | message(STATUS "") 310 | endif() 311 | endforeach() 312 | endfunction() 313 | 314 | #=============================================================================# 315 | # [PUBLIC/USER] 316 | # 317 | # print_programmer_list() 318 | # 319 | # see documentation at top 320 | #=============================================================================# 321 | function(PRINT_PROGRAMMER_LIST) 322 | foreach(PLATFORM ${ARDUINO_PLATFORMS}) 323 | if(${PLATFORM}_PROGRAMMERS) 324 | message(STATUS "${PLATFORM} Programmers:") 325 | print_list(${PLATFORM}_PROGRAMMERS) 326 | endif() 327 | message(STATUS "") 328 | endforeach() 329 | endfunction() 330 | 331 | #=============================================================================# 332 | # [PUBLIC/USER] 333 | # 334 | # print_programmer_settings(PROGRAMMER) 335 | # 336 | # see documentation at top 337 | #=============================================================================# 338 | function(PRINT_PROGRAMMER_SETTINGS PROGRAMMER) 339 | if(${PROGRAMMER}.SETTINGS) 340 | message(STATUS "Programmer ${PROGRAMMER} Settings:") 341 | print_settings(${PROGRAMMER}) 342 | endif() 343 | endfunction() 344 | 345 | # [PUBLIC/USER] 346 | # 347 | # print_board_settings(ARDUINO_BOARD) 348 | # 349 | # see documentation at top 350 | function(PRINT_BOARD_SETTINGS ARDUINO_BOARD) 351 | if(${ARDUINO_BOARD}.SETTINGS) 352 | message(STATUS "Arduino ${ARDUINO_BOARD} Board:") 353 | print_settings(${ARDUINO_BOARD}) 354 | endif() 355 | endfunction() 356 | 357 | #=============================================================================# 358 | # [PUBLIC/USER] 359 | # see documentation at top 360 | #=============================================================================# 361 | function(GENERATE_ARDUINO_LIBRARY INPUT_NAME) 362 | message(STATUS "Generating ${INPUT_NAME}") 363 | parse_generator_arguments(${INPUT_NAME} INPUT 364 | "NO_AUTOLIBS;MANUAL" # Options 365 | "BOARD" # One Value Keywords 366 | "SRCS;HDRS;LIBS" # Multi Value Keywords 367 | ${ARGN}) 368 | 369 | if(NOT INPUT_BOARD) 370 | set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) 371 | endif() 372 | if(NOT INPUT_MANUAL) 373 | set(INPUT_MANUAL FALSE) 374 | endif() 375 | required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") 376 | 377 | set(ALL_LIBS) 378 | set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS}) 379 | 380 | if(NOT INPUT_MANUAL) 381 | setup_arduino_core(CORE_LIB ${INPUT_BOARD}) 382 | endif() 383 | 384 | find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "") 385 | set(LIB_DEP_INCLUDES) 386 | foreach(LIB_DEP ${TARGET_LIBS}) 387 | set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"") 388 | endforeach() 389 | 390 | if(NOT ${INPUT_NO_AUTOLIBS}) 391 | setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") 392 | endif() 393 | 394 | list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) 395 | 396 | add_library(${INPUT_NAME} ${ALL_SRCS}) 397 | 398 | get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${INPUT_BOARD} ${INPUT_MANUAL}) 399 | 400 | set_target_properties(${INPUT_NAME} PROPERTIES 401 | COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS} ${LIB_DEP_INCLUDES}" 402 | LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") 403 | 404 | target_link_libraries(${INPUT_NAME} ${ALL_LIBS} "-lc -lm") 405 | endfunction() 406 | 407 | #=============================================================================# 408 | # [PUBLIC/USER] 409 | # see documentation at top 410 | #=============================================================================# 411 | function(GENERATE_AVR_LIBRARY INPUT_NAME) 412 | message(STATUS "Generating ${INPUT_NAME}") 413 | parse_generator_arguments(${INPUT_NAME} INPUT 414 | "NO_AUTOLIBS;MANUAL" # Options 415 | "BOARD" # One Value Keywords 416 | "SRCS;HDRS;LIBS" # Multi Value Keywords 417 | ${ARGN}) 418 | 419 | if(NOT INPUT_BOARD) 420 | set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) 421 | endif() 422 | 423 | required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") 424 | 425 | if(INPUT_HDRS) 426 | set( INPUT_HDRS "SRCS ${INPUT_HDRS}" ) 427 | endif() 428 | if(INPUT_LIBS) 429 | set( INPUT_LIBS "LIBS ${INPUT_LIBS}" ) 430 | endif() 431 | 432 | if(INPUT_HDRS) 433 | list(INSERT INPUT_HDRS 0 "HDRS") 434 | endif() 435 | if(INPUT_LIBS) 436 | list(INSERT INPUT_LIBS 0 "LIBS") 437 | endif() 438 | 439 | 440 | generate_arduino_library( ${INPUT_NAME} 441 | NO_AUTOLIBS 442 | MANUAL 443 | BOARD ${INPUT_BOARD} 444 | SRCS ${INPUT_SRCS} 445 | ${INPUT_HDRS} 446 | ${INPUT_LIBS} ) 447 | 448 | endfunction() 449 | 450 | #=============================================================================# 451 | # [PUBLIC/USER] 452 | # see documentation at top 453 | #=============================================================================# 454 | function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) 455 | message(STATUS "Generating ${INPUT_NAME}") 456 | parse_generator_arguments(${INPUT_NAME} INPUT 457 | "NO_AUTOLIBS;MANUAL" # Options 458 | "BOARD;PORT;SKETCH;PROGRAMMER" # One Value Keywords 459 | "SERIAL;SRCS;HDRS;LIBS;ARDLIBS;AFLAGS" # Multi Value Keywords 460 | ${ARGN}) 461 | 462 | if(NOT INPUT_BOARD) 463 | set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) 464 | endif() 465 | if(NOT INPUT_PORT) 466 | set(INPUT_PORT ${ARDUINO_DEFAULT_PORT}) 467 | endif() 468 | if(NOT INPUT_SERIAL) 469 | set(INPUT_SERIAL ${ARDUINO_DEFAULT_SERIAL}) 470 | endif() 471 | if(NOT INPUT_PROGRAMMER) 472 | set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) 473 | endif() 474 | if(NOT INPUT_MANUAL) 475 | set(INPUT_MANUAL FALSE) 476 | endif() 477 | required_variables(VARS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") 478 | 479 | set(ALL_LIBS) 480 | set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS}) 481 | set(LIB_DEP_INCLUDES) 482 | 483 | if(NOT INPUT_MANUAL) 484 | setup_arduino_core(CORE_LIB ${INPUT_BOARD}) 485 | endif() 486 | 487 | if(NOT "${INPUT_SKETCH}" STREQUAL "") 488 | get_filename_component(INPUT_SKETCH "${INPUT_SKETCH}" ABSOLUTE) 489 | setup_arduino_sketch(${INPUT_NAME} ${INPUT_SKETCH} ALL_SRCS) 490 | if (IS_DIRECTORY "${INPUT_SKETCH}") 491 | set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${INPUT_SKETCH}\"") 492 | else() 493 | get_filename_component(INPUT_SKETCH_PATH "${INPUT_SKETCH}" PATH) 494 | set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${INPUT_SKETCH_PATH}\"") 495 | endif() 496 | endif() 497 | 498 | required_variables(VARS ALL_SRCS MSG "must define SRCS or SKETCH for target ${INPUT_NAME}") 499 | 500 | find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "${INPUT_ARDLIBS}") 501 | foreach(LIB_DEP ${TARGET_LIBS}) 502 | arduino_debug_msg("Arduino Library: ${LIB_DEP}") 503 | set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"") 504 | endforeach() 505 | 506 | if(NOT INPUT_NO_AUTOLIBS) 507 | setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${INPUT_ARDLIBS}" "${LIB_DEP_INCLUDES}" "") 508 | foreach(LIB_INCLUDES ${ALL_LIBS_INCLUDES}) 509 | arduino_debug_msg("Arduino Library Includes: ${LIB_INCLUDES}") 510 | set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} ${LIB_INCLUDES}") 511 | endforeach() 512 | endif() 513 | 514 | list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) 515 | 516 | setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_MANUAL}") 517 | 518 | if(INPUT_PORT) 519 | setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") 520 | endif() 521 | 522 | if(INPUT_SERIAL) 523 | setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") 524 | endif() 525 | 526 | endfunction() 527 | 528 | #=============================================================================# 529 | # [PUBLIC/USER] 530 | # see documentation at top 531 | #=============================================================================# 532 | function(GENERATE_AVR_FIRMWARE INPUT_NAME) 533 | # TODO: This is not optimal!!!! 534 | message(STATUS "Generating ${INPUT_NAME}") 535 | parse_generator_arguments(${INPUT_NAME} INPUT 536 | "NO_AUTOLIBS;MANUAL" # Options 537 | "BOARD;PORT;PROGRAMMER" # One Value Keywords 538 | "SERIAL;SRCS;HDRS;LIBS;AFLAGS" # Multi Value Keywords 539 | ${ARGN}) 540 | 541 | if(NOT INPUT_BOARD) 542 | set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) 543 | endif() 544 | if(NOT INPUT_PORT) 545 | set(INPUT_PORT ${ARDUINO_DEFAULT_PORT}) 546 | endif() 547 | if(NOT INPUT_SERIAL) 548 | set(INPUT_SERIAL ${ARDUINO_DEFAULT_SERIAL}) 549 | endif() 550 | if(NOT INPUT_PROGRAMMER) 551 | set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) 552 | endif() 553 | 554 | required_variables(VARS INPUT_BOARD INPUT_SRCS MSG "must define for target ${INPUT_NAME}") 555 | 556 | if(INPUT_HDRS) 557 | list(INSERT INPUT_HDRS 0 "HDRS") 558 | endif() 559 | if(INPUT_LIBS) 560 | list(INSERT INPUT_LIBS 0 "LIBS") 561 | endif() 562 | if(INPUT_AFLAGS) 563 | list(INSERT INPUT_AFLAGS 0 "AFLAGS") 564 | endif() 565 | 566 | generate_arduino_firmware( ${INPUT_NAME} 567 | NO_AUTOLIBS 568 | MANUAL 569 | BOARD ${INPUT_BOARD} 570 | PORT ${INPUT_PORT} 571 | PROGRAMMER ${INPUT_PROGRAMMER} 572 | SERIAL ${INPUT_SERIAL} 573 | SRCS ${INPUT_SRCS} 574 | ${INPUT_HDRS} 575 | ${INPUT_LIBS} 576 | ${INPUT_AFLAGS} ) 577 | 578 | endfunction() 579 | 580 | #=============================================================================# 581 | # [PUBLIC/USER] 582 | # see documentation at top 583 | #=============================================================================# 584 | function(GENERATE_ARDUINO_EXAMPLE INPUT_NAME) 585 | parse_generator_arguments(${INPUT_NAME} INPUT 586 | "" # Options 587 | "LIBRARY;EXAMPLE;BOARD;PORT;PROGRAMMER" # One Value Keywords 588 | "SERIAL;AFLAGS" # Multi Value Keywords 589 | ${ARGN}) 590 | 591 | 592 | if(NOT INPUT_BOARD) 593 | set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) 594 | endif() 595 | if(NOT INPUT_PORT) 596 | set(INPUT_PORT ${ARDUINO_DEFAULT_PORT}) 597 | endif() 598 | if(NOT INPUT_SERIAL) 599 | set(INPUT_SERIAL ${ARDUINO_DEFAULT_SERIAL}) 600 | endif() 601 | if(NOT INPUT_PROGRAMMER) 602 | set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) 603 | endif() 604 | required_variables(VARS INPUT_LIBRARY INPUT_EXAMPLE INPUT_BOARD 605 | MSG "must define for target ${INPUT_NAME}") 606 | 607 | message(STATUS "Generating ${INPUT_NAME}") 608 | 609 | set(ALL_LIBS) 610 | set(ALL_SRCS) 611 | 612 | setup_arduino_core(CORE_LIB ${INPUT_BOARD}) 613 | 614 | setup_arduino_example("${INPUT_NAME}" "${INPUT_LIBRARY}" "${INPUT_EXAMPLE}" ALL_SRCS) 615 | 616 | if(NOT ALL_SRCS) 617 | message(FATAL_ERROR "Missing sources for example, aborting!") 618 | endif() 619 | 620 | find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "") 621 | set(LIB_DEP_INCLUDES) 622 | foreach(LIB_DEP ${TARGET_LIBS}) 623 | set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"") 624 | endforeach() 625 | 626 | setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") 627 | 628 | list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) 629 | 630 | setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" FALSE) 631 | 632 | if(INPUT_PORT) 633 | setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") 634 | endif() 635 | 636 | if(INPUT_SERIAL) 637 | setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") 638 | endif() 639 | endfunction() 640 | 641 | #=============================================================================# 642 | # [PUBLIC/USER] 643 | # see documentation at top 644 | #=============================================================================# 645 | function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) 646 | string(REGEX REPLACE "/$" "" PLATFORM_PATH ${PLATFORM_PATH}) 647 | GET_FILENAME_COMPONENT(PLATFORM ${PLATFORM_PATH} NAME) 648 | 649 | if(PLATFORM) 650 | string(TOUPPER ${PLATFORM} PLATFORM) 651 | list(FIND ARDUINO_PLATFORMS ${PLATFORM} platform_exists) 652 | 653 | if (platform_exists EQUAL -1) 654 | set(${PLATFORM}_PLATFORM_PATH ${PLATFORM_PATH} CACHE INTERNAL "The path to ${PLATFORM}") 655 | set(ARDUINO_PLATFORMS ${ARDUINO_PLATFORMS} ${PLATFORM} CACHE INTERNAL "A list of registered platforms") 656 | 657 | find_file(${PLATFORM}_CORES_PATH 658 | NAMES cores 659 | PATHS ${PLATFORM_PATH} 660 | DOC "Path to directory containing the Arduino core sources.") 661 | 662 | find_file(${PLATFORM}_VARIANTS_PATH 663 | NAMES variants 664 | PATHS ${PLATFORM_PATH} 665 | DOC "Path to directory containing the Arduino variant sources.") 666 | 667 | find_file(${PLATFORM}_BOOTLOADERS_PATH 668 | NAMES bootloaders 669 | PATHS ${PLATFORM_PATH} 670 | DOC "Path to directory containing the Arduino bootloader images and sources.") 671 | 672 | find_file(${PLATFORM}_PROGRAMMERS_PATH 673 | NAMES programmers.txt 674 | PATHS ${PLATFORM_PATH} 675 | DOC "Path to Arduino programmers definition file.") 676 | 677 | find_file(${PLATFORM}_BOARDS_PATH 678 | NAMES boards.txt 679 | PATHS ${PLATFORM_PATH} 680 | DOC "Path to Arduino boards definition file.") 681 | 682 | if(${PLATFORM}_BOARDS_PATH) 683 | load_arduino_style_settings(${PLATFORM}_BOARDS "${PLATFORM_PATH}/boards.txt") 684 | endif() 685 | 686 | if(${PLATFORM}_PROGRAMMERS_PATH) 687 | load_arduino_style_settings(${PLATFORM}_PROGRAMMERS "${ARDUINO_PROGRAMMERS_PATH}") 688 | endif() 689 | 690 | if(${PLATFORM}_VARIANTS_PATH) 691 | file(GLOB sub-dir ${${PLATFORM}_VARIANTS_PATH}/*) 692 | foreach(dir ${sub-dir}) 693 | if(IS_DIRECTORY ${dir}) 694 | get_filename_component(variant ${dir} NAME) 695 | set(VARIANTS ${VARIANTS} ${variant} CACHE INTERNAL "A list of registered variant boards") 696 | set(${variant}.path ${dir} CACHE INTERNAL "The path to the variant ${variant}") 697 | endif() 698 | endforeach() 699 | endif() 700 | 701 | if(${PLATFORM}_CORES_PATH) 702 | file(GLOB sub-dir ${${PLATFORM}_CORES_PATH}/*) 703 | foreach(dir ${sub-dir}) 704 | if(IS_DIRECTORY ${dir}) 705 | get_filename_component(core ${dir} NAME) 706 | set(CORES ${CORES} ${core} CACHE INTERNAL "A list of registered cores") 707 | set(${core}.path ${dir} CACHE INTERNAL "The path to the core ${core}") 708 | endif() 709 | endforeach() 710 | endif() 711 | endif() 712 | endif() 713 | 714 | endfunction() 715 | 716 | #=============================================================================# 717 | # Internal Functions 718 | #=============================================================================# 719 | 720 | #=============================================================================# 721 | # [PRIVATE/INTERNAL] 722 | # 723 | # parse_generator_arguments(TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS [ARG1 ARG2 .. ARGN]) 724 | # 725 | # PREFIX - Parsed options prefix 726 | # OPTIONS - List of options 727 | # ARGS - List of one value keyword arguments 728 | # MULTI_ARGS - List of multi value keyword arguments 729 | # [ARG1 ARG2 .. ARGN] - command arguments [optional] 730 | # 731 | # Parses generator options from either variables or command arguments 732 | # 733 | #=============================================================================# 734 | macro(PARSE_GENERATOR_ARGUMENTS TARGET_NAME PREFIX OPTIONS ARGS MULTI_ARGS) 735 | cmake_parse_arguments(${PREFIX} "${OPTIONS}" "${ARGS}" "${MULTI_ARGS}" ${ARGN}) 736 | error_for_unparsed(${PREFIX}) 737 | load_generator_settings(${TARGET_NAME} ${PREFIX} ${OPTIONS} ${ARGS} ${MULTI_ARGS}) 738 | endmacro() 739 | 740 | #=============================================================================# 741 | # [PRIVATE/INTERNAL] 742 | # 743 | # load_generator_settings(TARGET_NAME PREFIX [SUFFIX_1 SUFFIX_2 .. SUFFIX_N]) 744 | # 745 | # TARGET_NAME - The base name of the user settings 746 | # PREFIX - The prefix name used for generator settings 747 | # SUFFIX_XX - List of suffixes to load 748 | # 749 | # Loads a list of user settings into the generators scope. User settings have 750 | # the following syntax: 751 | # 752 | # ${BASE_NAME}${SUFFIX} 753 | # 754 | # The BASE_NAME is the target name and the suffix is a specific generator settings. 755 | # 756 | # For every user setting found a generator setting is created of the follwoing fromat: 757 | # 758 | # ${PREFIX}${SUFFIX} 759 | # 760 | # The purpose of loading the settings into the generator is to not modify user settings 761 | # and to have a generic naming of the settings within the generator. 762 | # 763 | #=============================================================================# 764 | function(LOAD_GENERATOR_SETTINGS TARGET_NAME PREFIX) 765 | foreach(GEN_SUFFIX ${ARGN}) 766 | if(${TARGET_NAME}_${GEN_SUFFIX} AND NOT ${PREFIX}_${GEN_SUFFIX}) 767 | set(${PREFIX}_${GEN_SUFFIX} ${${TARGET_NAME}_${GEN_SUFFIX}} PARENT_SCOPE) 768 | endif() 769 | endforeach() 770 | endfunction() 771 | 772 | #=============================================================================# 773 | # [PRIVATE/INTERNAL] 774 | # 775 | # get_arduino_flags(COMPILE_FLAGS LINK_FLAGS BOARD_ID MANUAL) 776 | # 777 | # COMPILE_FLAGS_VAR -Variable holding compiler flags 778 | # LINK_FLAGS_VAR - Variable holding linker flags 779 | # BOARD_ID - The board id name 780 | # MANUAL - (Advanced) Only use AVR Libc/Includes 781 | # 782 | # Configures the the build settings for the specified Arduino Board. 783 | # 784 | #=============================================================================# 785 | function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) 786 | 787 | set(BOARD_CORE ${${BOARD_ID}.build.core}) 788 | if(BOARD_CORE) 789 | if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)") 790 | string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) 791 | set(ARDUINO_VERSION_DEFINE "") 792 | if(CMAKE_MATCH_1 GREATER 0) 793 | set(ARDUINO_VERSION_DEFINE "${CMAKE_MATCH_1}") 794 | endif() 795 | if(CMAKE_MATCH_2 GREATER 10) 796 | set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_2}") 797 | else() 798 | set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}") 799 | endif() 800 | else() 801 | message("Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})") 802 | endif() 803 | 804 | # output 805 | set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -mmcu=${${BOARD_ID}.build.mcu}") 806 | if(DEFINED ${BOARD_ID}.build.vid) 807 | set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}") 808 | endif() 809 | if(DEFINED ${BOARD_ID}.build.pid) 810 | set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_PID=${${BOARD_ID}.build.pid}") 811 | endif() 812 | if(NOT MANUAL) 813 | set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${${BOARD_CORE}.path}\" -I\"${ARDUINO_LIBRARIES_PATH}\"") 814 | endif() 815 | set(LINK_FLAGS "-mmcu=${${BOARD_ID}.build.mcu}") 816 | if(ARDUINO_SDK_VERSION VERSION_GREATER 1.0 OR ARDUINO_SDK_VERSION VERSION_EQUAL 1.0) 817 | if(NOT MANUAL) 818 | set(PIN_HEADER ${${${BOARD_ID}.build.variant}.path}) 819 | if(PIN_HEADER) 820 | set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${PIN_HEADER}\"") 821 | endif() 822 | endif() 823 | endif() 824 | 825 | # output 826 | set(${COMPILE_FLAGS_VAR} "${COMPILE_FLAGS}" PARENT_SCOPE) 827 | set(${LINK_FLAGS_VAR} "${LINK_FLAGS}" PARENT_SCOPE) 828 | 829 | else() 830 | message(FATAL_ERROR "Invalid Arduino board ID (${BOARD_ID}), aborting.") 831 | endif() 832 | endfunction() 833 | 834 | #=============================================================================# 835 | # [PRIVATE/INTERNAL] 836 | # 837 | # setup_arduino_core(VAR_NAME BOARD_ID) 838 | # 839 | # VAR_NAME - Variable name that will hold the generated library name 840 | # BOARD_ID - Arduino board id 841 | # 842 | # Creates the Arduino Core library for the specified board, 843 | # each board gets it's own version of the library. 844 | # 845 | #=============================================================================# 846 | function(setup_arduino_core VAR_NAME BOARD_ID) 847 | set(CORE_LIB_NAME ${BOARD_ID}_CORE) 848 | set(BOARD_CORE ${${BOARD_ID}.build.core}) 849 | if(BOARD_CORE) 850 | if(NOT TARGET ${CORE_LIB_NAME}) 851 | set(BOARD_CORE_PATH ${${BOARD_CORE}.path}) 852 | find_sources(CORE_SRCS ${BOARD_CORE_PATH} True) 853 | # Debian/Ubuntu fix 854 | list(REMOVE_ITEM CORE_SRCS "${BOARD_CORE_PATH}/main.cxx") 855 | add_library(${CORE_LIB_NAME} ${CORE_SRCS}) 856 | get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) 857 | set_target_properties(${CORE_LIB_NAME} PROPERTIES 858 | COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS}" 859 | LINK_FLAGS "${ARDUINO_LINK_FLAGS}") 860 | endif() 861 | set(${VAR_NAME} ${CORE_LIB_NAME} PARENT_SCOPE) 862 | endif() 863 | endfunction() 864 | 865 | #=============================================================================# 866 | # [PRIVATE/INTERNAL] 867 | # 868 | # find_arduino_libraries(VAR_NAME SRCS ARDLIBS) 869 | # 870 | # VAR_NAME - Variable name which will hold the results 871 | # SRCS - Sources that will be analized 872 | # ARDLIBS - Arduino libraries identified by name (e.g., Wire, SPI, Servo) 873 | # 874 | # returns a list of paths to libraries found. 875 | # 876 | # Finds all Arduino type libraries included in sources. Available libraries 877 | # are ${ARDUINO_SDK_PATH}/libraries and ${CMAKE_CURRENT_SOURCE_DIR}. 878 | # 879 | # Also adds Arduino libraries specifically names in ALIBS. We add ".h" to the 880 | # names and then process them just like the Arduino libraries found in the sources. 881 | # 882 | # A Arduino library is a folder that has the same name as the include header. 883 | # For example, if we have a include "#include " then the following 884 | # directory structure is considered a Arduino library: 885 | # 886 | # LibraryName/ 887 | # |- LibraryName.h 888 | # `- LibraryName.c 889 | # 890 | # If such a directory is found then all sources within that directory are considred 891 | # to be part of that Arduino library. 892 | # 893 | #=============================================================================# 894 | function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) 895 | set(ARDUINO_LIBS ) 896 | foreach(SRC ${SRCS}) 897 | 898 | # Skipping generated files. They are, probably, not exist yet. 899 | # TODO: Maybe it's possible to skip only really nonexisting files, 900 | # but then it wiil be less deterministic. 901 | get_source_file_property(_srcfile_generated ${SRC} GENERATED) 902 | # Workaround for sketches, which are marked as generated 903 | get_source_file_property(_sketch_generated ${SRC} GENERATED_SKETCH) 904 | 905 | if(NOT ${_srcfile_generated} OR ${_sketch_generated}) 906 | if(NOT (EXISTS ${SRC} OR 907 | EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${SRC} OR 908 | EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${SRC})) 909 | message(FATAL_ERROR "Invalid source file: ${SRC}") 910 | endif() 911 | file(STRINGS ${SRC} SRC_CONTENTS) 912 | 913 | foreach(LIBNAME ${ARDLIBS}) 914 | list(APPEND SRC_CONTENTS "#include <${LIBNAME}.h>") 915 | endforeach() 916 | 917 | foreach(SRC_LINE ${SRC_CONTENTS}) 918 | if("${SRC_LINE}" MATCHES "^[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]") 919 | get_filename_component(INCLUDE_NAME ${CMAKE_MATCH_1} NAME_WE) 920 | get_property(LIBRARY_SEARCH_PATH 921 | DIRECTORY # Property Scope 922 | PROPERTY LINK_DIRECTORIES) 923 | foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) 924 | if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) 925 | list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) 926 | break() 927 | endif() 928 | if(EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) 929 | list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) 930 | break() 931 | endif() 932 | endforeach() 933 | endif() 934 | endforeach() 935 | endif() 936 | endforeach() 937 | if(ARDUINO_LIBS) 938 | list(REMOVE_DUPLICATES ARDUINO_LIBS) 939 | endif() 940 | set(${VAR_NAME} ${ARDUINO_LIBS} PARENT_SCOPE) 941 | endfunction() 942 | 943 | #=============================================================================# 944 | # [PRIVATE/INTERNAL] 945 | # 946 | # setup_arduino_library(VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) 947 | # 948 | # VAR_NAME - Vairable wich will hold the generated library names 949 | # BOARD_ID - Board ID 950 | # LIB_PATH - Path of the library 951 | # COMPILE_FLAGS - Compile flags 952 | # LINK_FLAGS - Link flags 953 | # 954 | # Creates an Arduino library, with all it's library dependencies. 955 | # 956 | # ${LIB_NAME}_RECURSE controls if the library will recurse 957 | # when looking for source files. 958 | # 959 | #=============================================================================# 960 | 961 | # For known libraries can list recurse here 962 | set(Wire_RECURSE True) 963 | set(Ethernet_RECURSE True) 964 | set(SD_RECURSE True) 965 | function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) 966 | set(LIB_TARGETS) 967 | set(LIB_INCLUDES) 968 | 969 | get_filename_component(LIB_NAME ${LIB_PATH} NAME) 970 | set(TARGET_LIB_NAME ${BOARD_ID}_${LIB_NAME}) 971 | if(NOT TARGET ${TARGET_LIB_NAME}) 972 | string(REGEX REPLACE ".*/" "" LIB_SHORT_NAME ${LIB_NAME}) 973 | 974 | # Detect if recursion is needed 975 | if (NOT DEFINED ${LIB_SHORT_NAME}_RECURSE) 976 | set(${LIB_SHORT_NAME}_RECURSE False) 977 | endif() 978 | 979 | find_sources(LIB_SRCS ${LIB_PATH} ${${LIB_SHORT_NAME}_RECURSE}) 980 | if(LIB_SRCS) 981 | 982 | arduino_debug_msg("Generating Arduino ${LIB_NAME} library") 983 | add_library(${TARGET_LIB_NAME} STATIC ${LIB_SRCS}) 984 | 985 | get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) 986 | 987 | find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "") 988 | 989 | foreach(LIB_DEP ${LIB_DEPS}) 990 | setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} "${COMPILE_FLAGS}" "${LINK_FLAGS}") 991 | list(APPEND LIB_TARGETS ${DEP_LIB_SRCS}) 992 | list(APPEND LIB_INCLUDES ${DEP_LIB_SRCS_INCLUDES}) 993 | endforeach() 994 | 995 | if (LIB_INCLUDES) 996 | string(REPLACE ";" " " LIB_INCLUDES "${LIB_INCLUDES}") 997 | endif() 998 | 999 | set_target_properties(${TARGET_LIB_NAME} PROPERTIES 1000 | COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${LIB_INCLUDES} -I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\" ${COMPILE_FLAGS}" 1001 | LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") 1002 | list(APPEND LIB_INCLUDES "-I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\"") 1003 | 1004 | target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE ${LIB_TARGETS}) 1005 | list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) 1006 | 1007 | endif() 1008 | else() 1009 | # Target already exists, skiping creating 1010 | list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) 1011 | endif() 1012 | if(LIB_TARGETS) 1013 | list(REMOVE_DUPLICATES LIB_TARGETS) 1014 | endif() 1015 | set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE) 1016 | set(${VAR_NAME}_INCLUDES ${LIB_INCLUDES} PARENT_SCOPE) 1017 | endfunction() 1018 | 1019 | #=============================================================================# 1020 | # [PRIVATE/INTERNAL] 1021 | # 1022 | # setup_arduino_libraries(VAR_NAME BOARD_ID SRCS COMPILE_FLAGS LINK_FLAGS) 1023 | # 1024 | # VAR_NAME - Vairable wich will hold the generated library names 1025 | # BOARD_ID - Board ID 1026 | # SRCS - source files 1027 | # COMPILE_FLAGS - Compile flags 1028 | # LINK_FLAGS - Linker flags 1029 | # 1030 | # Finds and creates all dependency libraries based on sources. 1031 | # 1032 | #=============================================================================# 1033 | function(setup_arduino_libraries VAR_NAME BOARD_ID SRCS ARDLIBS COMPILE_FLAGS LINK_FLAGS) 1034 | set(LIB_TARGETS) 1035 | set(LIB_INCLUDES) 1036 | 1037 | find_arduino_libraries(TARGET_LIBS "${SRCS}" ARDLIBS) 1038 | foreach(TARGET_LIB ${TARGET_LIBS}) 1039 | # Create static library instead of returning sources 1040 | setup_arduino_library(LIB_DEPS ${BOARD_ID} ${TARGET_LIB} "${COMPILE_FLAGS}" "${LINK_FLAGS}") 1041 | list(APPEND LIB_TARGETS ${LIB_DEPS}) 1042 | list(APPEND LIB_INCLUDES ${LIB_DEPS_INCLUDES}) 1043 | endforeach() 1044 | 1045 | set(${VAR_NAME} ${LIB_TARGETS} PARENT_SCOPE) 1046 | set(${VAR_NAME}_INCLUDES ${LIB_INCLUDES} PARENT_SCOPE) 1047 | endfunction() 1048 | 1049 | 1050 | #=============================================================================# 1051 | # [PRIVATE/INTERNAL] 1052 | # 1053 | # setup_arduino_target(TARGET_NAME ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL) 1054 | # 1055 | # TARGET_NAME - Target name 1056 | # BOARD_ID - Arduino board ID 1057 | # ALL_SRCS - All sources 1058 | # ALL_LIBS - All libraries 1059 | # COMPILE_FLAGS - Compile flags 1060 | # LINK_FLAGS - Linker flags 1061 | # MANUAL - (Advanced) Only use AVR Libc/Includes 1062 | # 1063 | # Creates an Arduino firmware target. 1064 | # 1065 | #=============================================================================# 1066 | function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL) 1067 | 1068 | add_executable(${TARGET_NAME} ${ALL_SRCS}) 1069 | set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".elf") 1070 | 1071 | get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} ${MANUAL}) 1072 | 1073 | set_target_properties(${TARGET_NAME} PROPERTIES 1074 | COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" 1075 | LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") 1076 | target_link_libraries(${TARGET_NAME} ${ALL_LIBS} "-lc -lm") 1077 | 1078 | if(NOT EXECUTABLE_OUTPUT_PATH) 1079 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) 1080 | endif() 1081 | set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) 1082 | add_custom_command(TARGET ${TARGET_NAME} POST_BUILD 1083 | COMMAND ${CMAKE_OBJCOPY} 1084 | ARGS ${ARDUINO_OBJCOPY_EEP_FLAGS} 1085 | ${TARGET_PATH}.elf 1086 | ${TARGET_PATH}.eep 1087 | COMMENT "Generating EEP image" 1088 | VERBATIM) 1089 | 1090 | # Convert firmware image to ASCII HEX format 1091 | add_custom_command(TARGET ${TARGET_NAME} POST_BUILD 1092 | COMMAND ${CMAKE_OBJCOPY} 1093 | ARGS ${ARDUINO_OBJCOPY_HEX_FLAGS} 1094 | ${TARGET_PATH}.elf 1095 | ${TARGET_PATH}.hex 1096 | COMMENT "Generating HEX image" 1097 | VERBATIM) 1098 | 1099 | # Display target size 1100 | add_custom_command(TARGET ${TARGET_NAME} POST_BUILD 1101 | COMMAND ${CMAKE_COMMAND} 1102 | ARGS -DFIRMWARE_IMAGE=${TARGET_PATH}.elf 1103 | -DMCU=${${BOARD_ID}.build.mcu} 1104 | -DEEPROM_IMAGE=${TARGET_PATH}.eep 1105 | -P ${ARDUINO_SIZE_SCRIPT} 1106 | COMMENT "Calculating image size" 1107 | VERBATIM) 1108 | 1109 | # Create ${TARGET_NAME}-size target 1110 | add_custom_target(${TARGET_NAME}-size 1111 | COMMAND ${CMAKE_COMMAND} 1112 | -DFIRMWARE_IMAGE=${TARGET_PATH}.elf 1113 | -DMCU=${${BOARD_ID}.build.mcu} 1114 | -DEEPROM_IMAGE=${TARGET_PATH}.eep 1115 | -P ${ARDUINO_SIZE_SCRIPT} 1116 | DEPENDS ${TARGET_NAME} 1117 | COMMENT "Calculating ${TARGET_NAME} image size") 1118 | 1119 | endfunction() 1120 | 1121 | #=============================================================================# 1122 | # [PRIVATE/INTERNAL] 1123 | # 1124 | # setup_arduino_upload(BOARD_ID TARGET_NAME PORT) 1125 | # 1126 | # BOARD_ID - Arduino board id 1127 | # TARGET_NAME - Target name 1128 | # PORT - Serial port for upload 1129 | # PROGRAMMER_ID - Programmer ID 1130 | # AVRDUDE_FLAGS - avrdude flags 1131 | # 1132 | # Create an upload target (${TARGET_NAME}-upload) for the specified Arduino target. 1133 | # 1134 | #=============================================================================# 1135 | function(setup_arduino_upload BOARD_ID TARGET_NAME PORT PROGRAMMER_ID AVRDUDE_FLAGS) 1136 | setup_arduino_bootloader_upload(${TARGET_NAME} ${BOARD_ID} ${PORT} "${AVRDUDE_FLAGS}") 1137 | 1138 | # Add programmer support if defined 1139 | if(PROGRAMMER_ID AND ${PROGRAMMER_ID}.protocol) 1140 | setup_arduino_programmer_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") 1141 | setup_arduino_bootloader_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") 1142 | endif() 1143 | endfunction() 1144 | 1145 | 1146 | #=============================================================================# 1147 | # [PRIVATE/INTERNAL] 1148 | # 1149 | # setup_arduino_bootloader_upload(TARGET_NAME BOARD_ID PORT) 1150 | # 1151 | # TARGET_NAME - target name 1152 | # BOARD_ID - board id 1153 | # PORT - serial port 1154 | # AVRDUDE_FLAGS - avrdude flags (override) 1155 | # 1156 | # Set up target for upload firmware via the bootloader. 1157 | # 1158 | # The target for uploading the firmware is ${TARGET_NAME}-upload . 1159 | # 1160 | #=============================================================================# 1161 | function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS) 1162 | set(UPLOAD_TARGET ${TARGET_NAME}-upload) 1163 | set(AVRDUDE_ARGS) 1164 | 1165 | setup_arduino_bootloader_args(${BOARD_ID} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) 1166 | 1167 | if(NOT AVRDUDE_ARGS) 1168 | message("Could not generate default avrdude bootloader args, aborting!") 1169 | return() 1170 | endif() 1171 | 1172 | if(NOT EXECUTABLE_OUTPUT_PATH) 1173 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) 1174 | endif() 1175 | set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) 1176 | 1177 | list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex") 1178 | list(APPEND AVRDUDE_ARGS "-Ueeprom:w:${TARGET_PATH}.eep:i") 1179 | add_custom_target(${UPLOAD_TARGET} 1180 | ${ARDUINO_AVRDUDE_PROGRAM} 1181 | ${AVRDUDE_ARGS} 1182 | DEPENDS ${TARGET_NAME}) 1183 | 1184 | # Global upload target 1185 | if(NOT TARGET upload) 1186 | add_custom_target(upload) 1187 | endif() 1188 | 1189 | add_dependencies(upload ${UPLOAD_TARGET}) 1190 | endfunction() 1191 | 1192 | #=============================================================================# 1193 | # [PRIVATE/INTERNAL] 1194 | # 1195 | # setup_arduino_programmer_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) 1196 | # 1197 | # TARGET_NAME - name of target to burn 1198 | # BOARD_ID - board id 1199 | # PROGRAMMER - programmer id 1200 | # PORT - serial port 1201 | # AVRDUDE_FLAGS - avrdude flags (override) 1202 | # 1203 | # Sets up target for burning firmware via a programmer. 1204 | # 1205 | # The target for burning the firmware is ${TARGET_NAME}-burn . 1206 | # 1207 | #=============================================================================# 1208 | function(setup_arduino_programmer_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) 1209 | set(PROGRAMMER_TARGET ${TARGET_NAME}-burn) 1210 | 1211 | set(AVRDUDE_ARGS) 1212 | 1213 | setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) 1214 | 1215 | if(NOT AVRDUDE_ARGS) 1216 | message("Could not generate default avrdude programmer args, aborting!") 1217 | return() 1218 | endif() 1219 | 1220 | if(NOT EXECUTABLE_OUTPUT_PATH) 1221 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) 1222 | endif() 1223 | set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) 1224 | 1225 | list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex") 1226 | 1227 | add_custom_target(${PROGRAMMER_TARGET} 1228 | ${ARDUINO_AVRDUDE_PROGRAM} 1229 | ${AVRDUDE_ARGS} 1230 | DEPENDS ${TARGET_NAME}) 1231 | endfunction() 1232 | 1233 | #=============================================================================# 1234 | # [PRIVATE/INTERNAL] 1235 | # 1236 | # setup_arduino_bootloader_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) 1237 | # 1238 | # TARGET_NAME - name of target to burn 1239 | # BOARD_ID - board id 1240 | # PROGRAMMER - programmer id 1241 | # PORT - serial port 1242 | # AVRDUDE_FLAGS - avrdude flags (override) 1243 | # 1244 | # Create a target for burning a bootloader via a programmer. 1245 | # 1246 | # The target for burning the bootloader is ${TARGET_NAME}-burn-bootloader 1247 | # 1248 | #=============================================================================# 1249 | function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) 1250 | set(BOOTLOADER_TARGET ${TARGET_NAME}-burn-bootloader) 1251 | 1252 | set(AVRDUDE_ARGS) 1253 | 1254 | setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) 1255 | 1256 | if(NOT AVRDUDE_ARGS) 1257 | message("Could not generate default avrdude programmer args, aborting!") 1258 | return() 1259 | endif() 1260 | 1261 | foreach( ITEM unlock_bits high_fuses low_fuses path file) 1262 | if(NOT ${BOARD_ID}.bootloader.${ITEM}) 1263 | message("Missing ${BOARD_ID}.bootloader.${ITEM}, not creating bootloader burn target ${BOOTLOADER_TARGET}.") 1264 | return() 1265 | endif() 1266 | endforeach() 1267 | 1268 | if(NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") 1269 | message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") 1270 | message("Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.") 1271 | return() 1272 | endif() 1273 | 1274 | # Erase the chip 1275 | list(APPEND AVRDUDE_ARGS "-e") 1276 | 1277 | # Set unlock bits and fuses (because chip is going to be erased) 1278 | list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.unlock_bits}:m") 1279 | if(${BOARD_ID}.bootloader.extended_fuses) 1280 | list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}.bootloader.extended_fuses}:m") 1281 | endif() 1282 | list(APPEND AVRDUDE_ARGS 1283 | "-Uhfuse:w:${${BOARD_ID}.bootloader.high_fuses}:m" 1284 | "-Ulfuse:w:${${BOARD_ID}.bootloader.low_fuses}:m") 1285 | 1286 | # Set bootloader image 1287 | list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}.bootloader.file}:i") 1288 | 1289 | # Set lockbits 1290 | list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.lock_bits}:m") 1291 | 1292 | # Create burn bootloader target 1293 | add_custom_target(${BOOTLOADER_TARGET} 1294 | ${ARDUINO_AVRDUDE_PROGRAM} 1295 | ${AVRDUDE_ARGS} 1296 | WORKING_DIRECTORY ${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path} 1297 | DEPENDS ${TARGET_NAME}) 1298 | endfunction() 1299 | 1300 | #=============================================================================# 1301 | # [PRIVATE/INTERNAL] 1302 | # 1303 | # setup_arduino_programmer_args(BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) 1304 | # 1305 | # BOARD_ID - board id 1306 | # PROGRAMMER - programmer id 1307 | # TARGET_NAME - target name 1308 | # PORT - serial port 1309 | # AVRDUDE_FLAGS - avrdude flags (override) 1310 | # OUTPUT_VAR - name of output variable for result 1311 | # 1312 | # Sets up default avrdude settings for burning firmware via a programmer. 1313 | #=============================================================================# 1314 | function(setup_arduino_programmer_args BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) 1315 | set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) 1316 | 1317 | if(NOT AVRDUDE_FLAGS) 1318 | set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) 1319 | endif() 1320 | 1321 | list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}") 1322 | 1323 | #TODO: Check mandatory settings before continuing 1324 | if(NOT ${PROGRAMMER}.protocol) 1325 | message(FATAL_ERROR "Missing ${PROGRAMMER}.protocol, aborting!") 1326 | endif() 1327 | 1328 | list(APPEND AVRDUDE_ARGS "-c${${PROGRAMMER}.protocol}") # Set programmer 1329 | 1330 | if(${PROGRAMMER}.communication STREQUAL "usb") 1331 | list(APPEND AVRDUDE_ARGS "-Pusb") # Set USB as port 1332 | elseif(${PROGRAMMER}.communication STREQUAL "serial") 1333 | list(APPEND AVRDUDE_ARGS "-P${PORT}") # Set port 1334 | if(${PROGRAMMER}.speed) 1335 | list(APPEND AVRDUDE_ARGS "-b${${PROGRAMMER}.speed}") # Set baud rate 1336 | endif() 1337 | endif() 1338 | 1339 | if(${PROGRAMMER}.force) 1340 | list(APPEND AVRDUDE_ARGS "-F") # Set force 1341 | endif() 1342 | 1343 | if(${PROGRAMMER}.delay) 1344 | list(APPEND AVRDUDE_ARGS "-i${${PROGRAMMER}.delay}") # Set delay 1345 | endif() 1346 | 1347 | list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}.build.mcu}") # MCU Type 1348 | 1349 | list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) 1350 | 1351 | set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) 1352 | endfunction() 1353 | 1354 | #=============================================================================# 1355 | # [PRIVATE/INTERNAL] 1356 | # 1357 | # setup_arduino_bootloader_args(BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) 1358 | # 1359 | # BOARD_ID - board id 1360 | # TARGET_NAME - target name 1361 | # PORT - serial port 1362 | # AVRDUDE_FLAGS - avrdude flags (override) 1363 | # OUTPUT_VAR - name of output variable for result 1364 | # 1365 | # Sets up default avrdude settings for uploading firmware via the bootloader. 1366 | #=============================================================================# 1367 | function(setup_arduino_bootloader_args BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) 1368 | set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) 1369 | 1370 | if(NOT AVRDUDE_FLAGS) 1371 | set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) 1372 | endif() 1373 | 1374 | list(APPEND AVRDUDE_ARGS 1375 | "-C${ARDUINO_AVRDUDE_CONFIG_PATH}" # avrdude config 1376 | "-p${${BOARD_ID}.build.mcu}" # MCU Type 1377 | ) 1378 | 1379 | # Programmer 1380 | if(NOT ${BOARD_ID}.upload.protocol OR ${BOARD_ID}.upload.protocol STREQUAL "stk500") 1381 | list(APPEND AVRDUDE_ARGS "-cstk500v1") 1382 | else() 1383 | list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}.upload.protocol}") 1384 | endif() 1385 | 1386 | set(UPLOAD_SPEED "19200") 1387 | if(${BOARD_ID}.upload.speed) 1388 | set(UPLOAD_SPEED ${${BOARD_ID}.upload.speed}) 1389 | endif() 1390 | 1391 | list(APPEND AVRDUDE_ARGS 1392 | "-b${UPLOAD_SPEED}" # Baud rate 1393 | "-P${PORT}" # Serial port 1394 | "-D" # Dont erase 1395 | ) 1396 | 1397 | list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) 1398 | 1399 | set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) 1400 | endfunction() 1401 | 1402 | #=============================================================================# 1403 | # [PRIVATE/INTERNAL] 1404 | # 1405 | # find_sources(VAR_NAME LIB_PATH RECURSE) 1406 | # 1407 | # VAR_NAME - Variable name that will hold the detected sources 1408 | # LIB_PATH - The base path 1409 | # RECURSE - Whether or not to recurse 1410 | # 1411 | # Finds all C/C++ sources located at the specified path. 1412 | # 1413 | #=============================================================================# 1414 | function(find_sources VAR_NAME LIB_PATH RECURSE) 1415 | set(FILE_SEARCH_LIST 1416 | ${LIB_PATH}/*.cpp 1417 | ${LIB_PATH}/*.c 1418 | ${LIB_PATH}/*.cc 1419 | ${LIB_PATH}/*.cxx 1420 | ${LIB_PATH}/*.h 1421 | ${LIB_PATH}/*.hh 1422 | ${LIB_PATH}/*.hxx) 1423 | 1424 | if(RECURSE) 1425 | file(GLOB_RECURSE LIB_FILES ${FILE_SEARCH_LIST}) 1426 | else() 1427 | file(GLOB LIB_FILES ${FILE_SEARCH_LIST}) 1428 | endif() 1429 | 1430 | if(LIB_FILES) 1431 | set(${VAR_NAME} ${LIB_FILES} PARENT_SCOPE) 1432 | endif() 1433 | endfunction() 1434 | 1435 | #=============================================================================# 1436 | # [PRIVATE/INTERNAL] 1437 | # 1438 | # setup_serial_target(TARGET_NAME CMD) 1439 | # 1440 | # TARGET_NAME - Target name 1441 | # CMD - Serial terminal command 1442 | # 1443 | # Creates a target (${TARGET_NAME}-serial) for launching the serial termnial. 1444 | # 1445 | #=============================================================================# 1446 | function(setup_serial_target TARGET_NAME CMD SERIAL_PORT) 1447 | string(CONFIGURE "${CMD}" FULL_CMD @ONLY) 1448 | add_custom_target(${TARGET_NAME}-serial 1449 | COMMAND ${FULL_CMD}) 1450 | endfunction() 1451 | 1452 | 1453 | #=============================================================================# 1454 | # [PRIVATE/INTERNAL] 1455 | # 1456 | # detect_arduino_version(VAR_NAME) 1457 | # 1458 | # VAR_NAME - Variable name where the detected version will be saved 1459 | # 1460 | # Detects the Arduino SDK Version based on the revisions.txt file. The 1461 | # following variables will be generated: 1462 | # 1463 | # ${VAR_NAME} -> the full version (major.minor.patch) 1464 | # ${VAR_NAME}_MAJOR -> the major version 1465 | # ${VAR_NAME}_MINOR -> the minor version 1466 | # ${VAR_NAME}_PATCH -> the patch version 1467 | # 1468 | #=============================================================================# 1469 | function(detect_arduino_version VAR_NAME) 1470 | if(ARDUINO_VERSION_PATH) 1471 | file(READ ${ARDUINO_VERSION_PATH} RAW_VERSION) 1472 | if("${RAW_VERSION}" MATCHES " *[0]+([0-9]+)") 1473 | set(PARSED_VERSION 0.${CMAKE_MATCH_1}.0) 1474 | elseif("${RAW_VERSION}" MATCHES "[ ]*([0-9]+[.][0-9]+[.][0-9]+)") 1475 | set(PARSED_VERSION ${CMAKE_MATCH_1}) 1476 | elseif("${RAW_VERSION}" MATCHES "[ ]*([0-9]+[.][0-9]+)") 1477 | set(PARSED_VERSION ${CMAKE_MATCH_1}.0) 1478 | endif() 1479 | 1480 | if(NOT PARSED_VERSION STREQUAL "") 1481 | string(REPLACE "." ";" SPLIT_VERSION ${PARSED_VERSION}) 1482 | list(GET SPLIT_VERSION 0 SPLIT_VERSION_MAJOR) 1483 | list(GET SPLIT_VERSION 1 SPLIT_VERSION_MINOR) 1484 | list(GET SPLIT_VERSION 2 SPLIT_VERSION_PATCH) 1485 | 1486 | set(${VAR_NAME} "${PARSED_VERSION}" PARENT_SCOPE) 1487 | set(${VAR_NAME}_MAJOR "${SPLIT_VERSION_MAJOR}" PARENT_SCOPE) 1488 | set(${VAR_NAME}_MINOR "${SPLIT_VERSION_MINOR}" PARENT_SCOPE) 1489 | set(${VAR_NAME}_PATCH "${SPLIT_VERSION_PATCH}" PARENT_SCOPE) 1490 | endif() 1491 | endif() 1492 | endfunction() 1493 | 1494 | 1495 | #=============================================================================# 1496 | # [PRIVATE/INTERNAL] 1497 | # 1498 | # load_arduino_style_settings(SETTINGS_LIST SETTINGS_PATH) 1499 | # 1500 | # SETTINGS_LIST - Variable name of settings list 1501 | # SETTINGS_PATH - File path of settings file to load. 1502 | # 1503 | # Load a Arduino style settings file into the cache. 1504 | # 1505 | # Examples of this type of settings file is the boards.txt and 1506 | # programmers.txt files located in ${ARDUINO_SDK}/hardware/arduino. 1507 | # 1508 | # Settings have to following format: 1509 | # 1510 | # entry.setting[.subsetting] = value 1511 | # 1512 | # where [.subsetting] is optional 1513 | # 1514 | # For example, the following settings: 1515 | # 1516 | # uno.name=Arduino Uno 1517 | # uno.upload.protocol=stk500 1518 | # uno.upload.maximum_size=32256 1519 | # uno.build.mcu=atmega328p 1520 | # uno.build.core=arduino 1521 | # 1522 | # will generate the follwoing equivalent CMake variables: 1523 | # 1524 | # set(uno.name "Arduino Uno") 1525 | # set(uno.upload.protocol "stk500") 1526 | # set(uno.upload.maximum_size "32256") 1527 | # set(uno.build.mcu "atmega328p") 1528 | # set(uno.build.core "arduino") 1529 | # 1530 | # set(uno.SETTINGS name upload build) # List of settings for uno 1531 | # set(uno.upload.SUBSETTINGS protocol maximum_size) # List of sub-settings for uno.upload 1532 | # set(uno.build.SUBSETTINGS mcu core) # List of sub-settings for uno.build 1533 | # 1534 | # The ${ENTRY_NAME}.SETTINGS variable lists all settings for the entry, while 1535 | # ${ENTRY_NAME}.SUBSETTINGS variables lists all settings for a sub-setting of 1536 | # a entry setting pair. 1537 | # 1538 | # These variables are generated in order to be able to programatically traverse 1539 | # all settings (for a example see print_board_settings() function). 1540 | # 1541 | #=============================================================================# 1542 | function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH) 1543 | 1544 | if(NOT ${SETTINGS_LIST} AND EXISTS ${SETTINGS_PATH}) 1545 | file(STRINGS ${SETTINGS_PATH} FILE_ENTRIES) # Settings file split into lines 1546 | 1547 | foreach(FILE_ENTRY ${FILE_ENTRIES}) 1548 | if("${FILE_ENTRY}" MATCHES "^[^#]+=.*") 1549 | string(REGEX MATCH "^[^=]+" SETTING_NAME ${FILE_ENTRY}) 1550 | string(REGEX MATCH "[^=]+$" SETTING_VALUE ${FILE_ENTRY}) 1551 | string(REPLACE "." ";" ENTRY_NAME_TOKENS ${SETTING_NAME}) 1552 | string(STRIP "${SETTING_VALUE}" SETTING_VALUE) 1553 | 1554 | list(LENGTH ENTRY_NAME_TOKENS ENTRY_NAME_TOKENS_LEN) 1555 | 1556 | # Add entry to settings list if it does not exist 1557 | list(GET ENTRY_NAME_TOKENS 0 ENTRY_NAME) 1558 | list(FIND ${SETTINGS_LIST} ${ENTRY_NAME} ENTRY_NAME_INDEX) 1559 | if(ENTRY_NAME_INDEX LESS 0) 1560 | # Add entry to main list 1561 | list(APPEND ${SETTINGS_LIST} ${ENTRY_NAME}) 1562 | endif() 1563 | 1564 | # Add entry setting to entry settings list if it does not exist 1565 | set(ENTRY_SETTING_LIST ${ENTRY_NAME}.SETTINGS) 1566 | list(GET ENTRY_NAME_TOKENS 1 ENTRY_SETTING) 1567 | list(FIND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING} ENTRY_SETTING_INDEX) 1568 | if(ENTRY_SETTING_INDEX LESS 0) 1569 | # Add setting to entry 1570 | list(APPEND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING}) 1571 | set(${ENTRY_SETTING_LIST} ${${ENTRY_SETTING_LIST}} 1572 | CACHE INTERNAL "Arduino ${ENTRY_NAME} Board settings list") 1573 | endif() 1574 | 1575 | set(FULL_SETTING_NAME ${ENTRY_NAME}.${ENTRY_SETTING}) 1576 | 1577 | # Add entry sub-setting to entry sub-settings list if it does not exists 1578 | if(ENTRY_NAME_TOKENS_LEN GREATER 2) 1579 | set(ENTRY_SUBSETTING_LIST ${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) 1580 | list(GET ENTRY_NAME_TOKENS 2 ENTRY_SUBSETTING) 1581 | list(FIND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING} ENTRY_SUBSETTING_INDEX) 1582 | if(ENTRY_SUBSETTING_INDEX LESS 0) 1583 | list(APPEND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING}) 1584 | set(${ENTRY_SUBSETTING_LIST} ${${ENTRY_SUBSETTING_LIST}} 1585 | CACHE INTERNAL "Arduino ${ENTRY_NAME} Board sub-settings list") 1586 | endif() 1587 | set(FULL_SETTING_NAME ${FULL_SETTING_NAME}.${ENTRY_SUBSETTING}) 1588 | endif() 1589 | 1590 | # Save setting value 1591 | set(${FULL_SETTING_NAME} ${SETTING_VALUE} 1592 | CACHE INTERNAL "Arduino ${ENTRY_NAME} Board setting") 1593 | 1594 | 1595 | endif() 1596 | endforeach() 1597 | set(${SETTINGS_LIST} ${${SETTINGS_LIST}} 1598 | CACHE STRING "List of detected Arduino Board configurations") 1599 | mark_as_advanced(${SETTINGS_LIST}) 1600 | endif() 1601 | endfunction() 1602 | 1603 | #=============================================================================# 1604 | # print_settings(ENTRY_NAME) 1605 | # 1606 | # ENTRY_NAME - name of entry 1607 | # 1608 | # Print the entry settings (see load_arduino_syle_settings()). 1609 | # 1610 | #=============================================================================# 1611 | function(PRINT_SETTINGS ENTRY_NAME) 1612 | if(${ENTRY_NAME}.SETTINGS) 1613 | 1614 | foreach(ENTRY_SETTING ${${ENTRY_NAME}.SETTINGS}) 1615 | if(${ENTRY_NAME}.${ENTRY_SETTING}) 1616 | message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}}") 1617 | endif() 1618 | if(${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) 1619 | foreach(ENTRY_SUBSETTING ${${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS}) 1620 | if(${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}) 1621 | message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}}") 1622 | endif() 1623 | endforeach() 1624 | endif() 1625 | message(STATUS "") 1626 | endforeach() 1627 | endif() 1628 | endfunction() 1629 | 1630 | #=============================================================================# 1631 | # [PRIVATE/INTERNAL] 1632 | # 1633 | # print_list(SETTINGS_LIST) 1634 | # 1635 | # SETTINGS_LIST - Variables name of settings list 1636 | # 1637 | # Print list settings and names (see load_arduino_syle_settings()). 1638 | #=============================================================================# 1639 | function(PRINT_LIST SETTINGS_LIST) 1640 | if(${SETTINGS_LIST}) 1641 | set(MAX_LENGTH 0) 1642 | foreach(ENTRY_NAME ${${SETTINGS_LIST}}) 1643 | string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH) 1644 | if(CURRENT_LENGTH GREATER MAX_LENGTH) 1645 | set(MAX_LENGTH ${CURRENT_LENGTH}) 1646 | endif() 1647 | endforeach() 1648 | foreach(ENTRY_NAME ${${SETTINGS_LIST}}) 1649 | string(LENGTH "${ENTRY_NAME}" CURRENT_LENGTH) 1650 | math(EXPR PADDING_LENGTH "${MAX_LENGTH}-${CURRENT_LENGTH}") 1651 | set(PADDING "") 1652 | foreach(X RANGE ${PADDING_LENGTH}) 1653 | set(PADDING "${PADDING} ") 1654 | endforeach() 1655 | message(STATUS " ${PADDING}${ENTRY_NAME}: ${${ENTRY_NAME}.name}") 1656 | endforeach() 1657 | endif() 1658 | endfunction() 1659 | 1660 | #=============================================================================# 1661 | # [PRIVATE/INTERNAL] 1662 | # 1663 | # setup_arduino_example(TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) 1664 | # 1665 | # TARGET_NAME - Target name 1666 | # LIBRARY_NAME - Library name 1667 | # EXAMPLE_NAME - Example name 1668 | # OUTPUT_VAR - Variable name to save sketch path. 1669 | # 1670 | # Creates a Arduino example from a the specified library. 1671 | #=============================================================================# 1672 | function(SETUP_ARDUINO_EXAMPLE TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) 1673 | set(EXAMPLE_SKETCH_PATH ) 1674 | 1675 | get_property(LIBRARY_SEARCH_PATH 1676 | DIRECTORY # Property Scope 1677 | PROPERTY LINK_DIRECTORIES) 1678 | foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries) 1679 | if(EXISTS "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") 1680 | set(EXAMPLE_SKETCH_PATH "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") 1681 | break() 1682 | endif() 1683 | endforeach() 1684 | 1685 | if(EXAMPLE_SKETCH_PATH) 1686 | setup_arduino_sketch(${TARGET_NAME} ${EXAMPLE_SKETCH_PATH} SKETCH_CPP) 1687 | set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) 1688 | else() 1689 | message(FATAL_ERROR "Could not find example ${EXAMPLE_NAME} from library ${LIBRARY_NAME}") 1690 | endif() 1691 | endfunction() 1692 | 1693 | #=============================================================================# 1694 | # [PRIVATE/INTERNAL] 1695 | # 1696 | # setup_arduino_sketch(TARGET_NAME SKETCH_PATH OUTPUT_VAR) 1697 | # 1698 | # TARGET_NAME - Target name 1699 | # SKETCH_PATH - Path to sketch directory 1700 | # OUTPUT_VAR - Variable name where to save generated sketch source 1701 | # 1702 | # Generates C++ sources from Arduino Sketch. 1703 | #=============================================================================# 1704 | function(SETUP_ARDUINO_SKETCH TARGET_NAME SKETCH_PATH OUTPUT_VAR) 1705 | get_filename_component(SKETCH_NAME "${SKETCH_PATH}" NAME) 1706 | get_filename_component(SKETCH_PATH "${SKETCH_PATH}" ABSOLUTE) 1707 | 1708 | if(EXISTS "${SKETCH_PATH}") 1709 | set(SKETCH_CPP ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_${SKETCH_NAME}.cpp) 1710 | 1711 | if (IS_DIRECTORY "${SKETCH_PATH}") 1712 | # Sketch directory specified, try to find main sketch... 1713 | set(MAIN_SKETCH ${SKETCH_PATH}/${SKETCH_NAME}) 1714 | 1715 | if(EXISTS "${MAIN_SKETCH}.pde") 1716 | set(MAIN_SKETCH "${MAIN_SKETCH}.pde") 1717 | elseif(EXISTS "${MAIN_SKETCH}.ino") 1718 | set(MAIN_SKETCH "${MAIN_SKETCH}.ino") 1719 | else() 1720 | message(FATAL_ERROR "Could not find main sketch (${SKETCH_NAME}.pde or ${SKETCH_NAME}.ino) at ${SKETCH_PATH}! Please specify the main sketch file path instead of directory.") 1721 | endif() 1722 | else() 1723 | # Sektch file specified, assuming parent directory as sketch directory 1724 | set(MAIN_SKETCH ${SKETCH_PATH}) 1725 | get_filename_component(SKETCH_PATH "${SKETCH_PATH}" PATH) 1726 | endif() 1727 | arduino_debug_msg("sketch: ${MAIN_SKETCH}") 1728 | 1729 | # Find all sketch files 1730 | file(GLOB SKETCH_SOURCES ${SKETCH_PATH}/*.pde ${SKETCH_PATH}/*.ino) 1731 | list(REMOVE_ITEM SKETCH_SOURCES ${MAIN_SKETCH}) 1732 | list(SORT SKETCH_SOURCES) 1733 | 1734 | generate_cpp_from_sketch("${MAIN_SKETCH}" "${SKETCH_SOURCES}" "${SKETCH_CPP}") 1735 | 1736 | # Regenerate build system if sketch changes 1737 | add_custom_command(OUTPUT ${SKETCH_CPP} 1738 | COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} 1739 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 1740 | DEPENDS ${MAIN_SKETCH} ${SKETCH_SOURCES} 1741 | COMMENT "Regnerating ${SKETCH_NAME} Sketch") 1742 | set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED TRUE) 1743 | # Mark file that it exists for find_file 1744 | set_source_files_properties(${SKETCH_CPP} PROPERTIES GENERATED_SKETCH TRUE) 1745 | 1746 | set("${OUTPUT_VAR}" ${${OUTPUT_VAR}} ${SKETCH_CPP} PARENT_SCOPE) 1747 | else() 1748 | message(FATAL_ERROR "Sketch does not exist: ${SKETCH_PATH}") 1749 | endif() 1750 | endfunction() 1751 | 1752 | 1753 | #=============================================================================# 1754 | # [PRIVATE/INTERNAL] 1755 | # 1756 | # generate_cpp_from_sketch(MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) 1757 | # 1758 | # MAIN_SKETCH_PATH - Main sketch file path 1759 | # SKETCH_SOURCES - Setch source paths 1760 | # SKETCH_CPP - Name of file to generate 1761 | # 1762 | # Generate C++ source file from Arduino sketch files. 1763 | #=============================================================================# 1764 | function(GENERATE_CPP_FROM_SKETCH MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) 1765 | file(WRITE ${SKETCH_CPP} "// automatically generated by arduino-cmake\n") 1766 | file(READ ${MAIN_SKETCH_PATH} MAIN_SKETCH) 1767 | 1768 | # remove comments 1769 | remove_comments(MAIN_SKETCH MAIN_SKETCH_NO_COMMENTS) 1770 | 1771 | # find first statement 1772 | string(REGEX MATCH "[\n][_a-zA-Z0-9]+[^\n]*" FIRST_STATEMENT "${MAIN_SKETCH_NO_COMMENTS}") 1773 | string(FIND "${MAIN_SKETCH}" "${FIRST_STATEMENT}" HEAD_LENGTH) 1774 | if ("${HEAD_LENGTH}" STREQUAL "-1") 1775 | set(HEAD_LENGTH 0) 1776 | endif() 1777 | #message(STATUS "FIRST STATEMENT: ${FIRST_STATEMENT}") 1778 | #message(STATUS "FIRST STATEMENT POSITION: ${HEAD_LENGTH}") 1779 | string(LENGTH "${MAIN_SKETCH}" MAIN_SKETCH_LENGTH) 1780 | 1781 | string(SUBSTRING "${MAIN_SKETCH}" 0 ${HEAD_LENGTH} SKETCH_HEAD) 1782 | #arduino_debug_msg("SKETCH_HEAD:\n${SKETCH_HEAD}") 1783 | 1784 | # find the body of the main pde 1785 | math(EXPR BODY_LENGTH "${MAIN_SKETCH_LENGTH}-${HEAD_LENGTH}") 1786 | string(SUBSTRING "${MAIN_SKETCH}" "${HEAD_LENGTH}+1" "${BODY_LENGTH}-1" SKETCH_BODY) 1787 | #arduino_debug_msg("BODY:\n${SKETCH_BODY}") 1788 | 1789 | # write the file head 1790 | file(APPEND ${SKETCH_CPP} "#line 1 \"${MAIN_SKETCH_PATH}\"\n${SKETCH_HEAD}") 1791 | 1792 | # Count head line offset (for GCC error reporting) 1793 | file(STRINGS ${SKETCH_CPP} SKETCH_HEAD_LINES) 1794 | list(LENGTH SKETCH_HEAD_LINES SKETCH_HEAD_LINES_COUNT) 1795 | math(EXPR SKETCH_HEAD_OFFSET "${SKETCH_HEAD_LINES_COUNT}+2") 1796 | 1797 | # add arduino include header 1798 | #file(APPEND ${SKETCH_CPP} "\n#line 1 \"autogenerated\"\n") 1799 | file(APPEND ${SKETCH_CPP} "\n#line ${SKETCH_HEAD_OFFSET} \"${SKETCH_CPP}\"\n") 1800 | if(ARDUINO_SDK_VERSION VERSION_LESS 1.0) 1801 | file(APPEND ${SKETCH_CPP} "#include \"WProgram.h\"\n") 1802 | else() 1803 | file(APPEND ${SKETCH_CPP} "#include \"Arduino.h\"\n") 1804 | endif() 1805 | 1806 | # add function prototypes 1807 | foreach(SKETCH_SOURCE_PATH ${SKETCH_SOURCES} ${MAIN_SKETCH_PATH}) 1808 | arduino_debug_msg("Sketch: ${SKETCH_SOURCE_PATH}") 1809 | file(READ ${SKETCH_SOURCE_PATH} SKETCH_SOURCE) 1810 | remove_comments(SKETCH_SOURCE SKETCH_SOURCE) 1811 | 1812 | set(ALPHA "a-zA-Z") 1813 | set(NUM "0-9") 1814 | set(ALPHANUM "${ALPHA}${NUM}") 1815 | set(WORD "_${ALPHANUM}") 1816 | set(LINE_START "(^|[\n])") 1817 | set(QUALIFIERS "[ \t]*([${ALPHA}]+[ ])*") 1818 | set(TYPE "[${WORD}]+([ ]*[\n][\t]*|[ ])+") 1819 | set(FNAME "[${WORD}]+[ ]?[\n]?[\t]*[ ]*") 1820 | set(FARGS "[(]([\t]*[ ]*[*&]?[ ]?[${WORD}](\\[([${NUM}]+)?\\])*[,]?[ ]*[\n]?)*([,]?[ ]*[\n]?)?[)]") 1821 | set(BODY_START "([ ]*[\n][\t]*|[ ]|[\n])*{") 1822 | set(PROTOTYPE_PATTERN "${LINE_START}${QUALIFIERS}${TYPE}${FNAME}${FARGS}${BODY_START}") 1823 | 1824 | string(REGEX MATCHALL "${PROTOTYPE_PATTERN}" SKETCH_PROTOTYPES "${SKETCH_SOURCE}") 1825 | 1826 | # Write function prototypes 1827 | file(APPEND ${SKETCH_CPP} "\n//=== START Forward: ${SKETCH_SOURCE_PATH}\n") 1828 | foreach(SKETCH_PROTOTYPE ${SKETCH_PROTOTYPES}) 1829 | string(REPLACE "\n" " " SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}") 1830 | string(REPLACE "{" "" SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}") 1831 | arduino_debug_msg("\tprototype: ${SKETCH_PROTOTYPE};") 1832 | # " else if(var == other) {" shoudn't be listed as prototype 1833 | if(NOT SKETCH_PROTOTYPE MATCHES "(if[ ]?[\n]?[\t]*[ ]*[)])") 1834 | file(APPEND ${SKETCH_CPP} "${SKETCH_PROTOTYPE};\n") 1835 | else() 1836 | arduino_debug_msg("\trejected prototype: ${SKETCH_PROTOTYPE};") 1837 | endif() 1838 | file(APPEND ${SKETCH_CPP} "${SKETCH_PROTOTYPE};\n") 1839 | endforeach() 1840 | file(APPEND ${SKETCH_CPP} "//=== END Forward: ${SKETCH_SOURCE_PATH}\n") 1841 | endforeach() 1842 | 1843 | # Write Sketch CPP source 1844 | get_num_lines("${SKETCH_HEAD}" HEAD_NUM_LINES) 1845 | file(APPEND ${SKETCH_CPP} "#line ${HEAD_NUM_LINES} \"${MAIN_SKETCH_PATH}\"\n") 1846 | file(APPEND ${SKETCH_CPP} "\n${SKETCH_BODY}") 1847 | foreach (SKETCH_SOURCE_PATH ${SKETCH_SOURCES}) 1848 | file(READ ${SKETCH_SOURCE_PATH} SKETCH_SOURCE) 1849 | file(APPEND ${SKETCH_CPP} "\n//=== START : ${SKETCH_SOURCE_PATH}\n") 1850 | file(APPEND ${SKETCH_CPP} "#line 1 \"${SKETCH_SOURCE_PATH}\"\n") 1851 | file(APPEND ${SKETCH_CPP} "${SKETCH_SOURCE}") 1852 | file(APPEND ${SKETCH_CPP} "\n//=== END : ${SKETCH_SOURCE_PATH}\n") 1853 | endforeach() 1854 | endfunction() 1855 | 1856 | #=============================================================================# 1857 | # [PRIVATE/INTERNAL] 1858 | # 1859 | # setup_arduino_size_script(OUTPUT_VAR) 1860 | # 1861 | # OUTPUT_VAR - Output variable that will contain the script path 1862 | # 1863 | # Generates script used to display the firmware size. 1864 | #=============================================================================# 1865 | function(SETUP_ARDUINO_SIZE_SCRIPT OUTPUT_VAR) 1866 | set(ARDUINO_SIZE_SCRIPT_PATH ${CMAKE_BINARY_DIR}/CMakeFiles/FirmwareSize.cmake) 1867 | 1868 | file(WRITE ${ARDUINO_SIZE_SCRIPT_PATH} " 1869 | set(AVRSIZE_PROGRAM ${AVRSIZE_PROGRAM}) 1870 | set(AVRSIZE_FLAGS -C --mcu=\${MCU}) 1871 | 1872 | execute_process(COMMAND \${AVRSIZE_PROGRAM} \${AVRSIZE_FLAGS} \${FIRMWARE_IMAGE} \${EEPROM_IMAGE} 1873 | OUTPUT_VARIABLE SIZE_OUTPUT) 1874 | 1875 | 1876 | string(STRIP \"\${SIZE_OUTPUT}\" RAW_SIZE_OUTPUT) 1877 | 1878 | # Convert lines into a list 1879 | string(REPLACE \"\\n\" \";\" SIZE_OUTPUT_LIST \"\${SIZE_OUTPUT}\") 1880 | 1881 | set(SIZE_OUTPUT_LINES) 1882 | foreach(LINE \${SIZE_OUTPUT_LIST}) 1883 | if(NOT \"\${LINE}\" STREQUAL \"\") 1884 | list(APPEND SIZE_OUTPUT_LINES \"\${LINE}\") 1885 | endif() 1886 | endforeach() 1887 | 1888 | function(EXTRACT LIST_NAME INDEX VARIABLE) 1889 | list(GET \"\${LIST_NAME}\" \${INDEX} RAW_VALUE) 1890 | string(STRIP \"\${RAW_VALUE}\" VALUE) 1891 | 1892 | set(\${VARIABLE} \"\${VALUE}\" PARENT_SCOPE) 1893 | endfunction() 1894 | function(PARSE INPUT VARIABLE_PREFIX) 1895 | if(\${INPUT} MATCHES \"([^:]+):[ \\t]*([0-9]+)[ \\t]*([^ \\t]+)[ \\t]*[(]([0-9.]+)%.*\") 1896 | set(ENTRY_NAME \${CMAKE_MATCH_1}) 1897 | set(ENTRY_SIZE \${CMAKE_MATCH_2}) 1898 | set(ENTRY_SIZE_TYPE \${CMAKE_MATCH_3}) 1899 | set(ENTRY_PERCENT \${CMAKE_MATCH_4}) 1900 | endif() 1901 | 1902 | set(\${VARIABLE_PREFIX}_NAME \${ENTRY_NAME} PARENT_SCOPE) 1903 | set(\${VARIABLE_PREFIX}_SIZE \${ENTRY_SIZE} PARENT_SCOPE) 1904 | set(\${VARIABLE_PREFIX}_SIZE_TYPE \${ENTRY_SIZE_TYPE} PARENT_SCOPE) 1905 | set(\${VARIABLE_PREFIX}_PERCENT \${ENTRY_PERCENT} PARENT_SCOPE) 1906 | endfunction() 1907 | 1908 | list(LENGTH SIZE_OUTPUT_LINES SIZE_OUTPUT_LENGTH) 1909 | #message(\"\${SIZE_OUTPUT_LINES}\") 1910 | #message(\"\${SIZE_OUTPUT_LENGTH}\") 1911 | if (\${SIZE_OUTPUT_LENGTH} STREQUAL 14) 1912 | EXTRACT(SIZE_OUTPUT_LINES 3 FIRMWARE_PROGRAM_SIZE_ROW) 1913 | EXTRACT(SIZE_OUTPUT_LINES 5 FIRMWARE_DATA_SIZE_ROW) 1914 | PARSE(FIRMWARE_PROGRAM_SIZE_ROW FIRMWARE_PROGRAM) 1915 | PARSE(FIRMWARE_DATA_SIZE_ROW FIRMWARE_DATA) 1916 | 1917 | set(FIRMWARE_STATUS \"Firmware Size: \") 1918 | set(FIRMWARE_STATUS \"\${FIRMWARE_STATUS} [\${FIRMWARE_PROGRAM_NAME}: \${FIRMWARE_PROGRAM_SIZE} \${FIRMWARE_PROGRAM_SIZE_TYPE} (\${FIRMWARE_PROGRAM_PERCENT}%)] \") 1919 | set(FIRMWARE_STATUS \"\${FIRMWARE_STATUS} [\${FIRMWARE_DATA_NAME}: \${FIRMWARE_DATA_SIZE} \${FIRMWARE_DATA_SIZE_TYPE} (\${FIRMWARE_DATA_PERCENT}%)]\") 1920 | set(FIRMWARE_STATUS \"\${FIRMWARE_STATUS} on \${MCU}\") 1921 | 1922 | EXTRACT(SIZE_OUTPUT_LINES 10 EEPROM_PROGRAM_SIZE_ROW) 1923 | EXTRACT(SIZE_OUTPUT_LINES 12 EEPROM_DATA_SIZE_ROW) 1924 | PARSE(EEPROM_PROGRAM_SIZE_ROW EEPROM_PROGRAM) 1925 | PARSE(EEPROM_DATA_SIZE_ROW EEPROM_DATA) 1926 | 1927 | set(EEPROM_STATUS \"EEPROM Size: \") 1928 | set(EEPROM_STATUS \"\${EEPROM_STATUS} [\${EEPROM_PROGRAM_NAME}: \${EEPROM_PROGRAM_SIZE} \${EEPROM_PROGRAM_SIZE_TYPE} (\${EEPROM_PROGRAM_PERCENT}%)] \") 1929 | set(EEPROM_STATUS \"\${EEPROM_STATUS} [\${EEPROM_DATA_NAME}: \${EEPROM_DATA_SIZE} \${EEPROM_DATA_SIZE_TYPE} (\${EEPROM_DATA_PERCENT}%)]\") 1930 | set(EEPROM_STATUS \"\${EEPROM_STATUS} on \${MCU}\") 1931 | 1932 | message(\"\${FIRMWARE_STATUS}\") 1933 | message(\"\${EEPROM_STATUS}\\n\") 1934 | 1935 | if(\$ENV{VERBOSE}) 1936 | message(\"\${RAW_SIZE_OUTPUT}\\n\") 1937 | elseif(\$ENV{VERBOSE_SIZE}) 1938 | message(\"\${RAW_SIZE_OUTPUT}\\n\") 1939 | endif() 1940 | else() 1941 | message(\"\${RAW_SIZE_OUTPUT}\") 1942 | endif() 1943 | ") 1944 | 1945 | set(${OUTPUT_VAR} ${ARDUINO_SIZE_SCRIPT_PATH} PARENT_SCOPE) 1946 | endfunction() 1947 | 1948 | 1949 | #=============================================================================# 1950 | # [PRIVATE/INTERNAL] 1951 | # 1952 | # arduino_debug_on() 1953 | # 1954 | # Enables Arduino module debugging. 1955 | #=============================================================================# 1956 | function(ARDUINO_DEBUG_ON) 1957 | set(ARDUINO_DEBUG True PARENT_SCOPE) 1958 | endfunction() 1959 | 1960 | 1961 | #=============================================================================# 1962 | # [PRIVATE/INTERNAL] 1963 | # 1964 | # arduino_debug_off() 1965 | # 1966 | # Disables Arduino module debugging. 1967 | #=============================================================================# 1968 | function(ARDUINO_DEBUG_OFF) 1969 | set(ARDUINO_DEBUG False PARENT_SCOPE) 1970 | endfunction() 1971 | 1972 | 1973 | #=============================================================================# 1974 | # [PRIVATE/INTERNAL] 1975 | # 1976 | # arduino_debug_msg(MSG) 1977 | # 1978 | # MSG - Message to print 1979 | # 1980 | # Print Arduino debugging information. In order to enable printing 1981 | # use arduino_debug_on() and to disable use arduino_debug_off(). 1982 | #=============================================================================# 1983 | function(ARDUINO_DEBUG_MSG MSG) 1984 | if(ARDUINO_DEBUG) 1985 | message("## ${MSG}") 1986 | endif() 1987 | endfunction() 1988 | 1989 | #=============================================================================# 1990 | # [PRIVATE/INTERNAL] 1991 | # 1992 | # remove_comments(SRC_VAR OUT_VAR) 1993 | # 1994 | # SRC_VAR - variable holding sources 1995 | # OUT_VAR - variable holding sources with no comments 1996 | # 1997 | # Removes all comments from the source code. 1998 | #=============================================================================# 1999 | function(REMOVE_COMMENTS SRC_VAR OUT_VAR) 2000 | string(REGEX REPLACE "[\\./\\\\]" "_" FILE "${NAME}") 2001 | 2002 | set(SRC ${${SRC_VAR}}) 2003 | 2004 | #message(STATUS "removing comments from: ${FILE}") 2005 | #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_pre_remove_comments.txt" ${SRC}) 2006 | #message(STATUS "\n${SRC}") 2007 | 2008 | # remove all comments 2009 | string(REGEX REPLACE "([/][/][^\n]*)|([/][\\*]([^\\*]|([\\*]+[^/\\*]))*[\\*]+[/])" "" OUT "${SRC}") 2010 | 2011 | #file(WRITE "${CMAKE_BINARY_DIR}/${FILE}_post_remove_comments.txt" ${SRC}) 2012 | #message(STATUS "\n${SRC}") 2013 | 2014 | set(${OUT_VAR} ${OUT} PARENT_SCOPE) 2015 | 2016 | endfunction() 2017 | 2018 | #=============================================================================# 2019 | # [PRIVATE/INTERNAL] 2020 | # 2021 | # get_num_lines(DOCUMENT OUTPUT_VAR) 2022 | # 2023 | # DOCUMENT - Document contents 2024 | # OUTPUT_VAR - Variable which will hold the line number count 2025 | # 2026 | # Counts the line number of the document. 2027 | #=============================================================================# 2028 | function(GET_NUM_LINES DOCUMENT OUTPUT_VAR) 2029 | string(REGEX MATCHALL "[\n]" MATCH_LIST "${DOCUMENT}") 2030 | list(LENGTH MATCH_LIST NUM) 2031 | set(${OUTPUT_VAR} ${NUM} PARENT_SCOPE) 2032 | endfunction() 2033 | 2034 | #=============================================================================# 2035 | # [PRIVATE/INTERNAL] 2036 | # 2037 | # required_variables(MSG msg VARS var1 var2 .. varN) 2038 | # 2039 | # MSG - Message to be displayed in case of error 2040 | # VARS - List of variables names to check 2041 | # 2042 | # Ensure the specified variables are not empty, otherwise a fatal error is emmited. 2043 | #=============================================================================# 2044 | function(REQUIRED_VARIABLES) 2045 | cmake_parse_arguments(INPUT "" "MSG" "VARS" ${ARGN}) 2046 | error_for_unparsed(INPUT) 2047 | foreach(VAR ${INPUT_VARS}) 2048 | if ("${${VAR}}" STREQUAL "") 2049 | message(FATAL_ERROR "${VAR} not set: ${INPUT_MSG}") 2050 | endif() 2051 | endforeach() 2052 | endfunction() 2053 | 2054 | #=============================================================================# 2055 | # [PRIVATE/INTERNAL] 2056 | # 2057 | # error_for_unparsed(PREFIX) 2058 | # 2059 | # PREFIX - Prefix name 2060 | # 2061 | # Emit fatal error if there are unparsed argument from cmake_parse_arguments(). 2062 | #=============================================================================# 2063 | function(ERROR_FOR_UNPARSED PREFIX) 2064 | set(ARGS "${${PREFIX}_UNPARSED_ARGUMENTS}") 2065 | if (NOT ( "${ARGS}" STREQUAL "") ) 2066 | message(FATAL_ERROR "unparsed argument: ${ARGS}") 2067 | endif() 2068 | endfunction() 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | #=============================================================================# 2076 | # C Flags 2077 | #=============================================================================# 2078 | if (NOT DEFINED ARDUINO_C_FLAGS) 2079 | set(ARDUINO_C_FLAGS "-mcall-prologues -ffunction-sections -fdata-sections") 2080 | endif (NOT DEFINED ARDUINO_C_FLAGS) 2081 | set(CMAKE_C_FLAGS "-g -Os ${ARDUINO_C_FLAGS}" CACHE STRING "") 2082 | set(CMAKE_C_FLAGS_DEBUG "-g ${ARDUINO_C_FLAGS}" CACHE STRING "") 2083 | set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG ${ARDUINO_C_FLAGS}" CACHE STRING "") 2084 | set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG -w ${ARDUINO_C_FLAGS}" CACHE STRING "") 2085 | set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g -w ${ARDUINO_C_FLAGS}" CACHE STRING "") 2086 | 2087 | #=============================================================================# 2088 | # C++ Flags 2089 | #=============================================================================# 2090 | if (NOT DEFINED ARDUINO_CXX_FLAGS) 2091 | set(ARDUINO_CXX_FLAGS "${ARDUINO_C_FLAGS} -fno-exceptions") 2092 | endif (NOT DEFINED ARDUINO_CXX_FLAGS) 2093 | set(CMAKE_CXX_FLAGS "-g -Os ${ARDUINO_CXX_FLAGS}" CACHE STRING "") 2094 | set(CMAKE_CXX_FLAGS_DEBUG "-g ${ARDUINO_CXX_FLAGS}" CACHE STRING "") 2095 | set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG ${ARDUINO_CXX_FLAGS}" CACHE STRING "") 2096 | set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG ${ARDUINO_CXX_FLAGS}" CACHE STRING "") 2097 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -g ${ARDUINO_CXX_FLAGS}" CACHE STRING "") 2098 | 2099 | #=============================================================================# 2100 | # Executable Linker Flags # 2101 | #=============================================================================# 2102 | set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections -lm") 2103 | set(CMAKE_EXE_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2104 | set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2105 | set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2106 | set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2107 | set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2108 | 2109 | #=============================================================================# 2110 | #=============================================================================# 2111 | # Shared Lbrary Linker Flags # 2112 | #=============================================================================# 2113 | set(CMAKE_SHARED_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2114 | set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2115 | set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2116 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2117 | set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2118 | 2119 | set(CMAKE_MODULE_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2120 | set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2121 | set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2122 | set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2123 | set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") 2124 | 2125 | 2126 | #=============================================================================# 2127 | # Arduino Settings 2128 | #=============================================================================# 2129 | set(ARDUINO_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load 2130 | --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "") 2131 | set(ARDUINO_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") 2132 | set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "") 2133 | 2134 | #=============================================================================# 2135 | # Initialization 2136 | #=============================================================================# 2137 | if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) 2138 | register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/) 2139 | 2140 | find_file(ARDUINO_LIBRARIES_PATH 2141 | NAMES libraries 2142 | PATHS ${ARDUINO_SDK_PATH} 2143 | DOC "Path to directory containing the Arduino libraries.") 2144 | 2145 | find_file(ARDUINO_VERSION_PATH 2146 | NAMES lib/version.txt 2147 | PATHS ${ARDUINO_SDK_PATH} 2148 | DOC "Path to Arduino version file.") 2149 | 2150 | find_program(ARDUINO_AVRDUDE_PROGRAM 2151 | NAMES avrdude 2152 | PATHS ${ARDUINO_SDK_PATH} 2153 | PATH_SUFFIXES hardware/tools hardware/tools/avr/bin 2154 | NO_DEFAULT_PATH) 2155 | 2156 | find_program(ARDUINO_AVRDUDE_PROGRAM 2157 | NAMES avrdude 2158 | DOC "Path to avrdude programmer binary.") 2159 | 2160 | find_program(AVRSIZE_PROGRAM 2161 | NAMES avr-size) 2162 | 2163 | find_file(ARDUINO_AVRDUDE_CONFIG_PATH 2164 | NAMES avrdude.conf 2165 | PATHS ${ARDUINO_SDK_PATH} /etc/avrdude /etc 2166 | PATH_SUFFIXES hardware/tools 2167 | hardware/tools/avr/etc 2168 | DOC "Path to avrdude programmer configuration file.") 2169 | 2170 | if(NOT CMAKE_OBJCOPY) 2171 | find_program(AVROBJCOPY_PROGRAM 2172 | avr-objcopy) 2173 | set(ADDITIONAL_REQUIRED_VARS AVROBJCOPY_PROGRAM) 2174 | set(CMAKE_OBJCOPY ${AVROBJCOPY_PROGRAM}) 2175 | endif(NOT CMAKE_OBJCOPY) 2176 | 2177 | set(ARDUINO_DEFAULT_BOARD uno CACHE STRING "Default Arduino Board ID when not specified.") 2178 | set(ARDUINO_DEFAULT_PORT CACHE STRING "Default Arduino port when not specified.") 2179 | set(ARDUINO_DEFAULT_SERIAL CACHE STRING "Default Arduino Serial command when not specified.") 2180 | set(ARDUINO_DEFAULT_PROGRAMMER CACHE STRING "Default Arduino Programmer ID when not specified.") 2181 | 2182 | # Ensure that all required paths are found 2183 | required_variables(VARS 2184 | ARDUINO_PLATFORMS 2185 | ARDUINO_CORES_PATH 2186 | ARDUINO_BOOTLOADERS_PATH 2187 | ARDUINO_LIBRARIES_PATH 2188 | ARDUINO_BOARDS_PATH 2189 | ARDUINO_PROGRAMMERS_PATH 2190 | ARDUINO_VERSION_PATH 2191 | ARDUINO_AVRDUDE_FLAGS 2192 | ARDUINO_AVRDUDE_PROGRAM 2193 | ARDUINO_AVRDUDE_CONFIG_PATH 2194 | AVRSIZE_PROGRAM 2195 | ${ADDITIONAL_REQUIRED_VARS} 2196 | MSG "Invalid Arduino SDK path (${ARDUINO_SDK_PATH}).\n") 2197 | 2198 | detect_arduino_version(ARDUINO_SDK_VERSION) 2199 | set(ARDUINO_SDK_VERSION ${ARDUINO_SDK_VERSION} CACHE STRING "Arduino SDK Version") 2200 | set(ARDUINO_SDK_VERSION_MAJOR ${ARDUINO_SDK_VERSION_MAJOR} CACHE STRING "Arduino SDK Major Version") 2201 | set(ARDUINO_SDK_VERSION_MINOR ${ARDUINO_SDK_VERSION_MINOR} CACHE STRING "Arduino SDK Minor Version") 2202 | set(ARDUINO_SDK_VERSION_PATCH ${ARDUINO_SDK_VERSION_PATCH} CACHE STRING "Arduino SDK Patch Version") 2203 | 2204 | if(ARDUINO_SDK_VERSION VERSION_LESS 0.19) 2205 | message(FATAL_ERROR "Unsupported Arduino SDK (require verion 0.19 or higher)") 2206 | endif() 2207 | 2208 | message(STATUS "Arduino SDK version ${ARDUINO_SDK_VERSION}: ${ARDUINO_SDK_PATH}") 2209 | 2210 | setup_arduino_size_script(ARDUINO_SIZE_SCRIPT) 2211 | set(ARDUINO_SIZE_SCRIPT ${ARDUINO_SIZE_SCRIPT} CACHE INTERNAL "Arduino Size Script") 2212 | 2213 | #print_board_list() 2214 | #print_programmer_list() 2215 | 2216 | set(ARDUINO_FOUND True CACHE INTERNAL "Arduino Found") 2217 | mark_as_advanced( 2218 | ARDUINO_CORES_PATH 2219 | ARDUINO_VARIANTS_PATH 2220 | ARDUINO_BOOTLOADERS_PATH 2221 | ARDUINO_LIBRARIES_PATH 2222 | ARDUINO_BOARDS_PATH 2223 | ARDUINO_PROGRAMMERS_PATH 2224 | ARDUINO_VERSION_PATH 2225 | ARDUINO_AVRDUDE_FLAGS 2226 | ARDUINO_AVRDUDE_PROGRAM 2227 | ARDUINO_AVRDUDE_CONFIG_PATH 2228 | ARDUINO_OBJCOPY_EEP_FLAGS 2229 | ARDUINO_OBJCOPY_HEX_FLAGS 2230 | AVRSIZE_PROGRAM) 2231 | endif() 2232 | 2233 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #==============================================================================# 4 | # # 5 | # Author : QueezyTheGreat # 6 | # Description: Build configuration script # 7 | # # 8 | # Makes sure that we don't execute cmake or ccmake in the source # 9 | # directory(we like prestine sources) # 10 | # # 11 | # If we execute this script in the sources directory, a build directory # 12 | # will be created from where the actual build configuration will be executed. # 13 | # # 14 | # If we aren't in the source directory everything works normally. # 15 | # # 16 | # By default cmake is used to configure the build system, but you can also # 17 | # chose from the ncurses version (ccmake) and the GUI version (cmake-gui). # 18 | # # 19 | #==============================================================================# 20 | 21 | 22 | # Find executable path 23 | function path_locate { 24 | local EXECUTABLE_NAME 25 | local PATH_OUTPUT_VARIABLE_NAME 26 | local EXECUTABLE_PATH 27 | 28 | # Check if we have required arguments 29 | if [ "${#}" -lt 2 ]; then 30 | echo "Insuficient amount of arguments..." 31 | echo "locate_path EXECUTABLE_NAME PATH_OUTPUT_VARIABLE_NAME" 32 | exit 1 33 | fi 34 | 35 | EXECUTABLE_NAME="$1" 36 | PATH_OUTPUT_VAR="$2" 37 | 38 | if [ "${EXECUTABLE_NAME}X" = "X" ]; then 39 | echo "Missing executable name" 40 | echo "locate_path EXECUTABLE_NAME PATH_OUTPUT_VARIABLE_NAME" 41 | exit 1 42 | fi 43 | if [ "${PATH_OUTPUT_VAR}X" = "X" ]; then 44 | echo "Missing path output variable name" 45 | echo "locate_path EXECUTABLE_NAME PATH_OUTPUT_VARIABLE_NAME" 46 | exit 1 47 | fi 48 | 49 | # Try to find full path 50 | EXECUTABLE_PATH="$(type -p ${EXECUTABLE_NAME})" 51 | 52 | # Setting executable path 53 | eval "${PATH_OUTPUT_VAR}"=${EXECUTABLE_PATH} 54 | } 55 | 56 | # Find executable path, exit if not found 57 | function require { 58 | local EXECUTABLE_NAME 59 | local PATH_OUTPUT_VARIABLE_NAME 60 | local EXECUTABLE_PATH 61 | 62 | # Check if we have required arguments 63 | if [ "${#}" -lt 2 ]; then 64 | echo "Insuficient amount of arguments..." 65 | echo "require EXECUTABLE_NAME PATH_OUTPUT_VARIABLE_NAME" 66 | exit 1 67 | fi 68 | 69 | EXECUTABLE_NAME="$1" 70 | PATH_OUTPUT_VAR="$2" 71 | 72 | if [ "${EXECUTABLE_NAME}X" = "X" ]; then 73 | echo "Missing executable name" 74 | echo "require EXECUTABLE_NAME PATH_OUTPUT_VARIABLE_NAME" 75 | exit 1 76 | fi 77 | if [ "${PATH_OUTPUT_VAR}X" = "X" ]; then 78 | echo "Missing path output variable name" 79 | echo "require EXECUTABLE_NAME PATH_OUTPUT_VARIABLE_NAME" 80 | exit 1 81 | fi 82 | 83 | # Try to find full path 84 | EXECUTABLE_PATH="$(type -p ${EXECUTABLE_NAME})" 85 | 86 | if [ "${EXECUTABLE_PATH}X" = "X" ]; then 87 | # No path was found.... failing 88 | echo "${EXECUTABLE_NAME} is not available" 89 | echo "Aborting..." 90 | 91 | exit -1 92 | fi 93 | 94 | if [ ! -x "${EXECUTABLE_PATH}" ]; then 95 | echo "${EXECUTABLE_NAME} is not executable" 96 | echo "Aborting..." 97 | 98 | exit -1 99 | fi 100 | 101 | # Setting executable path 102 | eval "${PATH_OUTPUT_VAR}"=${EXECUTABLE_PATH} 103 | } 104 | 105 | 106 | # Executable names 107 | CMAKE_NAME="cmake" 108 | CCMAKE_NAME="ccmake" 109 | CMAKEGUI_NAME="cmake-gui" 110 | 111 | # Find executable paths 112 | require ${CMAKE_NAME} CMAKE_PATH 113 | path_locate ${CCMAKE_NAME} CCMAKE_PATH 114 | path_locate ${CMAKEGUI_NAME} CMAKEGUI_PATH 115 | 116 | # Warning file 117 | WARNING_PATH="${HOME}/.configure_warning" 118 | 119 | # Detect where we are and where the sources are 120 | CONFIG_BASE_PATH=$(cd "$(dirname "$0")"; pwd) 121 | CURRENT_PATH=$(pwd) 122 | 123 | IN_BASE="$(echo ${CURRENT_PATH}| grep ${CONFIG_BASE_PATH})" 124 | IN_BUILD="$(echo ${CURRENT_PATH}| grep ${CONFIG_BASE_PATH}/build)" 125 | 126 | # Set the default cmake executable 127 | # to be used 128 | CMAKE_EXECUTABLE="${CMAKE_PATH}" 129 | 130 | # Check for command line arguments 131 | case $1 in 132 | "-h") 133 | echo "$0 [-h|-x|-c] [cmake_args...]" 134 | echo 135 | echo " -h Display this help message" 136 | echo " -x Run GUI version of CMake" 137 | echo " -c Run Curses version of CMake" 138 | echo 139 | echo " cmake_args CMake arguments that will be passed" 140 | echo " to the chosen CMake binary, by default" 141 | echo " cmake is used (if -x or -c not used)" 142 | echo 143 | 144 | exit 1 145 | ;; 146 | "-x") 147 | if [ ! -e "${CMAKEGUI_PATH}" ]; then 148 | echo "${CMAKEGUI_NAME} is not available" 149 | echo "Aborting...'" 150 | 151 | exit -1 152 | fi 153 | 154 | # Setting executable to cmake-gui 155 | CMAKE_EXECUTABLE="${CMAKEGUI_PATH}" 156 | 157 | # Shift argument list, getting rid of script name 158 | # and first command line argument 159 | shift 160 | ;; 161 | "-c") 162 | if [ ! -e "${CCMAKE_PATH}" ]; then 163 | echo "${CCMAKE_NAME} is not available" 164 | echo "Aborting...'" 165 | 166 | exit -1 167 | 168 | fi 169 | 170 | # Setting executable to ccmake 171 | CMAKE_EXECUTABLE="${CCMAKE_PATH}" 172 | 173 | # Shift argument list, getting rid of script name 174 | # and first command line argument 175 | shift 176 | ;; 177 | esac 178 | 179 | 180 | echo 181 | echo Project Sources: ${CONFIG_BASE_PATH} 182 | echo CMake Executable: ${CMAKE_EXECUTABLE} 183 | echo 184 | 185 | 186 | # Check if we are in source directory 187 | if [ "${IN_BASE}X" != "X" ]; then 188 | # We are within the source directory 189 | if [ "${IN_BUILD}X" != "X" ]; then 190 | # We are in the build directory 191 | echo 'Building within build directory' 192 | # Running chosen cmake executable 193 | ${CMAKE_EXECUTABLE} ${*} ${CONFIG_BASE_PATH} 194 | else 195 | # We are in the source directory 196 | # but not within the build directory 197 | if [ ! -f "${WARNING_PATH}" ]; then 198 | echo 199 | echo 200 | echo "Running CMake within the source directory is HIGHLY discouraged." 201 | echo "You should either build the project outside the source directory" 202 | echo "or create a directory called build within the root of the project" 203 | echo 204 | echo 205 | echo "This warning will only apear once..." 206 | echo 207 | echo 208 | echo 209 | echo -n "Continuing in 15" 210 | for COUNT in 14 13 12 11 10 9 8 7 6 5 4 3 2 1; do 211 | sleep 1 212 | echo -n "..${COUNT}" 213 | done 214 | echo 215 | 216 | # Removing waring 217 | touch "${WARNING_PATH}" 218 | fi 219 | 220 | if [ ! -d "${CONFIG_BASE_PATH}/build" ]; then 221 | echo "Creating build directory: ${CONFIG_BASE_PATH}/build" 222 | mkdir "${CONFIG_BASE_PATH}/build" 223 | fi 224 | 225 | # Changing to build directory 226 | echo "Changing to build directory: ${CONFIG_BASE_PATH}/build" 227 | cd "${CONFIG_BASE_PATH}/build" 228 | 229 | # Running chosen cmake executable in new build directory 230 | ${CMAKE_EXECUTABLE} ${*} ${CONFIG_BASE_PATH} 231 | 232 | fi 233 | else 234 | # We are outside of the source directory 235 | # Running chosen cmake executable 236 | ${CMAKE_EXECUTABLE} ${*} ${CONFIG_BASE_PATH} 237 | fi 238 | 239 | if [ "${?}" -eq 0 ]; then 240 | echo 241 | echo "To build project: make" 242 | echo "To install project: make install" 243 | echo "Generate packages: make package" 244 | echo 245 | 246 | exit 0 247 | else 248 | exit 1 249 | fi 250 | -------------------------------------------------------------------------------- /configure.bat: -------------------------------------------------------------------------------- 1 | ::===========================================================================:: 2 | :: Author: QueezyTheGreat :: 3 | :: Description: Small wrapper around cmake and cmake-gui for :: 4 | :: easy build system configuration and generation. :: 5 | ::===========================================================================:: 6 | @echo off 7 | 8 | set CURRENT_PATH=%CD% 9 | 10 | set CONFIGURE_PATH=%~dp0% 11 | set CONFIGURE_MODE=%1 12 | set CONFIGURE_ARGS=%* 13 | 14 | set BUILD_PATh=build 15 | 16 | set CMAKE_NAME=cmake.exe 17 | set CMAKEGUI_NAME=cmake-gui.exe 18 | 19 | 20 | :: Parse arguments 21 | if /i [%CONFIGURE_MODE%] EQU [-h] goto :print_help 22 | if /i [%CONFIGURE_MODE%] EQU [--help] goto :print_help 23 | if /i [%CONFIGURE_MODE%] EQU [/?] goto :print_help 24 | 25 | 26 | :: Check dependencies 27 | for %%X in (%CMAKE_NAME% %CMAKEGUI_NAME%) do ( 28 | set FOUND=%%~$PATH:X 29 | if not defined FOUND ( 30 | echo %%X missing on the path, aborting! 31 | echo. 32 | echo Please ensure that CMake is available on the system path. 33 | echo. 34 | pause 35 | goto :EXIT 36 | ) 37 | ) 38 | 39 | :: Generate/Configure build 40 | call :init_build 41 | call :setup_build 42 | 43 | 44 | ::===========================================================================:: 45 | :: :: 46 | ::===========================================================================:: 47 | goto :EXIT 48 | 49 | 50 | :: Initialize build path 51 | :init_build 52 | if "%CURRENT_PATH%\" EQU "%CONFIGURE_PATH%" ( 53 | :: In sources, create build directory 54 | set "BUILD_PATH=%CONFIGURE_PATH%%BUILD_PATH%" 55 | 56 | :: Create build directory 57 | if not exist "%BUILD_PATH%" ( 58 | mkdir "%BUILD_PATH%" 59 | ) 60 | ) else ( 61 | :: Out of sources, do nothing 62 | set BUILD_PATH=%CD% 63 | ) 64 | goto :RETURN 65 | 66 | :: Configure/Generate build system 67 | :setup_build 68 | cd "%BUILD_PATH%" 69 | if /i [%CONFIGURE_MODE%] EQU [-c] ( 70 | :: Command Line version (cmake) 71 | echo cmake %CONFIGURE_ARGS:~3% "%CONFIGURE_PATH%" 72 | %CMAKE_NAME% %CONFIGURE_ARGS:~3% "%CONFIGURE_PATH%" 73 | ) else ( 74 | :: GUI version (cmake-gui) 75 | start %CMAKEGUI_NAME% "%CONFIGURE_PATH%" 76 | ) 77 | cd "%CURRENT_PATH%" 78 | goto :RETURN 79 | 80 | :: Display help message 81 | :print_help 82 | echo configure [-h ^| -c OPTS] 83 | echo -h Display this message 84 | echo -c Command line version of CMake 85 | echo. 86 | echo OPTS Options to pass to CMake command line 87 | echo. 88 | echo Small wrapper around cmake and cmake-gui for 89 | echo easy build system configuration and generation. 90 | echo. 91 | echo For GUI and command line use. 92 | goto :EXIT 93 | 94 | :RETURN 95 | :EXIT 96 | -------------------------------------------------------------------------------- /example/Blink/Blink.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Blink 3 | Turns on an LED on for one second, then off for one second, repeatedly. 4 | 5 | This example code is in the public domain. 6 | */ 7 | 8 | #include "config.h" 9 | 10 | Test1 a; 11 | 12 | void setup() { 13 | // initialize the digital pin as an output. 14 | // Pin 13 has an LED connected on most Arduino boards: 15 | pinMode(13, OUTPUT); 16 | /* 17 | This is a weird comment 18 | //*/ 19 | } 20 | 21 | void loop() { 22 | digitalWrite(13, HIGH); // set the LED on 23 | delay(1000); // wait for a second 24 | digitalWrite(13, LOW); // set the LED off 25 | delay(1000); // wait for a second 26 | } 27 | -------------------------------------------------------------------------------- /example/Blink/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | class Test1 { 4 | }; 5 | #endif 6 | -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This configuration file outlines some of the ways Arduino CMake 2 | # can be used. For a detailed explenation of all the options please 3 | # reade README.rst. 4 | 5 | set(ARDUINO_DEFAULT_BOARD diecimila) # Default Board ID, when not specified 6 | set(ARDUINO_DEFAULT_PORT /dev/ttyUSB0) # Default Port, when not specified 7 | 8 | 9 | #====================================================================# 10 | # master_writer example from Wire library 11 | #====================================================================# 12 | generate_arduino_example(wire_example 13 | LIBRARY Wire 14 | EXAMPLE master_writer) 15 | 16 | # Alternative: by vairables 17 | #set(wire_example_LIBRARY Wire) 18 | #set(wire_example_EXAMPLE master_writer) 19 | # 20 | #generate_arduino_example(wire_example) 21 | 22 | 23 | 24 | #====================================================================# 25 | # Original blink sketch (from Arduino SDK examples) 26 | #====================================================================# 27 | 28 | # Some installations have renamed the example directories 29 | if (EXISTS "${ARDUINO_SDK_PATH}/examples/01.Basics/Blink") 30 | set(BLINK_SKETCH "${ARDUINO_SDK_PATH}/examples/01.Basics/Blink") 31 | else() 32 | set(BLINK_SKETCH "${ARDUINO_SDK_PATH}/examples/1.Basics/Blink") 33 | endif() 34 | 35 | generate_arduino_firmware(blink_original 36 | SKETCH "${BLINK_SKETCH}" 37 | PORT /dev/ttyACM0 38 | SERIAL picocom @SERIAL_PORT@ 39 | BOARD uno) 40 | 41 | # Alternative: by variables 42 | #set(blink_original_SKETCH "${BLINK_SKETCH}") 43 | #set(blink_original_PORT /dev/ttyACM) 44 | #set(blink_original_SERIAL picocom @SERIAL_PORT@) 45 | #set(blink_original_BOARD uno) 46 | # 47 | #generate_arduino_firmware(blink_original) 48 | 49 | 50 | 51 | 52 | #====================================================================# 53 | # Bundled blink sketch example 54 | #====================================================================# 55 | generate_arduino_firmware(blink_bundled 56 | SKETCH Blink 57 | PROGRAMMER usbtinyisp 58 | NO_AUTOLIBS) 59 | 60 | # Alternative: by variables 61 | #set(blink_bundled_SKETCH Blink) 62 | #set(blink_bundled_PROGRAMMER usbtinyisp) 63 | #set(blink_bundled_NO_AUTOLIBS true) 64 | # 65 | #generate_arduino_firmware(blink_bundled) 66 | 67 | 68 | 69 | 70 | #====================================================================# 71 | # Advanced static library exmaple 72 | #====================================================================# 73 | generate_arduino_library(blink_lib 74 | SRCS blink_lib.cpp 75 | HDRS blink_lib.h 76 | BOARD uno) 77 | 78 | # Alternative: by variables 79 | #set(blink_lib_SRCS blink_lib.cpp) 80 | #set(blink_lib_HDRS blink_lib.h) 81 | #set(blink_lib_BOARD uno) 82 | # 83 | #generate_arduino_library(blink_lib) 84 | 85 | 86 | 87 | 88 | #====================================================================# 89 | # Advanced firwmare example 90 | #====================================================================# 91 | generate_arduino_firmware(blink 92 | SRCS blink.cpp 93 | LIBS blink_lib 94 | BOARD uno) 95 | 96 | # Alternative: by variables 97 | #set(blink_SRCS blink.cpp) 98 | #set(blink_LIBS blink_lib) 99 | #set(blink_BOARD uno) 100 | # 101 | #generate_arduino_firmware(blink) 102 | -------------------------------------------------------------------------------- /example/blink.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Blink 3 | Turns on an LED on for one second, then off for one second, repeatedly. 4 | Example uses a static library to show off generate_arduino_library(). 5 | 6 | This example code is in the public domain. 7 | */ 8 | #if ARDUINO >= 100 9 | #include "Arduino.h" 10 | #else 11 | #include "WProgram.h" 12 | #endif 13 | 14 | #include "blink_lib.h" 15 | 16 | void setup() { 17 | blink_setup(); // Setup for blinking 18 | } 19 | 20 | void loop() { 21 | blink(1000); // Blink for a second 22 | } 23 | -------------------------------------------------------------------------------- /example/blink_lib.cpp: -------------------------------------------------------------------------------- 1 | #if ARDUINO >= 100 2 | #include "Arduino.h" 3 | #else 4 | #include "WProgram.h" 5 | #endif 6 | 7 | #include "blink_lib.h" 8 | 9 | void blink_setup(uint8_t pin) { 10 | pinMode(pin, OUTPUT); 11 | } 12 | 13 | 14 | void blink(unsigned long duration, uint8_t pin) { 15 | digitalWrite(pin, HIGH); // set the LED on 16 | delay(duration); // wait for a second 17 | digitalWrite(pin, LOW); // set the LED off 18 | delay(duration); // wait for a second 19 | } 20 | -------------------------------------------------------------------------------- /example/blink_lib.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * Setup for blinking. 5 | * 6 | * @param pin - pin number 7 | **/ 8 | void blink_setup(uint8_t pin=13); 9 | 10 | 11 | /** 12 | * Blink a single time for the specified duration. 13 | * 14 | * @param duration - duration in miliseconds 15 | * @param pin - pin number 16 | **/ 17 | void blink(unsigned long duration, uint8_t pin=13); 18 | --------------------------------------------------------------------------------