From 79cf1bf9cff76db9cf7cc9d991ad96340d5782ba Mon Sep 17 00:00:00 2001 From: Altex Date: Thu, 23 Apr 2015 16:29:02 +0300 Subject: [PATCH 01/29] Added Arduino IDE 1.6 support and minor fixes --- .gitignore | 4 +- CMakeLists.txt | 13 ++- README.rst => README.original.rst | 4 + README.txt | 165 ++++++++++++++++++++++++++ cmake/ArduinoToolchain.cmake | 5 + cmake/Platform/Arduino.cmake | 188 ++++++++++++++++++++---------- example/Blink/Blink.ino | 26 ----- example/Blink/config.h | 5 - example/CMakeLists.txt | 107 ++--------------- example/blink.cpp | 22 ---- example/blink_lib.cpp | 19 --- example/blink_lib.h | 17 --- example/example.cpp | 23 ++++ 13 files changed, 352 insertions(+), 246 deletions(-) rename README.rst => README.original.rst (99%) create mode 100644 README.txt delete mode 100644 example/Blink/Blink.ino delete mode 100644 example/Blink/config.h delete mode 100644 example/blink.cpp delete mode 100644 example/blink_lib.cpp delete mode 100644 example/blink_lib.h create mode 100644 example/example.cpp diff --git a/.gitignore b/.gitignore index 378eac2..9c16f36 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -build +build/ +.idea/ + diff --git a/CMakeLists.txt b/CMakeLists.txt index 755e3d2..d1dd28d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,13 @@ # Description: Arduino CMake example # # # #=============================================================================# + +# this line is needed only if you use boards with selectable cpu (like mega, pro etc) +# and this line should go before call to "cmake/ArduinoToolchain.cmake" +# this is durty hack and should be fixed somewhen, because it should go to +# particular cmake subdirectory +set(ARDUINO_CPU 16MHzatmega328) + set(CMAKE_TOOLCHAIN_FILE cmake/ArduinoToolchain.cmake) # Arduino Toolchain @@ -17,4 +24,8 @@ project(ArduinoExample C CXX) print_board_list() print_programmer_list() -add_subdirectory(example) #add the example directory into build +# add libraries to project +link_directories(${ARDUINO_SDK}/libraries) + +# add the project directory into build +add_subdirectory(example) diff --git a/README.rst b/README.original.rst similarity index 99% rename from README.rst rename to README.original.rst index 4675f03..18aeb8a 100644 --- a/README.rst +++ b/README.original.rst @@ -744,6 +744,10 @@ The following options control how **Arduino CMake** is configured: +---------------------------------+-----------------------------------------------------+ | **ARDUINO_DEFAULT_BOARD** | Default Arduino Board ID, when not specified. | +---------------------------------+-----------------------------------------------------+ +| **ARDUINO_CPU** | Selected CPU from Arduino 1.5 menu boards. For mega | +| | board, for example, you have to set atmega2560 | +| | before including ARDUINO ToolChain | ++---------------------------------+-----------------------------------------------------+ | **ARDUINO_DEFAULT_PORT** | Default Arduino port, when not specified. | +---------------------------------+-----------------------------------------------------+ | **ARDUINO_DEFAULT_SERIAL** | Default Arduino Serial command, when not specified. | diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..1c26a4d --- /dev/null +++ b/README.txt @@ -0,0 +1,165 @@ +Arduino Cmake Example Project +=============================== + +Здесь находится проект с примером настроек cmake для работы с arduino. +Исправно загружается и работает в CLion и Windows, используя в качестве +toolchain из Arduino IDE 1.6+ и MinGW. + +Оригинальный код проекта распространяется под лицензией +Mozilla Public License, v. 2.0 http://mozilla.org/MPL/2.0/ + +Список авторов и контрибьюторов оригинального проекта +описан в оригинальном readme: +/README.original.rst + +Полезные ссылки +------------------------------- +Оригинальный проект находится по адресу +https://github.com/queezythegreat/arduino-cmake + +В текущем же репозитории находится его копия с наложенными патчами, +взятыми из pull requests отсюда +https://github.com/queezythegreat/arduino-cmake/pulls +и написанными мной патчами, закрывающими ряд багов, +и добавляющими ряд фич. + +Некоторые примеры настроек проекта для CLion взяты из статьи +http://habrahabr.ru/post/247017/ + +Изменения по сравнению с оригиналом +------------------------------- +1. Наложен патч "Adding support for SDK 1.5" + https://github.com/queezythegreat/arduino-cmake/pull/104 + Добавлена поддержка Arduino 1.5-1.6. + +2. Наложен патч "fixed bug in find_file method" + https://github.com/queezythegreat/arduino-cmake/pull/109 + Стандартные пути окружения windows не учитываются при поиске Arduino IDE. + +3. Наложен патч "Fix CMP0038 warnings on CMake >= 3.0" + https://github.com/queezythegreat/arduino-cmake/pull/143 + +4. Исправлены пути windows для того, чтобы avr-size писал размер + скомпиллированного бинарника при сборке. + +5. Исправлены пути, по которым ищутся настройки в boards.txt для остальных + плат кроме mega, так как заливка скетча работала только с mega, так как + неверно определялся программатор. + +6. Все опции сборки взяты по максимому из оригинальной IDE, и скорее всего + сделано не оптимально и требует более детального анализа. + +7. Убрал различия между всеми видами сборки, и это деструктивное изменение, + которое не нужно мёрджить с основным проектом. Я так сделал потому-что + не стал разбираться как лучше всего выбрать опции и для каких режимов (debug, release). + +8. Оригинальный Readme сохранён в README.original.rst + +Установка CLion + Arduino IDE + MinGW +----------------------------------- +1. Установить MinGW (нужно для CLion, добавляет make, g++, cpp) + +1.1. Установить MinGW + http://sourceforge.net/projects/mingw/files/Installer/ + Тестировалось на версии mingw-get-0.6.2-mingw32-beta-20131004-1 + +1.2. Запустить MinGW Installation Manager + +1.3. Выбрать пакеты из "Basic Setup" + - mingw-developer-toolkit + - mingw32-base + - mingw32-gcc-g++ + - msys-base +и нажать "Apply Changes" + +2. Установить Arduino IDE 1.6 (нужен для сборки проекта, включает avr toolchain) + http://www.arduino.cc/en/Main/OldSoftwareReleases + Тестировалось на версии 1.6.3 + +3. Установить и настроить JetBrains CLion 1.0 + +3.1. Установить JetBrains CLion 1.0 + https://www.jetbrains.com/clion/ + Тестировалось на версии 1.0 + +3.2. Запустить CLion + +3.3. Настроить toolchain + Меню настроек "File" -> "Settings" + Выбрать "Build, Execudion, Deployment" -> "Toolchain" + Дальше сконфигурировать + - Env: MinGW "c:\mingw" + - cmake: "bundled cmake" + +После этого cmake должен правильно собирать проект. +Всё, что для этого потребуется - это открыть проект в CLion. + +Портирование вашего проекта из Arduino IDE +----------------------------------- +Предположим у вас есть свой проект, с названием Robot и файлами +- /Robot.ino +- /Chassis.cpp +- /Chassis.h +который уже работает в Arduino IDE, и вы хотите его перенести в CLion. + +1. Создаём новый проект с названием arduino-cmake-robot + git clone {THIS_REPO} arduino-cmake-robot +Нам больше не потребуется связь с оригинальным проектом, +мы в дальнейшем будем работать со своим репозиторием. + git remote rm origin + +2. Копируем файлы проекта Robot +Создаём папку /robot в корне нового проекта. +Копируем файлы в эту папку, теперь у нас три новых файла в новом проекте + - /robot/Robot.ino + - /robot/Chassis.cpp + - /robot/Chassis.h + +3. Переименовываем Robot.ino в robot.cpp +Теперь у нас старые файлы в новом проекте с такими названиями + - /robot/robot.cpp + - /robot/Chassis.cpp + - /robot/Chassis.h + +4. Подключаем стандартную библиотеку Arduino +Добавляем в /robot/robot.cpp первой строчкой + #include "Arduino.h" + +5. Создаём файл с настройками сборки проекта +Копируем /example/CMakeLists.txt в /robot/CMakeLists.txt + +6. Настраиваем CMakeLists.txt проекта robot (/robot/CMakeLists.txt) +Указываем название проекта + set(PROJECT_NAME robot) + +Указываем название платформы, под которую собираем. +Пример 1. Для примера это Arduino Pro (Arduino Pro Mini) + set(${PROJECT_NAME}_BOARD pro) +Пример 2. Для Arduino UNO это бы выглядело так + set(${PROJECT_NAME}_BOARD uno) + +Указываем название файла, который раньше был с расширением INO + set(${PROJECT_NAME}_SRCS robot.cpp) +Указываем нужный COM порт, к которому подключается плата + set(${PROJECT_NAME}_PORT COM3) + +7. Настраиваем корневой CMakeLists.txt (/CMakeLists.txt) +Выбираем правильный вариант процессора для платы +Это название берётся из файла + C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt + +Пример 1. Для Arduino Pro 16Mhz 5V ATmega 328 +нужно смотреть строчку "pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)" +и брать соответствующий идентификатор "16MHzatmega328", а не название "ATmega328 (5V, 16 MHz)" + set(ARDUINO_CPU 16MHzatmega328) +Пример 2. Для Arduino UNO нужно ничего не указывать, просто закомментировать строчку, +потому что для UNO нет выбора процессоров + # (закомментировали) set(ARDUINO_CPU 16MHzatmega328) + +Подключаем нужно папку, меняем example на robot + # (закомментировали) add_subdirectory(example) + add_subdirectory(robot) + +8. Открываем проект в CLion и выбираем опцию сборки robot (для компилляции) +или robot_upload (для компилляции и закрузки). +Собираем проект (CTRL+F9). Проект загружается на плату. diff --git a/cmake/ArduinoToolchain.cmake b/cmake/ArduinoToolchain.cmake index f320898..164f004 100644 --- a/cmake/ArduinoToolchain.cmake +++ b/cmake/ArduinoToolchain.cmake @@ -81,3 +81,8 @@ else() message(FATAL_ERROR "Could not find Arduino SDK (set ARDUINO_SDK_PATH)!") endif() +set(ARDUINO_CPUMENU) +if(ARDUINO_CPU) + set(ARDUINO_CPUMENU ".menu.cpu.${ARDUINO_CPU}") +endif(ARDUINO_CPU) + diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 042a3c1..979569b 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -500,7 +500,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "${INPUT_ARDLIBS}") foreach(LIB_DEP ${TARGET_LIBS}) arduino_debug_msg("Arduino Library: ${LIB_DEP}") - set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\"") + set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\" -I\"${LIB_DEP}/src\"") endforeach() if(NOT INPUT_NO_AUTOLIBS) @@ -657,27 +657,38 @@ function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) find_file(${PLATFORM}_CORES_PATH NAMES cores PATHS ${PLATFORM_PATH} - DOC "Path to directory containing the Arduino core sources.") + DOC "Path to directory containing the Arduino core sources." + NO_SYSTEM_ENVIRONMENT_PATH) find_file(${PLATFORM}_VARIANTS_PATH NAMES variants PATHS ${PLATFORM_PATH} - DOC "Path to directory containing the Arduino variant sources.") + DOC "Path to directory containing the Arduino variant sources." + NO_SYSTEM_ENVIRONMENT_PATH) find_file(${PLATFORM}_BOOTLOADERS_PATH NAMES bootloaders PATHS ${PLATFORM_PATH} - DOC "Path to directory containing the Arduino bootloader images and sources.") + DOC "Path to directory containing the Arduino bootloader images and sources." + NO_SYSTEM_ENVIRONMENT_PATH) + + find_file(${PLATFORM}_LIBRARIES_PATH + NAMES libraries + PATHS ${PLATFORM_PATH} + DOC "Path to directory containing the Arduino hardware libraries sources." + NO_SYSTEM_ENVIRONMENT_PATH) find_file(${PLATFORM}_PROGRAMMERS_PATH NAMES programmers.txt PATHS ${PLATFORM_PATH} - DOC "Path to Arduino programmers definition file.") + DOC "Path to Arduino programmers definition file." + NO_SYSTEM_ENVIRONMENT_PATH) find_file(${PLATFORM}_BOARDS_PATH NAMES boards.txt PATHS ${PLATFORM_PATH} - DOC "Path to Arduino boards definition file.") + DOC "Path to Arduino boards definition file." + NO_SYSTEM_ENVIRONMENT_PATH) if(${PLATFORM}_BOARDS_PATH) load_arduino_style_settings(${PLATFORM}_BOARDS "${PLATFORM_PATH}/boards.txt") @@ -708,6 +719,7 @@ function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) endif() endforeach() endif() + endif() endif() @@ -786,7 +798,7 @@ function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) set(BOARD_CORE ${${BOARD_ID}.build.core}) if(BOARD_CORE) - if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)") + if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)[.]([0-9]+)") string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) set(ARDUINO_VERSION_DEFINE "") if(CMAKE_MATCH_1 GREATER 0) @@ -797,12 +809,17 @@ function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) else() set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}") endif() + if(CMAKE_MATCH_3 GREATER 10) + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_3}") + else() + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_3}") + endif() else() message("Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})") endif() # output - set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -mmcu=${${BOARD_ID}.build.mcu}") + set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -DARDUINO_${${BOARD_ID}.build.board} -DARDUINO_ARCH_AVR -mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") if(DEFINED ${BOARD_ID}.build.vid) set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}") endif() @@ -812,7 +829,7 @@ function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) if(NOT MANUAL) set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${${BOARD_CORE}.path}\" -I\"${ARDUINO_LIBRARIES_PATH}\"") endif() - set(LINK_FLAGS "-mmcu=${${BOARD_ID}.build.mcu}") + set(LINK_FLAGS "-mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") if(ARDUINO_SDK_VERSION VERSION_GREATER 1.0 OR ARDUINO_SDK_VERSION VERSION_EQUAL 1.0) if(NOT MANUAL) set(PIN_HEADER ${${${BOARD_ID}.build.variant}.path}) @@ -920,11 +937,15 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) get_property(LIBRARY_SEARCH_PATH DIRECTORY # Property Scope PROPERTY LINK_DIRECTORIES) - foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) + foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() endif() + if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src/${CMAKE_MATCH_1}) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) + break() + endif() if(EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) break() @@ -962,6 +983,10 @@ endfunction() set(Wire_RECURSE True) set(Ethernet_RECURSE True) set(SD_RECURSE True) +set(SPI_RECURSE True) +set(SoftwareSerial_RECURSE True) +set(EEPROM_RECURSE True) +set(LiquidCrystal_RECURSE True) function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) set(LIB_TARGETS) set(LIB_INCLUDES) @@ -978,7 +1003,7 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA find_sources(LIB_SRCS ${LIB_PATH} ${${LIB_SHORT_NAME}_RECURSE}) if(LIB_SRCS) - + message(STATUS "Generating ${TARGET_LIB_NAME} for library ${LIB_NAME}") arduino_debug_msg("Generating Arduino ${LIB_NAME} library") add_library(${TARGET_LIB_NAME} STATIC ${LIB_SRCS}) @@ -987,9 +1012,17 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "") foreach(LIB_DEP ${LIB_DEPS}) + if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME AND DEP_LIB_SRCS) + message(STATUS "Found library ${LIB_NAME} needs ${DEP_LIB_SRCS}") + endif() + setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} "${COMPILE_FLAGS}" "${LINK_FLAGS}") - list(APPEND LIB_TARGETS ${DEP_LIB_SRCS}) - list(APPEND LIB_INCLUDES ${DEP_LIB_SRCS_INCLUDES}) + # Do not link to this library. DEP_LIB_SRCS will always be only one entry + # if we are looking at the same library. + if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME) + list(APPEND LIB_TARGETS ${DEP_LIB_SRCS}) + list(APPEND LIB_INCLUDES ${DEP_LIB_SRCS_INCLUDES}) + endif() endforeach() if (LIB_INCLUDES) @@ -997,9 +1030,9 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA endif() set_target_properties(${TARGET_LIB_NAME} PROPERTIES - COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${LIB_INCLUDES} -I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\" ${COMPILE_FLAGS}" + COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${LIB_INCLUDES} -I\"${LIB_PATH}\" -I\"${LIB_PATH}/src\" -I\"${LIB_PATH}/utility\" ${COMPILE_FLAGS}" LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") - list(APPEND LIB_INCLUDES "-I\"${LIB_PATH}\" -I\"${LIB_PATH}/utility\"") + list(APPEND LIB_INCLUDES "-I\"${LIB_PATH}\" -I\"${LIB_PATH}/src\" -I\"${LIB_PATH}/utility\"") target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE ${LIB_TARGETS}) list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) @@ -1079,6 +1112,8 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) endif() set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) + + message(STATUS "Using ${CMAKE_OBJCOPY} for converting firmware image to hex") add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ARGS ${ARDUINO_OBJCOPY_EEP_FLAGS} @@ -1100,7 +1135,7 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -DFIRMWARE_IMAGE=${TARGET_PATH}.elf - -DMCU=${${BOARD_ID}.build.mcu} + -DMCU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu} -DEEPROM_IMAGE=${TARGET_PATH}.eep -P ${ARDUINO_SIZE_SCRIPT} COMMENT "Calculating image size" @@ -1110,7 +1145,7 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA add_custom_target(${TARGET_NAME}-size COMMAND ${CMAKE_COMMAND} -DFIRMWARE_IMAGE=${TARGET_PATH}.elf - -DMCU=${${BOARD_ID}.build.mcu} + -DMCU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu} -DEEPROM_IMAGE=${TARGET_PATH}.eep -P ${ARDUINO_SIZE_SCRIPT} DEPENDS ${TARGET_NAME} @@ -1174,7 +1209,7 @@ function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS endif() set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex") + list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex:i") list(APPEND AVRDUDE_ARGS "-Ueeprom:w:${TARGET_PATH}.eep:i") add_custom_target(${UPLOAD_TARGET} ${ARDUINO_AVRDUDE_PROGRAM} @@ -1265,8 +1300,8 @@ function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRD endif() endforeach() - if(NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") - message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}.bootloader.file}") + if(NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}") + message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}") message("Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.") return() endif() @@ -1277,14 +1312,14 @@ function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRD # Set unlock bits and fuses (because chip is going to be erased) list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.unlock_bits}:m") if(${BOARD_ID}.bootloader.extended_fuses) - list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}.bootloader.extended_fuses}:m") + list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.extended_fuses}:m") endif() list(APPEND AVRDUDE_ARGS - "-Uhfuse:w:${${BOARD_ID}.bootloader.high_fuses}:m" + "-Uhfuse:w:${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.high_fuses}:m" "-Ulfuse:w:${${BOARD_ID}.bootloader.low_fuses}:m") # Set bootloader image - list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}.bootloader.file}:i") + list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}:i") # Set lockbits list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.lock_bits}:m") @@ -1344,7 +1379,7 @@ function(setup_arduino_programmer_args BOARD_ID PROGRAMMER TARGET_NAME PORT AVRD list(APPEND AVRDUDE_ARGS "-i${${PROGRAMMER}.delay}") # Set delay endif() - list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}.build.mcu}") # MCU Type + list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") # MCU Type list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) @@ -1373,19 +1408,23 @@ function(setup_arduino_bootloader_args BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS O list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}" # avrdude config - "-p${${BOARD_ID}.build.mcu}" # MCU Type + "-p${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}" # MCU Type ) # Programmer - if(NOT ${BOARD_ID}.upload.protocol OR ${BOARD_ID}.upload.protocol STREQUAL "stk500") - list(APPEND AVRDUDE_ARGS "-cstk500v1") + if(NOT ${BOARD_ID}${ARDUINO_CPUMENU}.upload.protocol OR ${BOARD_ID}${ARDUINO_CPUMENU}.upload.protocol STREQUAL "stk500") + if(NOT ${BOARD_ID}.upload.protocol OR ${BOARD_ID}.upload.protocol STREQUAL "stk500") + list(APPEND AVRDUDE_ARGS "-cstk500v1") + else() + list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}.upload.protocol}") + endif() else() - list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}.upload.protocol}") + list(APPEND AVRDUDE_ARGS "-c${${BOARD_ID}${ARDUINO_CPUMENU}.upload.protocol}") endif() set(UPLOAD_SPEED "19200") - if(${BOARD_ID}.upload.speed) - set(UPLOAD_SPEED ${${BOARD_ID}.upload.speed}) + if(${BOARD_ID}${ARDUINO_CPUMENU}.upload.speed) + set(UPLOAD_SPEED ${${BOARD_ID}${ARDUINO_CPUMENU}.upload.speed}) endif() list(APPEND AVRDUDE_ARGS @@ -1560,24 +1599,38 @@ function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH) # Add entry to main list list(APPEND ${SETTINGS_LIST} ${ENTRY_NAME}) endif() - + # Add entry setting to entry settings list if it does not exist set(ENTRY_SETTING_LIST ${ENTRY_NAME}.SETTINGS) list(GET ENTRY_NAME_TOKENS 1 ENTRY_SETTING) - list(FIND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING} ENTRY_SETTING_INDEX) - if(ENTRY_SETTING_INDEX LESS 0) - # Add setting to entry - list(APPEND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING}) - set(${ENTRY_SETTING_LIST} ${${ENTRY_SETTING_LIST}} - CACHE INTERNAL "Arduino ${ENTRY_NAME} Board settings list") - endif() + set(PARAMETERS 2) + if(ENTRY_SETTING STREQUAL "menu") + list(GET ENTRY_NAME_TOKENS 3 CPUNAME) + if(ENTRY_NAME_TOKENS_LEN GREATER 4) + list(GET ENTRY_NAME_TOKENS 4 PROPERTYNAME) + set(ENTRY_SETTING "menu.cpu.${CPUNAME}.${PROPERTYNAME}") + set(PARAMETERS 5) + else() + set(ENTRY_SETTING "menu.cpu.${CPUNAME}") + set(PARAMETERS 4) + endif() + list(APPEND ${ENTRY_SETTING_LIST} "${ENTRY_SETTING}") + else() + list(FIND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING} ENTRY_SETTING_INDEX) + if(ENTRY_SETTING_INDEX LESS 0) + # Add setting to entry + list(APPEND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING}) + set(${ENTRY_SETTING_LIST} ${${ENTRY_SETTING_LIST}} + CACHE INTERNAL "Arduino ${ENTRY_NAME} Board settings list") + endif() + endif() set(FULL_SETTING_NAME ${ENTRY_NAME}.${ENTRY_SETTING}) # Add entry sub-setting to entry sub-settings list if it does not exists - if(ENTRY_NAME_TOKENS_LEN GREATER 2) + if(ENTRY_NAME_TOKENS_LEN GREATER ${PARAMETERS}) set(ENTRY_SUBSETTING_LIST ${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) - list(GET ENTRY_NAME_TOKENS 2 ENTRY_SUBSETTING) + list(GET ENTRY_NAME_TOKENS ${PARAMETERS} ENTRY_SUBSETTING) list(FIND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING} ENTRY_SUBSETTING_INDEX) if(ENTRY_SUBSETTING_INDEX LESS 0) list(APPEND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING}) @@ -1675,7 +1728,8 @@ function(SETUP_ARDUINO_EXAMPLE TARGET_NAME LIBRARY_NAME EXAMPLE_NAME OUTPUT_VAR) get_property(LIBRARY_SEARCH_PATH DIRECTORY # Property Scope PROPERTY LINK_DIRECTORIES) - foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries) + foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries) + message(STATUS "Search ${LIBRARY_NAME} example directory in ${LIB_SEARCH_PATH}") if(EXISTS "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") set(EXAMPLE_SKETCH_PATH "${LIB_SEARCH_PATH}/${LIBRARY_NAME}/examples/${EXAMPLE_NAME}") break() @@ -1866,7 +1920,7 @@ function(SETUP_ARDUINO_SIZE_SCRIPT OUTPUT_VAR) set(ARDUINO_SIZE_SCRIPT_PATH ${CMAKE_BINARY_DIR}/CMakeFiles/FirmwareSize.cmake) file(WRITE ${ARDUINO_SIZE_SCRIPT_PATH} " - set(AVRSIZE_PROGRAM ${AVRSIZE_PROGRAM}) + set(AVRSIZE_PROGRAM \"${AVRSIZE_PROGRAM}\") set(AVRSIZE_FLAGS -C --mcu=\${MCU}) execute_process(COMMAND \${AVRSIZE_PROGRAM} \${AVRSIZE_FLAGS} \${FIRMWARE_IMAGE} \${EEPROM_IMAGE} @@ -2076,30 +2130,30 @@ endfunction() # C Flags #=============================================================================# if (NOT DEFINED ARDUINO_C_FLAGS) - set(ARDUINO_C_FLAGS "-mcall-prologues -ffunction-sections -fdata-sections") + set(ARDUINO_C_FLAGS "-g -Os -w -ffunction-sections -fdata-sections -MMD") endif (NOT DEFINED ARDUINO_C_FLAGS) -set(CMAKE_C_FLAGS "-g -Os ${ARDUINO_C_FLAGS}" CACHE STRING "") -set(CMAKE_C_FLAGS_DEBUG "-g ${ARDUINO_C_FLAGS}" CACHE STRING "") -set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG ${ARDUINO_C_FLAGS}" CACHE STRING "") -set(CMAKE_C_FLAGS_RELEASE "-Os -DNDEBUG -w ${ARDUINO_C_FLAGS}" CACHE STRING "") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "-Os -g -w ${ARDUINO_C_FLAGS}" CACHE STRING "") +set(CMAKE_C_FLAGS "${ARDUINO_C_FLAGS}" CACHE STRING "") +set(CMAKE_C_FLAGS_DEBUG "${ARDUINO_C_FLAGS}" CACHE STRING "") +set(CMAKE_C_FLAGS_MINSIZEREL "${ARDUINO_C_FLAGS}" CACHE STRING "") +set(CMAKE_C_FLAGS_RELEASE "${ARDUINO_C_FLAGS}" CACHE STRING "") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${ARDUINO_C_FLAGS}" CACHE STRING "") #=============================================================================# # C++ Flags #=============================================================================# if (NOT DEFINED ARDUINO_CXX_FLAGS) - set(ARDUINO_CXX_FLAGS "${ARDUINO_C_FLAGS} -fno-exceptions") + set(ARDUINO_CXX_FLAGS "-g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD") endif (NOT DEFINED ARDUINO_CXX_FLAGS) -set(CMAKE_CXX_FLAGS "-g -Os ${ARDUINO_CXX_FLAGS}" CACHE STRING "") -set(CMAKE_CXX_FLAGS_DEBUG "-g ${ARDUINO_CXX_FLAGS}" CACHE STRING "") -set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG ${ARDUINO_CXX_FLAGS}" CACHE STRING "") -set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG ${ARDUINO_CXX_FLAGS}" CACHE STRING "") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Os -g ${ARDUINO_CXX_FLAGS}" CACHE STRING "") +set(CMAKE_CXX_FLAGS "${ARDUINO_CXX_FLAGS}" CACHE STRING "") +set(CMAKE_CXX_FLAGS_DEBUG "${ARDUINO_CXX_FLAGS}" CACHE STRING "") +set(CMAKE_CXX_FLAGS_MINSIZEREL "${ARDUINO_CXX_FLAGS}" CACHE STRING "") +set(CMAKE_CXX_FLAGS_RELEASE "${ARDUINO_CXX_FLAGS}" CACHE STRING "") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${ARDUINO_CXX_FLAGS}" CACHE STRING "") #=============================================================================# # Executable Linker Flags # #=============================================================================# -set(ARDUINO_LINKER_FLAGS "-Wl,--gc-sections -lm") +set(ARDUINO_LINKER_FLAGS "-w -Os -Wl,--gc-sections") set(CMAKE_EXE_LINKER_FLAGS "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") @@ -2140,12 +2194,14 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) find_file(ARDUINO_LIBRARIES_PATH NAMES libraries PATHS ${ARDUINO_SDK_PATH} - DOC "Path to directory containing the Arduino libraries.") + DOC "Path to directory containing the Arduino libraries." + NO_SYSTEM_ENVIRONMENT_PATH) find_file(ARDUINO_VERSION_PATH NAMES lib/version.txt PATHS ${ARDUINO_SDK_PATH} - DOC "Path to Arduino version file.") + DOC "Path to Arduino version file." + NO_SYSTEM_ENVIRONMENT_PATH) find_program(ARDUINO_AVRDUDE_PROGRAM NAMES avrdude @@ -2165,13 +2221,14 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) PATHS ${ARDUINO_SDK_PATH} /etc/avrdude /etc PATH_SUFFIXES hardware/tools hardware/tools/avr/etc - DOC "Path to avrdude programmer configuration file.") + DOC "Path to avrdude programmer configuration file." + NO_SYSTEM_ENVIRONMENT_PATH) if(NOT CMAKE_OBJCOPY) find_program(AVROBJCOPY_PROGRAM avr-objcopy) set(ADDITIONAL_REQUIRED_VARS AVROBJCOPY_PROGRAM) - set(CMAKE_OBJCOPY ${AVROBJCOPY_PROGRAM}) + set(CMAKE_OBJCOPY ${AVROBJCOPY_PROGRAM} CACHE PATH "OBJCOPY Program for firmware convertion in hex") endif(NOT CMAKE_OBJCOPY) set(ARDUINO_DEFAULT_BOARD uno CACHE STRING "Default Arduino Board ID when not specified.") @@ -2230,3 +2287,16 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) AVRSIZE_PROGRAM) endif() +if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) + set(ARDUINO_PLATFORM "AVR") +else() + if(NOT ARDUINO_PLATFORM) + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/avr) + set(ARDUINO_PLATFORM "AVR") + else() + string(TOLOWER ${ARDUINO_PLATFORM} _platform) + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/${_platform}) + endif() +endif() + + diff --git a/example/Blink/Blink.ino b/example/Blink/Blink.ino deleted file mode 100644 index acc2285..0000000 --- a/example/Blink/Blink.ino +++ /dev/null @@ -1,26 +0,0 @@ -/* - Blink - Turns on an LED on for one second, then off for one second, repeatedly. - - This example code is in the public domain. - */ - -#include "config.h" - -Test1 a; - -void setup() { - // initialize the digital pin as an output. - // Pin 13 has an LED connected on most Arduino boards: - pinMode(13, OUTPUT); - /* - This is a weird comment - //*/ -} - -void loop() { - digitalWrite(13, HIGH); // set the LED on - delay(1000); // wait for a second - digitalWrite(13, LOW); // set the LED off - delay(1000); // wait for a second -} diff --git a/example/Blink/config.h b/example/Blink/config.h deleted file mode 100644 index 453c34a..0000000 --- a/example/Blink/config.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H -class Test1 { -}; -#endif diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 2302e27..2f6be93 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,101 +1,16 @@ -# This configuration file outlines some of the ways Arduino CMake -# can be used. For a detailed explenation of all the options please -# reade README.rst. +# Set a variable for commands below +set(PROJECT_NAME example) -set(ARDUINO_DEFAULT_BOARD diecimila) # Default Board ID, when not specified -set(ARDUINO_DEFAULT_PORT /dev/ttyUSB0) # Default Port, when not specified +# Define your project and language +project(${PROJECT_NAME} C CXX) +set(${PROJECT_NAME}_BOARD pro) -#====================================================================# -# master_writer example from Wire library -#====================================================================# -generate_arduino_example(wire_example - LIBRARY Wire - EXAMPLE master_writer) +# Define the source code +set(${PROJECT_NAME}_SRCS example.cpp) -# Alternative: by vairables -#set(wire_example_LIBRARY Wire) -#set(wire_example_EXAMPLE master_writer) -# -#generate_arduino_example(wire_example) +# Define the port for uploading code to the Arduino +set(${PROJECT_NAME}_PORT COM6) - - -#====================================================================# -# Original blink sketch (from Arduino SDK examples) -#====================================================================# - -# Some installations have renamed the example directories -if (EXISTS "${ARDUINO_SDK_PATH}/examples/01.Basics/Blink") - set(BLINK_SKETCH "${ARDUINO_SDK_PATH}/examples/01.Basics/Blink") -else() - set(BLINK_SKETCH "${ARDUINO_SDK_PATH}/examples/1.Basics/Blink") -endif() - -generate_arduino_firmware(blink_original - SKETCH "${BLINK_SKETCH}" - PORT /dev/ttyACM0 - SERIAL picocom @SERIAL_PORT@ - BOARD uno) - -# Alternative: by variables -#set(blink_original_SKETCH "${BLINK_SKETCH}") -#set(blink_original_PORT /dev/ttyACM) -#set(blink_original_SERIAL picocom @SERIAL_PORT@) -#set(blink_original_BOARD uno) -# -#generate_arduino_firmware(blink_original) - - - - -#====================================================================# -# Bundled blink sketch example -#====================================================================# -generate_arduino_firmware(blink_bundled - SKETCH Blink - PROGRAMMER usbtinyisp - NO_AUTOLIBS) - -# Alternative: by variables -#set(blink_bundled_SKETCH Blink) -#set(blink_bundled_PROGRAMMER usbtinyisp) -#set(blink_bundled_NO_AUTOLIBS true) -# -#generate_arduino_firmware(blink_bundled) - - - - -#====================================================================# -# Advanced static library exmaple -#====================================================================# -generate_arduino_library(blink_lib - SRCS blink_lib.cpp - HDRS blink_lib.h - BOARD uno) - -# Alternative: by variables -#set(blink_lib_SRCS blink_lib.cpp) -#set(blink_lib_HDRS blink_lib.h) -#set(blink_lib_BOARD uno) -# -#generate_arduino_library(blink_lib) - - - - -#====================================================================# -# Advanced firwmare example -#====================================================================# -generate_arduino_firmware(blink - SRCS blink.cpp - LIBS blink_lib - BOARD uno) - -# Alternative: by variables -#set(blink_SRCS blink.cpp) -#set(blink_LIBS blink_lib) -#set(blink_BOARD uno) -# -#generate_arduino_firmware(blink) +# Command to generate code arduino firmware (.hex file) +generate_arduino_firmware(${PROJECT_NAME}) diff --git a/example/blink.cpp b/example/blink.cpp deleted file mode 100644 index f04c53c..0000000 --- a/example/blink.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - Blink - Turns on an LED on for one second, then off for one second, repeatedly. - Example uses a static library to show off generate_arduino_library(). - - This example code is in the public domain. - */ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include "blink_lib.h" - -void setup() { - blink_setup(); // Setup for blinking -} - -void loop() { - blink(1000); // Blink for a second -} diff --git a/example/blink_lib.cpp b/example/blink_lib.cpp deleted file mode 100644 index 9783a10..0000000 --- a/example/blink_lib.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include "blink_lib.h" - -void blink_setup(uint8_t pin) { - pinMode(pin, OUTPUT); -} - - -void blink(unsigned long duration, uint8_t pin) { - digitalWrite(pin, HIGH); // set the LED on - delay(duration); // wait for a second - digitalWrite(pin, LOW); // set the LED off - delay(duration); // wait for a second -} diff --git a/example/blink_lib.h b/example/blink_lib.h deleted file mode 100644 index 8f5a377..0000000 --- a/example/blink_lib.h +++ /dev/null @@ -1,17 +0,0 @@ -#include - -/** - * Setup for blinking. - * - * @param pin - pin number - **/ -void blink_setup(uint8_t pin=13); - - -/** - * Blink a single time for the specified duration. - * - * @param duration - duration in miliseconds - * @param pin - pin number - **/ -void blink(unsigned long duration, uint8_t pin=13); diff --git a/example/example.cpp b/example/example.cpp new file mode 100644 index 0000000..797a864 --- /dev/null +++ b/example/example.cpp @@ -0,0 +1,23 @@ +#include "Arduino.h" + +#define LED_PIN 13 + +void setup() { + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); + + Serial.begin(9600); +} + +void loop() { + Serial.println("Example arduino project in CLion"); + + for (int i = 0; i < 2; i++) { + digitalWrite(LED_PIN, HIGH); + delay(100); + digitalWrite(LED_PIN, LOW); + delay(100); + } + + delay(1000); +} From d6a94db83e8176f380e117f482b23ff2cd474e9d Mon Sep 17 00:00:00 2001 From: Altex Date: Thu, 23 Apr 2015 16:35:11 +0300 Subject: [PATCH 02/29] Misspelling fixed --- README.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.txt b/README.txt index 1c26a4d..44fbba3 100644 --- a/README.txt +++ b/README.txt @@ -2,8 +2,8 @@ Arduino Cmake Example Project =============================== Здесь находится проект с примером настроек cmake для работы с arduino. -Исправно загружается и работает в CLion и Windows, используя в качестве -toolchain из Arduino IDE 1.6+ и MinGW. +Исправно загружается и работает в CLion и Windows, используя toolchain +из Arduino IDE 1.6+ и MinGW. Оригинальный код проекта распространяется под лицензией Mozilla Public License, v. 2.0 http://mozilla.org/MPL/2.0/ From a8926afe643739ca35eaa33547ab4aabdbe93bee Mon Sep 17 00:00:00 2001 From: Altex Date: Thu, 23 Apr 2015 22:49:43 +0300 Subject: [PATCH 03/29] Fixed misspelling --- README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 44fbba3..61b33d1 100644 --- a/README.txt +++ b/README.txt @@ -96,7 +96,7 @@ http://habrahabr.ru/post/247017/ Портирование вашего проекта из Arduino IDE ----------------------------------- -Предположим у вас есть свой проект, с названием Robot и файлами +Предположим, у вас есть свой проект, с названием Robot и файлами - /Robot.ino - /Chassis.cpp - /Chassis.h From 8d5deb570f42457b2e00a0f2eb7f143d2e8392ba Mon Sep 17 00:00:00 2001 From: Altex Date: Mon, 11 May 2015 16:49:08 +0300 Subject: [PATCH 04/29] Fixed misspelling --- README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.txt b/README.txt index 61b33d1..9986f77 100644 --- a/README.txt +++ b/README.txt @@ -156,7 +156,7 @@ http://habrahabr.ru/post/247017/ потому что для UNO нет выбора процессоров # (закомментировали) set(ARDUINO_CPU 16MHzatmega328) -Подключаем нужно папку, меняем example на robot +Подключаем нужную папку, меняем example на robot # (закомментировали) add_subdirectory(example) add_subdirectory(robot) From 9f4b7498f476ffb6225f8304040106a611ed61d3 Mon Sep 17 00:00:00 2001 From: Altex Date: Fri, 15 May 2015 15:37:13 +0300 Subject: [PATCH 05/29] Updated readme for other OS --- README.txt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/README.txt b/README.txt index 9986f77..c62ca36 100644 --- a/README.txt +++ b/README.txt @@ -2,15 +2,17 @@ Arduino Cmake Example Project =============================== Здесь находится проект с примером настроек cmake для работы с arduino. -Исправно загружается и работает в CLion и Windows, используя toolchain -из Arduino IDE 1.6+ и MinGW. +Корректно загружается и работает в CLion, используя toolchain +из Arduino IDE 1.6+. + +Протестированные настройки работают на Windows и MinGW, но всё так же +должно работать на linux и mac со стандартными пакетами cmake/make. Оригинальный код проекта распространяется под лицензией Mozilla Public License, v. 2.0 http://mozilla.org/MPL/2.0/ Список авторов и контрибьюторов оригинального проекта -описан в оригинальном readme: -/README.original.rst +описан в /README.original.rst Полезные ссылки ------------------------------- @@ -59,6 +61,9 @@ http://habrahabr.ru/post/247017/ ----------------------------------- 1. Установить MinGW (нужно для CLion, добавляет make, g++, cpp) +Этот пункт нужен только для установки на windows. Под другим OS его нужно пропустить +и переходить к следующему пункту - "Установка CLion". + 1.1. Установить MinGW http://sourceforge.net/projects/mingw/files/Installer/ Тестировалось на версии mingw-get-0.6.2-mingw32-beta-20131004-1 @@ -91,6 +96,10 @@ http://habrahabr.ru/post/247017/ - Env: MinGW "c:\mingw" - cmake: "bundled cmake" +Пункт MinGW доступен только в windows, поэтому для других OS меню с настройками +будет проще, и скорее всего сдесь вообще ничего не придётся менять, и всё будет +работать из коробки. + После этого cmake должен правильно собирать проект. Всё, что для этого потребуется - это открыть проект в CLion. @@ -147,6 +156,8 @@ http://habrahabr.ru/post/247017/ Выбираем правильный вариант процессора для платы Это название берётся из файла C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt +Этот пусть для windows, а для других платформ будет другой путь, +но похожий на "hardware\arduino\avr\boards.txt". Пример 1. Для Arduino Pro 16Mhz 5V ATmega 328 нужно смотреть строчку "pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)" From f8ca0e25a5df7c9ac1916243fa5447af34c195b3 Mon Sep 17 00:00:00 2001 From: Altex Date: Fri, 15 May 2015 20:03:43 +0300 Subject: [PATCH 06/29] wip --- README.russian.txt | 176 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 README.russian.txt diff --git a/README.russian.txt b/README.russian.txt new file mode 100644 index 0000000..c62ca36 --- /dev/null +++ b/README.russian.txt @@ -0,0 +1,176 @@ +Arduino Cmake Example Project +=============================== + +Здесь находится проект с примером настроек cmake для работы с arduino. +Корректно загружается и работает в CLion, используя toolchain +из Arduino IDE 1.6+. + +Протестированные настройки работают на Windows и MinGW, но всё так же +должно работать на linux и mac со стандартными пакетами cmake/make. + +Оригинальный код проекта распространяется под лицензией +Mozilla Public License, v. 2.0 http://mozilla.org/MPL/2.0/ + +Список авторов и контрибьюторов оригинального проекта +описан в /README.original.rst + +Полезные ссылки +------------------------------- +Оригинальный проект находится по адресу +https://github.com/queezythegreat/arduino-cmake + +В текущем же репозитории находится его копия с наложенными патчами, +взятыми из pull requests отсюда +https://github.com/queezythegreat/arduino-cmake/pulls +и написанными мной патчами, закрывающими ряд багов, +и добавляющими ряд фич. + +Некоторые примеры настроек проекта для CLion взяты из статьи +http://habrahabr.ru/post/247017/ + +Изменения по сравнению с оригиналом +------------------------------- +1. Наложен патч "Adding support for SDK 1.5" + https://github.com/queezythegreat/arduino-cmake/pull/104 + Добавлена поддержка Arduino 1.5-1.6. + +2. Наложен патч "fixed bug in find_file method" + https://github.com/queezythegreat/arduino-cmake/pull/109 + Стандартные пути окружения windows не учитываются при поиске Arduino IDE. + +3. Наложен патч "Fix CMP0038 warnings on CMake >= 3.0" + https://github.com/queezythegreat/arduino-cmake/pull/143 + +4. Исправлены пути windows для того, чтобы avr-size писал размер + скомпиллированного бинарника при сборке. + +5. Исправлены пути, по которым ищутся настройки в boards.txt для остальных + плат кроме mega, так как заливка скетча работала только с mega, так как + неверно определялся программатор. + +6. Все опции сборки взяты по максимому из оригинальной IDE, и скорее всего + сделано не оптимально и требует более детального анализа. + +7. Убрал различия между всеми видами сборки, и это деструктивное изменение, + которое не нужно мёрджить с основным проектом. Я так сделал потому-что + не стал разбираться как лучше всего выбрать опции и для каких режимов (debug, release). + +8. Оригинальный Readme сохранён в README.original.rst + +Установка CLion + Arduino IDE + MinGW +----------------------------------- +1. Установить MinGW (нужно для CLion, добавляет make, g++, cpp) + +Этот пункт нужен только для установки на windows. Под другим OS его нужно пропустить +и переходить к следующему пункту - "Установка CLion". + +1.1. Установить MinGW + http://sourceforge.net/projects/mingw/files/Installer/ + Тестировалось на версии mingw-get-0.6.2-mingw32-beta-20131004-1 + +1.2. Запустить MinGW Installation Manager + +1.3. Выбрать пакеты из "Basic Setup" + - mingw-developer-toolkit + - mingw32-base + - mingw32-gcc-g++ + - msys-base +и нажать "Apply Changes" + +2. Установить Arduino IDE 1.6 (нужен для сборки проекта, включает avr toolchain) + http://www.arduino.cc/en/Main/OldSoftwareReleases + Тестировалось на версии 1.6.3 + +3. Установить и настроить JetBrains CLion 1.0 + +3.1. Установить JetBrains CLion 1.0 + https://www.jetbrains.com/clion/ + Тестировалось на версии 1.0 + +3.2. Запустить CLion + +3.3. Настроить toolchain + Меню настроек "File" -> "Settings" + Выбрать "Build, Execudion, Deployment" -> "Toolchain" + Дальше сконфигурировать + - Env: MinGW "c:\mingw" + - cmake: "bundled cmake" + +Пункт MinGW доступен только в windows, поэтому для других OS меню с настройками +будет проще, и скорее всего сдесь вообще ничего не придётся менять, и всё будет +работать из коробки. + +После этого cmake должен правильно собирать проект. +Всё, что для этого потребуется - это открыть проект в CLion. + +Портирование вашего проекта из Arduino IDE +----------------------------------- +Предположим, у вас есть свой проект, с названием Robot и файлами +- /Robot.ino +- /Chassis.cpp +- /Chassis.h +который уже работает в Arduino IDE, и вы хотите его перенести в CLion. + +1. Создаём новый проект с названием arduino-cmake-robot + git clone {THIS_REPO} arduino-cmake-robot +Нам больше не потребуется связь с оригинальным проектом, +мы в дальнейшем будем работать со своим репозиторием. + git remote rm origin + +2. Копируем файлы проекта Robot +Создаём папку /robot в корне нового проекта. +Копируем файлы в эту папку, теперь у нас три новых файла в новом проекте + - /robot/Robot.ino + - /robot/Chassis.cpp + - /robot/Chassis.h + +3. Переименовываем Robot.ino в robot.cpp +Теперь у нас старые файлы в новом проекте с такими названиями + - /robot/robot.cpp + - /robot/Chassis.cpp + - /robot/Chassis.h + +4. Подключаем стандартную библиотеку Arduino +Добавляем в /robot/robot.cpp первой строчкой + #include "Arduino.h" + +5. Создаём файл с настройками сборки проекта +Копируем /example/CMakeLists.txt в /robot/CMakeLists.txt + +6. Настраиваем CMakeLists.txt проекта robot (/robot/CMakeLists.txt) +Указываем название проекта + set(PROJECT_NAME robot) + +Указываем название платформы, под которую собираем. +Пример 1. Для примера это Arduino Pro (Arduino Pro Mini) + set(${PROJECT_NAME}_BOARD pro) +Пример 2. Для Arduino UNO это бы выглядело так + set(${PROJECT_NAME}_BOARD uno) + +Указываем название файла, который раньше был с расширением INO + set(${PROJECT_NAME}_SRCS robot.cpp) +Указываем нужный COM порт, к которому подключается плата + set(${PROJECT_NAME}_PORT COM3) + +7. Настраиваем корневой CMakeLists.txt (/CMakeLists.txt) +Выбираем правильный вариант процессора для платы +Это название берётся из файла + C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt +Этот пусть для windows, а для других платформ будет другой путь, +но похожий на "hardware\arduino\avr\boards.txt". + +Пример 1. Для Arduino Pro 16Mhz 5V ATmega 328 +нужно смотреть строчку "pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)" +и брать соответствующий идентификатор "16MHzatmega328", а не название "ATmega328 (5V, 16 MHz)" + set(ARDUINO_CPU 16MHzatmega328) +Пример 2. Для Arduino UNO нужно ничего не указывать, просто закомментировать строчку, +потому что для UNO нет выбора процессоров + # (закомментировали) set(ARDUINO_CPU 16MHzatmega328) + +Подключаем нужную папку, меняем example на robot + # (закомментировали) add_subdirectory(example) + add_subdirectory(robot) + +8. Открываем проект в CLion и выбираем опцию сборки robot (для компилляции) +или robot_upload (для компилляции и закрузки). +Собираем проект (CTRL+F9). Проект загружается на плату. From dcc44001b9fc4c3efe8dccc7e1cb6d794762137e Mon Sep 17 00:00:00 2001 From: Altex Date: Fri, 15 May 2015 20:04:31 +0300 Subject: [PATCH 07/29] wip --- README.russian.txt => README.russian.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README.russian.txt => README.russian.rst (100%) diff --git a/README.russian.txt b/README.russian.rst similarity index 100% rename from README.russian.txt rename to README.russian.rst From 6b6dd077a9eb207239e30f6824f7f422b87a5b08 Mon Sep 17 00:00:00 2001 From: Altex Date: Thu, 21 May 2015 00:19:39 +0300 Subject: [PATCH 08/29] Fixed path settings for MacOS and Arduino IDE 1.6+ --- cmake/ArduinoToolchain.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/ArduinoToolchain.cmake b/cmake/ArduinoToolchain.cmake index 164f004..a1dfc34 100644 --- a/cmake/ArduinoToolchain.cmake +++ b/cmake/ArduinoToolchain.cmake @@ -69,6 +69,7 @@ endif() find_path(ARDUINO_SDK_PATH NAMES lib/version.txt PATH_SUFFIXES share/arduino + Arduino.app/Contents/Java/ Arduino.app/Contents/Resources/Java/ ${ARDUINO_PATHS} HINTS ${SDK_PATH_HINTS} From 359f4567ca50085eda97a7c2fc073a0a80b725b1 Mon Sep 17 00:00:00 2001 From: Altex Date: Sun, 30 Aug 2015 12:17:01 +0300 Subject: [PATCH 09/29] Fixed arduino.cmake for arduino nano --- cmake/Platform/Arduino.cmake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 979569b..8354855 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -819,7 +819,20 @@ function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) endif() # output - set(COMPILE_FLAGS "-DF_CPU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu} -DARDUINO=${ARDUINO_VERSION_DEFINE} -DARDUINO_${${BOARD_ID}.build.board} -DARDUINO_ARCH_AVR -mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") + set(COMPILE_FLAGS "") + + if(${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -DF_CPU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu}") + else() + if(${BOARD_ID}.build.f_cpu) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -DF_CPU=${${BOARD_ID}.build.f_cpu}") + else() + message(FATAL_ERROR "Can not find f_cpu in boards.txt for Arduino board ID (${BOARD_ID}), aborting.") + endif() + endif() + + set(COMPILE_FLAGS "${COMPILE_FLAGS} -DARDUINO=${ARDUINO_VERSION_DEFINE} -DARDUINO_${${BOARD_ID}.build.board} -DARDUINO_ARCH_AVR -mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") + if(DEFINED ${BOARD_ID}.build.vid) set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}") endif() From 7208928b5fe8b93b16ea49bdcb55d32092164f6e Mon Sep 17 00:00:00 2001 From: Altex Date: Wed, 2 Sep 2015 19:55:13 +0300 Subject: [PATCH 10/29] Added english readme --- README.english.rst | 174 ++++++++++++++++++++++++++++++++++++++++++++ README.russian.rst | 176 --------------------------------------------- README.txt | 6 +- 3 files changed, 178 insertions(+), 178 deletions(-) create mode 100644 README.english.rst delete mode 100644 README.russian.rst diff --git a/README.english.rst b/README.english.rst new file mode 100644 index 0000000..9806524 --- /dev/null +++ b/README.english.rst @@ -0,0 +1,174 @@ +Arduino Cmake Example Project +=============================== + +This is the Cmake project settings for the Arduino platform. +You can use this project as an example to develop C++ programs +in JetBrains CLion IDE for Arduino and using toolchain from +Arduino IDE 1.6+. + +This project correctly works and tested in Windows with MinGW, +but it should work in linux and mac with standard cmake/make pakages. + +Original cmake project is licensed with +Mozilla Public License, v. 2.0 http://mozilla.org/MPL/2.0/ + +Readme from the original project is moved to /README.original.rst. +You can find all the authors and contributors there. + +Usefull links +------------------------------- +Original project URI: https://github.com/queezythegreat/arduino-cmake + +Current project is it's fork with patches from pull requests +https://github.com/queezythegreat/arduino-cmake/pulls +and with my patches that fixes some major and minor bugs +as long as adds other new features. + +Some examples are taken from this article http://habrahabr.ru/post/247017/ + +Differencies between this project and original one +------------------------------- +1. Added patch "Adding support for SDK 1.5" + https://github.com/queezythegreat/arduino-cmake/pull/104 + Added support for Arduino IDE 1.5-1.6+. + +2. Added patch "fixed bug in find_file method" + https://github.com/queezythegreat/arduino-cmake/pull/109 + Now cmake project does not search for arduino toolchain + files in standard windows paths. + +3. Added patch "Fix CMP0038 warnings on CMake >= 3.0" + https://github.com/queezythegreat/arduino-cmake/pull/143 + Removed warnings. + +4. Fixed windows paths to avr-size command. Now we can see the size of the compiled arduino program. + +5. Fixed parsing of the boards.txt settings that are used for compilation of the boards (that differs from arduino mega). + +6. All compilation settings are taken from original Arduino IDE. + But i dont think i've done it the best way so you can try do better if you want. + +7. Removed any differences between all build flavors (debug, release, etc). This is descructive difference between this fork + and original project, that is why you should not try to merge this fork into original project. + I make it because i dont have enough experience in finding the best compile options for these different build types. + So now it uses original Arduino IDE options. + +8. Original Readme is saved in README.original.rst + +Installing CLion + Arduino IDE + MinGW +----------------------------------- +1. Install MinGW (needed for CLion, includes make, g++, cpp) + +This is needed only for windows. In different OS'es you should skip this and continue to +the next - "2. Install Arduino IDE". + +1.1. Installing MinGW + http://sourceforge.net/projects/mingw/files/Installer/ + Tested on version mingw-get-0.6.2-mingw32-beta-20131004-1 + +1.2. Run MinGW Installation Manager + +1.3. Choose packages from "Basic Setup" + - mingw-developer-toolkit + - mingw32-base + - mingw32-gcc-g++ + - msys-base +and push "Apply Changes" + +2. Install Arduino IDE 1.6 (needed for building the project, includes avr toolchain) + http://www.arduino.cc/en/Main/OldSoftwareReleases + Tested on version 1.6.3 + +3. Install and setup JetBrains CLion 1.0 + +3.1. Install JetBrains CLion 1.0 + https://www.jetbrains.com/clion/ + Test on version 1.0 + +3.2. Run CLion + +3.3. Setup toolchain + Menu settings "File" -> "Settings" + Choose "Build, Execudion, Deployment" -> "Toolchain" + Setup + - Env: MinGW "c:\mingw" + - cmake: "bundled cmake" + +MinGW option only exists in windows. + +All is done, you can open project in CLion. + +How to move you existing project from Arduino IDE +----------------------------------- + +For example, you have your own project named Robot with the following files +- /Robot.ino +- /Chassis.cpp +- /Chassis.h +that already works in Arduino IDE, and you want to move it to CLion IDE. + +1. Make new project with name arduino-cmake-robot +Clone this repository: + git clone {THIS_REPO_URI} arduino-cmake-robot + +We do not need origin any more, we will use our own project repository. +Remove origin: + git remote rm origin + +2. Copy our existing project files Robot +Make folder /robot in the root of new project. +Copy files into this folder. Now we have 3 new files in new project + - /robot/Robot.ino + - /robot/Chassis.cpp + - /robot/Chassis.h + +3. Rename Robot.ino into robot.cpp +Now our new files and folders structure is like the following: + - /robot/robot.cpp + - /robot/Chassis.cpp + - /robot/Chassis.h + +4. Add standard Arduino library +Add the following line before the very first line of the /robot/robot.cpp file + #include "Arduino.h" + +5. Make file with cmake build settings +Copy /example/CMakeLists.txt into /robot/CMakeLists.txt + +6. Setup CMakeLists.txt for "robot" project (/robot/CMakeLists.txt) +Set up the name of the project + set(PROJECT_NAME robot) + +Set up the target platform. +Example 1. For Arduino Pro (Arduino Pro Mini) it should look like this + set(${PROJECT_NAME}_BOARD pro) +Example 2. For Arduino UNO + set(${PROJECT_NAME}_BOARD uno) + +Set up the name of the file, that was previously with INO extension + set(${PROJECT_NAME}_SRCS robot.cpp) +Set up target COM port, which is connect to the board + set(${PROJECT_NAME}_PORT COM3) + +7. Set up root folder CMakeLists.txt (/CMakeLists.txt) +Choose correct CPU option for the board. +This name is located in the file + C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt +This is windows path. For other OS'es it will look similar to +"hardware\arduino\avr\boards.txt". + +Example 1. For Arduino Pro 16Mhz 5V ATmega 328 +we can file the line "pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)" +and than take correct CPU ID "16MHzatmega328", but not the value "ATmega328 (5V, 16 MHz)" + set(ARDUINO_CPU 16MHzatmega328) +Example 2. For Arduino UNO where is no need to define anything, just comment out the CPU ID line, +because Arduino UNO does not have different CPU options + # (commented) set(ARDUINO_CPU 16MHzatmega328) + +Add project folder, change "example" to "robot" + # (commented) add_subdirectory(example) + add_subdirectory(robot) + +8. Open project in CLion IDE and choose build option "robot" (for compilation only) +or "robot_upload" (for compilation and upload). +Build project (CTRL+F9). After that project starts to build and upload to the Arduino board. diff --git a/README.russian.rst b/README.russian.rst deleted file mode 100644 index c62ca36..0000000 --- a/README.russian.rst +++ /dev/null @@ -1,176 +0,0 @@ -Arduino Cmake Example Project -=============================== - -Здесь находится проект с примером настроек cmake для работы с arduino. -Корректно загружается и работает в CLion, используя toolchain -из Arduino IDE 1.6+. - -Протестированные настройки работают на Windows и MinGW, но всё так же -должно работать на linux и mac со стандартными пакетами cmake/make. - -Оригинальный код проекта распространяется под лицензией -Mozilla Public License, v. 2.0 http://mozilla.org/MPL/2.0/ - -Список авторов и контрибьюторов оригинального проекта -описан в /README.original.rst - -Полезные ссылки -------------------------------- -Оригинальный проект находится по адресу -https://github.com/queezythegreat/arduino-cmake - -В текущем же репозитории находится его копия с наложенными патчами, -взятыми из pull requests отсюда -https://github.com/queezythegreat/arduino-cmake/pulls -и написанными мной патчами, закрывающими ряд багов, -и добавляющими ряд фич. - -Некоторые примеры настроек проекта для CLion взяты из статьи -http://habrahabr.ru/post/247017/ - -Изменения по сравнению с оригиналом -------------------------------- -1. Наложен патч "Adding support for SDK 1.5" - https://github.com/queezythegreat/arduino-cmake/pull/104 - Добавлена поддержка Arduino 1.5-1.6. - -2. Наложен патч "fixed bug in find_file method" - https://github.com/queezythegreat/arduino-cmake/pull/109 - Стандартные пути окружения windows не учитываются при поиске Arduino IDE. - -3. Наложен патч "Fix CMP0038 warnings on CMake >= 3.0" - https://github.com/queezythegreat/arduino-cmake/pull/143 - -4. Исправлены пути windows для того, чтобы avr-size писал размер - скомпиллированного бинарника при сборке. - -5. Исправлены пути, по которым ищутся настройки в boards.txt для остальных - плат кроме mega, так как заливка скетча работала только с mega, так как - неверно определялся программатор. - -6. Все опции сборки взяты по максимому из оригинальной IDE, и скорее всего - сделано не оптимально и требует более детального анализа. - -7. Убрал различия между всеми видами сборки, и это деструктивное изменение, - которое не нужно мёрджить с основным проектом. Я так сделал потому-что - не стал разбираться как лучше всего выбрать опции и для каких режимов (debug, release). - -8. Оригинальный Readme сохранён в README.original.rst - -Установка CLion + Arduino IDE + MinGW ------------------------------------ -1. Установить MinGW (нужно для CLion, добавляет make, g++, cpp) - -Этот пункт нужен только для установки на windows. Под другим OS его нужно пропустить -и переходить к следующему пункту - "Установка CLion". - -1.1. Установить MinGW - http://sourceforge.net/projects/mingw/files/Installer/ - Тестировалось на версии mingw-get-0.6.2-mingw32-beta-20131004-1 - -1.2. Запустить MinGW Installation Manager - -1.3. Выбрать пакеты из "Basic Setup" - - mingw-developer-toolkit - - mingw32-base - - mingw32-gcc-g++ - - msys-base -и нажать "Apply Changes" - -2. Установить Arduino IDE 1.6 (нужен для сборки проекта, включает avr toolchain) - http://www.arduino.cc/en/Main/OldSoftwareReleases - Тестировалось на версии 1.6.3 - -3. Установить и настроить JetBrains CLion 1.0 - -3.1. Установить JetBrains CLion 1.0 - https://www.jetbrains.com/clion/ - Тестировалось на версии 1.0 - -3.2. Запустить CLion - -3.3. Настроить toolchain - Меню настроек "File" -> "Settings" - Выбрать "Build, Execudion, Deployment" -> "Toolchain" - Дальше сконфигурировать - - Env: MinGW "c:\mingw" - - cmake: "bundled cmake" - -Пункт MinGW доступен только в windows, поэтому для других OS меню с настройками -будет проще, и скорее всего сдесь вообще ничего не придётся менять, и всё будет -работать из коробки. - -После этого cmake должен правильно собирать проект. -Всё, что для этого потребуется - это открыть проект в CLion. - -Портирование вашего проекта из Arduino IDE ------------------------------------ -Предположим, у вас есть свой проект, с названием Robot и файлами -- /Robot.ino -- /Chassis.cpp -- /Chassis.h -который уже работает в Arduino IDE, и вы хотите его перенести в CLion. - -1. Создаём новый проект с названием arduino-cmake-robot - git clone {THIS_REPO} arduino-cmake-robot -Нам больше не потребуется связь с оригинальным проектом, -мы в дальнейшем будем работать со своим репозиторием. - git remote rm origin - -2. Копируем файлы проекта Robot -Создаём папку /robot в корне нового проекта. -Копируем файлы в эту папку, теперь у нас три новых файла в новом проекте - - /robot/Robot.ino - - /robot/Chassis.cpp - - /robot/Chassis.h - -3. Переименовываем Robot.ino в robot.cpp -Теперь у нас старые файлы в новом проекте с такими названиями - - /robot/robot.cpp - - /robot/Chassis.cpp - - /robot/Chassis.h - -4. Подключаем стандартную библиотеку Arduino -Добавляем в /robot/robot.cpp первой строчкой - #include "Arduino.h" - -5. Создаём файл с настройками сборки проекта -Копируем /example/CMakeLists.txt в /robot/CMakeLists.txt - -6. Настраиваем CMakeLists.txt проекта robot (/robot/CMakeLists.txt) -Указываем название проекта - set(PROJECT_NAME robot) - -Указываем название платформы, под которую собираем. -Пример 1. Для примера это Arduino Pro (Arduino Pro Mini) - set(${PROJECT_NAME}_BOARD pro) -Пример 2. Для Arduino UNO это бы выглядело так - set(${PROJECT_NAME}_BOARD uno) - -Указываем название файла, который раньше был с расширением INO - set(${PROJECT_NAME}_SRCS robot.cpp) -Указываем нужный COM порт, к которому подключается плата - set(${PROJECT_NAME}_PORT COM3) - -7. Настраиваем корневой CMakeLists.txt (/CMakeLists.txt) -Выбираем правильный вариант процессора для платы -Это название берётся из файла - C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt -Этот пусть для windows, а для других платформ будет другой путь, -но похожий на "hardware\arduino\avr\boards.txt". - -Пример 1. Для Arduino Pro 16Mhz 5V ATmega 328 -нужно смотреть строчку "pro.menu.cpu.16MHzatmega328=ATmega328 (5V, 16 MHz)" -и брать соответствующий идентификатор "16MHzatmega328", а не название "ATmega328 (5V, 16 MHz)" - set(ARDUINO_CPU 16MHzatmega328) -Пример 2. Для Arduino UNO нужно ничего не указывать, просто закомментировать строчку, -потому что для UNO нет выбора процессоров - # (закомментировали) set(ARDUINO_CPU 16MHzatmega328) - -Подключаем нужную папку, меняем example на robot - # (закомментировали) add_subdirectory(example) - add_subdirectory(robot) - -8. Открываем проект в CLion и выбираем опцию сборки robot (для компилляции) -или robot_upload (для компилляции и закрузки). -Собираем проект (CTRL+F9). Проект загружается на плату. diff --git a/README.txt b/README.txt index c62ca36..6fee9a1 100644 --- a/README.txt +++ b/README.txt @@ -1,6 +1,8 @@ Arduino Cmake Example Project =============================== +English readme: /README.english.rst + Здесь находится проект с примером настроек cmake для работы с arduino. Корректно загружается и работает в CLion, используя toolchain из Arduino IDE 1.6+. @@ -62,7 +64,7 @@ http://habrahabr.ru/post/247017/ 1. Установить MinGW (нужно для CLion, добавляет make, g++, cpp) Этот пункт нужен только для установки на windows. Под другим OS его нужно пропустить -и переходить к следующему пункту - "Установка CLion". +и переходить к следующему пункту - "2. Установка Arduino IDE". 1.1. Установить MinGW http://sourceforge.net/projects/mingw/files/Installer/ @@ -156,7 +158,7 @@ http://habrahabr.ru/post/247017/ Выбираем правильный вариант процессора для платы Это название берётся из файла C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt -Этот пусть для windows, а для других платформ будет другой путь, +Этот путь для windows, а для других платформ будет другой путь, но похожий на "hardware\arduino\avr\boards.txt". Пример 1. Для Arduino Pro 16Mhz 5V ATmega 328 From a57e164aa2dc7f2b22a7219a4cbcbcd656611341 Mon Sep 17 00:00:00 2001 From: Altex Date: Wed, 2 Sep 2015 19:57:09 +0300 Subject: [PATCH 11/29] Fixed file name --- README.english.rst => README.english.txt | 0 README.txt | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename README.english.rst => README.english.txt (100%) diff --git a/README.english.rst b/README.english.txt similarity index 100% rename from README.english.rst rename to README.english.txt diff --git a/README.txt b/README.txt index 6fee9a1..1c6f06e 100644 --- a/README.txt +++ b/README.txt @@ -1,7 +1,7 @@ Arduino Cmake Example Project =============================== -English readme: /README.english.rst +English readme: /README.english.txt Здесь находится проект с примером настроек cmake для работы с arduino. Корректно загружается и работает в CLion, используя toolchain From 805637daa39c9de8add3d956e1d0d8e5fcce253f Mon Sep 17 00:00:00 2001 From: Francois Campbell Date: Wed, 20 Jan 2016 18:09:45 -0500 Subject: [PATCH 12/29] Pulled in changes from ncasaril/arduino-cmake --- cmake/ArduinoToolchain.cmake | 2 +- cmake/Platform/Arduino.cmake | 126 +++++++++++++++++++---------------- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/cmake/ArduinoToolchain.cmake b/cmake/ArduinoToolchain.cmake index a1dfc34..acda9cf 100644 --- a/cmake/ArduinoToolchain.cmake +++ b/cmake/ArduinoToolchain.cmake @@ -69,8 +69,8 @@ endif() find_path(ARDUINO_SDK_PATH NAMES lib/version.txt PATH_SUFFIXES share/arduino - Arduino.app/Contents/Java/ Arduino.app/Contents/Resources/Java/ + Arduino.app/Contents/Java/ ${ARDUINO_PATHS} HINTS ${SDK_PATH_HINTS} DOC "Arduino SDK path.") diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 8354855..ad05253 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -22,7 +22,7 @@ # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] # SKETCH # Arduino sketch [must have SRCS or SKETCH] # SRCS # Sources [must have SRCS or SKETCH] -# HDRS # Headers +# HDRS # Headers # LIBS # Libraries to link # ARDLIBS # Arduino libraries to link (Wire, Servo, SPI, etc) # PORT # Serial port (enables upload support) @@ -33,10 +33,10 @@ # MANUAL # (Advanced) Only use AVR Libc/Includes # # Here is a short example for a target named test: -# +# # generate_arduino_firmware( # NAME test -# SRCS test.cpp +# SRCS test.cpp # test2.cpp # HDRS test.h test2.h # BOARD uno) @@ -71,7 +71,7 @@ # name # The name of the firmware target [REQUIRED] # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] # SRCS # Sources [REQUIRED] -# HDRS # Headers +# HDRS # Headers # LIBS # Libraries to link # PORT # Serial port (enables upload support) # SERIAL # Serial command for serial target @@ -79,10 +79,10 @@ # AFLAGS # Avrdude flags for target # # Here is a short example for a target named test: -# +# # generate_avr_firmware( # NAME test -# SRCS test.cpp +# SRCS test.cpp # test2.cpp # HDRS test.h test2.h # BOARD uno) @@ -113,16 +113,16 @@ # name # The name of the firmware target [REQUIRED] # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] # SRCS # Sources [REQUIRED] -# HDRS # Headers +# HDRS # Headers # LIBS # Libraries to link # NO_AUTOLIBS # Disables Arduino library detection # MANUAL # (Advanced) Only use AVR Libc/Includes # # Here is a short example for a target named test: -# +# # generate_arduino_library( # NAME test -# SRCS test.cpp +# SRCS test.cpp # test2.cpp # HDRS test.h test2.h # BOARD uno) @@ -152,14 +152,14 @@ # name # The name of the firmware target [REQUIRED] # BOARD # Board name (such as uno, mega2560, ...) [REQUIRED] # SRCS # Sources [REQUIRED] -# HDRS # Headers +# HDRS # Headers # LIBS # Libraries to link # # Here is a short example for a target named test: -# +# # generate_avr_library( # NAME test -# SRCS test.cpp +# SRCS test.cpp # test2.cpp # HDRS test.h test2.h # BOARD uno) @@ -245,7 +245,7 @@ # |-- variants/ # |-- boards.txt # `-- programmers.txt -# +# # The board.txt describes the target boards and bootloaders. While # programmers.txt the programmer defintions. # @@ -291,7 +291,7 @@ include(CMakeParseArguments) #=============================================================================# -# User Functions +# User Functions #=============================================================================# #=============================================================================# @@ -373,7 +373,7 @@ function(GENERATE_ARDUINO_LIBRARY INPUT_NAME) set(INPUT_MANUAL FALSE) endif() required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") - + set(ALL_LIBS) set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS}) @@ -415,13 +415,13 @@ function(GENERATE_AVR_LIBRARY INPUT_NAME) "BOARD" # One Value Keywords "SRCS;HDRS;LIBS" # Multi Value Keywords ${ARGN}) - + if(NOT INPUT_BOARD) set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) - endif() - + endif() + required_variables(VARS INPUT_SRCS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") - + if(INPUT_HDRS) set( INPUT_HDRS "SRCS ${INPUT_HDRS}" ) endif() @@ -437,14 +437,14 @@ function(GENERATE_AVR_LIBRARY INPUT_NAME) endif() - generate_arduino_library( ${INPUT_NAME} + generate_arduino_library( ${INPUT_NAME} NO_AUTOLIBS MANUAL BOARD ${INPUT_BOARD} SRCS ${INPUT_SRCS} ${INPUT_HDRS} ${INPUT_LIBS} ) - + endfunction() #=============================================================================# @@ -483,7 +483,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) if(NOT INPUT_MANUAL) setup_arduino_core(CORE_LIB ${INPUT_BOARD}) endif() - + if(NOT "${INPUT_SKETCH}" STREQUAL "") get_filename_component(INPUT_SKETCH "${INPUT_SKETCH}" ABSOLUTE) setup_arduino_sketch(${INPUT_NAME} ${INPUT_SKETCH} ALL_SRCS) @@ -510,7 +510,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} ${LIB_INCLUDES}") endforeach() endif() - + list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_MANUAL}") @@ -518,7 +518,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) if(INPUT_PORT) setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") endif() - + if(INPUT_SERIAL) setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") endif() @@ -537,7 +537,7 @@ function(GENERATE_AVR_FIRMWARE INPUT_NAME) "BOARD;PORT;PROGRAMMER" # One Value Keywords "SERIAL;SRCS;HDRS;LIBS;AFLAGS" # Multi Value Keywords ${ARGN}) - + if(NOT INPUT_BOARD) set(INPUT_BOARD ${ARDUINO_DEFAULT_BOARD}) endif() @@ -550,7 +550,7 @@ function(GENERATE_AVR_FIRMWARE INPUT_NAME) if(NOT INPUT_PROGRAMMER) set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) endif() - + required_variables(VARS INPUT_BOARD INPUT_SRCS MSG "must define for target ${INPUT_NAME}") if(INPUT_HDRS) @@ -563,7 +563,7 @@ function(GENERATE_AVR_FIRMWARE INPUT_NAME) list(INSERT INPUT_AFLAGS 0 "AFLAGS") endif() - generate_arduino_firmware( ${INPUT_NAME} + generate_arduino_firmware( ${INPUT_NAME} NO_AUTOLIBS MANUAL BOARD ${INPUT_BOARD} @@ -574,7 +574,7 @@ function(GENERATE_AVR_FIRMWARE INPUT_NAME) ${INPUT_HDRS} ${INPUT_LIBS} ${INPUT_AFLAGS} ) - + endfunction() #=============================================================================# @@ -626,13 +626,13 @@ function(GENERATE_ARDUINO_EXAMPLE INPUT_NAME) setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "" "${LIB_DEP_INCLUDES}" "") list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) - + setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" FALSE) if(INPUT_PORT) setup_arduino_upload(${INPUT_BOARD} ${INPUT_NAME} ${INPUT_PORT} "${INPUT_PROGRAMMER}" "${INPUT_AFLAGS}") endif() - + if(INPUT_SERIAL) setup_serial_target(${INPUT_NAME} "${INPUT_SERIAL}" "${INPUT_PORT}") endif() @@ -726,7 +726,7 @@ function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) endfunction() #=============================================================================# -# Internal Functions +# Internal Functions #=============================================================================# #=============================================================================# @@ -795,7 +795,7 @@ endfunction() # #=============================================================================# function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) - + set(BOARD_CORE ${${BOARD_ID}.build.core}) if(BOARD_CORE) if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)[.]([0-9]+)") @@ -852,7 +852,7 @@ function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) endif() endif() - # output + # output set(${COMPILE_FLAGS_VAR} "${COMPILE_FLAGS}" PARENT_SCOPE) set(${LINK_FLAGS_VAR} "${LINK_FLAGS}" PARENT_SCOPE) @@ -906,7 +906,7 @@ endfunction() # Finds all Arduino type libraries included in sources. Available libraries # are ${ARDUINO_SDK_PATH}/libraries and ${CMAKE_CURRENT_SOURCE_DIR}. # -# Also adds Arduino libraries specifically names in ALIBS. We add ".h" to the +# Also adds Arduino libraries specifically names in ALIBS. We add ".h" to the # names and then process them just like the Arduino libraries found in the sources. # # A Arduino library is a folder that has the same name as the include header. @@ -945,7 +945,7 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) endforeach() foreach(SRC_LINE ${SRC_CONTENTS}) - if("${SRC_LINE}" MATCHES "^[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]") + if("#${SRC_LINE}#" MATCHES "^#[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]#") get_filename_component(INCLUDE_NAME ${CMAKE_MATCH_1} NAME_WE) get_property(LIBRARY_SEARCH_PATH DIRECTORY # Property Scope @@ -1000,6 +1000,9 @@ set(SPI_RECURSE True) set(SoftwareSerial_RECURSE True) set(EEPROM_RECURSE True) set(LiquidCrystal_RECURSE True) +set(TFT_RECURSE True) +set(WiFi_RECURSE True) +set(Robot_Control_RECURSE True) function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) set(LIB_TARGETS) set(LIB_INCLUDES) @@ -1047,7 +1050,7 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") list(APPEND LIB_INCLUDES "-I\"${LIB_PATH}\" -I\"${LIB_PATH}/src\" -I\"${LIB_PATH}/utility\"") - target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE ${LIB_TARGETS}) + target_link_libraries(${TARGET_LIB_NAME} ${BOARD_ID}_CORE) list(APPEND LIB_TARGETS ${TARGET_LIB_NAME}) endif() @@ -1225,7 +1228,7 @@ function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex:i") list(APPEND AVRDUDE_ARGS "-Ueeprom:w:${TARGET_PATH}.eep:i") add_custom_target(${UPLOAD_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} + ${ARDUINO_AVRDUDE_PROGRAM} ${AVRDUDE_ARGS} DEPENDS ${TARGET_NAME}) @@ -1247,7 +1250,7 @@ endfunction() # PROGRAMMER - programmer id # PORT - serial port # AVRDUDE_FLAGS - avrdude flags (override) -# +# # Sets up target for burning firmware via a programmer. # # The target for burning the firmware is ${TARGET_NAME}-burn . @@ -1273,7 +1276,7 @@ function(setup_arduino_programmer_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRD list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex") add_custom_target(${PROGRAMMER_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} + ${ARDUINO_AVRDUDE_PROGRAM} ${AVRDUDE_ARGS} DEPENDS ${TARGET_NAME}) endfunction() @@ -1282,7 +1285,7 @@ endfunction() # [PRIVATE/INTERNAL] # # setup_arduino_bootloader_burn(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) -# +# # TARGET_NAME - name of target to burn # BOARD_ID - board id # PROGRAMMER - programmer id @@ -1339,7 +1342,7 @@ function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRD # Create burn bootloader target add_custom_target(${BOOTLOADER_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} + ${ARDUINO_AVRDUDE_PROGRAM} ${AVRDUDE_ARGS} WORKING_DIRECTORY ${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path} DEPENDS ${TARGET_NAME}) @@ -1444,7 +1447,7 @@ function(setup_arduino_bootloader_args BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS O "-b${UPLOAD_SPEED}" # Baud rate "-P${PORT}" # Serial port "-D" # Dont erase - ) + ) list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) @@ -1509,7 +1512,7 @@ endfunction() # # VAR_NAME - Variable name where the detected version will be saved # -# Detects the Arduino SDK Version based on the revisions.txt file. The +# Detects the Arduino SDK Version based on the lib/versions.txt file. The # following variables will be generated: # # ${VAR_NAME} -> the full version (major.minor.patch) @@ -1553,7 +1556,7 @@ endfunction() # SETTINGS_PATH - File path of settings file to load. # # Load a Arduino style settings file into the cache. -# +# # Examples of this type of settings file is the boards.txt and # programmers.txt files located in ${ARDUINO_SDK}/hardware/arduino. # @@ -1582,7 +1585,7 @@ endfunction() # set(uno.SETTINGS name upload build) # List of settings for uno # set(uno.upload.SUBSETTINGS protocol maximum_size) # List of sub-settings for uno.upload # set(uno.build.SUBSETTINGS mcu core) # List of sub-settings for uno.build -# +# # The ${ENTRY_NAME}.SETTINGS variable lists all settings for the entry, while # ${ENTRY_NAME}.SUBSETTINGS variables lists all settings for a sub-setting of # a entry setting pair. @@ -1612,7 +1615,7 @@ function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH) # Add entry to main list list(APPEND ${SETTINGS_LIST} ${ENTRY_NAME}) endif() - + # Add entry setting to entry settings list if it does not exist set(ENTRY_SETTING_LIST ${ENTRY_NAME}.SETTINGS) list(GET ENTRY_NAME_TOKENS 1 ENTRY_SETTING) @@ -1656,7 +1659,7 @@ function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH) # Save setting value set(${FULL_SETTING_NAME} ${SETTING_VALUE} CACHE INTERNAL "Arduino ${ENTRY_NAME} Board setting") - + endif() endforeach() @@ -1797,7 +1800,7 @@ function(SETUP_ARDUINO_SKETCH TARGET_NAME SKETCH_PATH OUTPUT_VAR) file(GLOB SKETCH_SOURCES ${SKETCH_PATH}/*.pde ${SKETCH_PATH}/*.ino) list(REMOVE_ITEM SKETCH_SOURCES ${MAIN_SKETCH}) list(SORT SKETCH_SOURCES) - + generate_cpp_from_sketch("${MAIN_SKETCH}" "${SKETCH_SOURCES}" "${SKETCH_CPP}") # Regenerate build system if sketch changes @@ -1892,7 +1895,7 @@ function(GENERATE_CPP_FROM_SKETCH MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) # Write function prototypes file(APPEND ${SKETCH_CPP} "\n//=== START Forward: ${SKETCH_SOURCE_PATH}\n") - foreach(SKETCH_PROTOTYPE ${SKETCH_PROTOTYPES}) + foreach(SKETCH_PROTOTYPE ${SKETCH_PROTOTYPES}) string(REPLACE "\n" " " SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}") string(REPLACE "{" "" SKETCH_PROTOTYPE "${SKETCH_PROTOTYPE}") arduino_debug_msg("\tprototype: ${SKETCH_PROTOTYPE};") @@ -1906,7 +1909,7 @@ function(GENERATE_CPP_FROM_SKETCH MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) endforeach() file(APPEND ${SKETCH_CPP} "//=== END Forward: ${SKETCH_SOURCE_PATH}\n") endforeach() - + # Write Sketch CPP source get_num_lines("${SKETCH_HEAD}" HEAD_NUM_LINES) file(APPEND ${SKETCH_CPP} "#line ${HEAD_NUM_LINES} \"${MAIN_SKETCH_PATH}\"\n") @@ -2140,7 +2143,7 @@ endfunction() #=============================================================================# -# C Flags +# C Flags #=============================================================================# if (NOT DEFINED ARDUINO_C_FLAGS) set(ARDUINO_C_FLAGS "-g -Os -w -ffunction-sections -fdata-sections -MMD") @@ -2152,7 +2155,7 @@ set(CMAKE_C_FLAGS_RELEASE "${ARDUINO_C_FLAGS}" CACHE STRING "") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${ARDUINO_C_FLAGS}" CACHE STRING "") #=============================================================================# -# C++ Flags +# C++ Flags #=============================================================================# if (NOT DEFINED ARDUINO_CXX_FLAGS) set(ARDUINO_CXX_FLAGS "-g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD") @@ -2191,7 +2194,7 @@ set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STR #=============================================================================# -# Arduino Settings +# Arduino Settings #=============================================================================# set(ARDUINO_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "") @@ -2199,7 +2202,7 @@ set(ARDUINO_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "") #=============================================================================# -# Initialization +# Initialization #=============================================================================# if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/) @@ -2272,7 +2275,7 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) set(ARDUINO_SDK_VERSION_PATCH ${ARDUINO_SDK_VERSION_PATCH} CACHE STRING "Arduino SDK Patch Version") if(ARDUINO_SDK_VERSION VERSION_LESS 0.19) - message(FATAL_ERROR "Unsupported Arduino SDK (require verion 0.19 or higher)") + message(FATAL_ERROR "Unsupported Arduino SDK (require version 0.19 or higher)") endif() message(STATUS "Arduino SDK version ${ARDUINO_SDK_VERSION}: ${ARDUINO_SDK_PATH}") @@ -2308,8 +2311,19 @@ else() set(ARDUINO_PLATFORM "AVR") else() string(TOLOWER ${ARDUINO_PLATFORM} _platform) - register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/${_platform}) + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/${_platform}) endif() endif() +if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) + set(ARDUINO_PLATFORM "AVR") +else() + if(NOT ARDUINO_PLATFORM) + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/avr) + set(ARDUINO_PLATFORM "AVR") + else() + string(TOLOWER ${ARDUINO_PLATFORM} _platform) + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/${_platform}) + endif() +endif() From 4a76ced86471e7749b7af9d214e88559734bbe39 Mon Sep 17 00:00:00 2001 From: Francois Campbell Date: Wed, 20 Jan 2016 18:18:46 -0500 Subject: [PATCH 13/29] Added .DS_Store to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9c16f36..f7a97c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ .idea/ +*/.DS_Store \ No newline at end of file From 402f509f66da26f471a01c27a4fe8e812df43472 Mon Sep 17 00:00:00 2001 From: Francois Campbell Date: Wed, 20 Jan 2016 18:20:19 -0500 Subject: [PATCH 14/29] Fixed .gitignore syntax --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f7a97c2..3128818 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ build/ .idea/ -*/.DS_Store \ No newline at end of file +*.DS_Store \ No newline at end of file From 37d2cc298814a3af0e87c715be9ed8b5e5e0b363 Mon Sep 17 00:00:00 2001 From: Francois Campbell Date: Wed, 20 Jan 2016 18:46:08 -0500 Subject: [PATCH 15/29] Made the English README the default one --- README.english.txt => README.md | 0 README.txt => README.ru.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename README.english.txt => README.md (100%) rename README.txt => README.ru.md (100%) diff --git a/README.english.txt b/README.md similarity index 100% rename from README.english.txt rename to README.md diff --git a/README.txt b/README.ru.md similarity index 100% rename from README.txt rename to README.ru.md From d8cec4ccc9db778063b4343bf32407bf815598b1 Mon Sep 17 00:00:00 2001 From: Alexander Schlarb Date: Sun, 7 Feb 2016 00:33:22 +0100 Subject: [PATCH 16/29] Respect CMake include path when searching for library dependency directories --- cmake/Platform/Arduino.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index ad05253..7cb143a 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -922,6 +922,8 @@ endfunction() # #=============================================================================# function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) + get_property(include_dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) + set(ARDUINO_LIBS ) foreach(SRC ${SRCS}) @@ -950,7 +952,7 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) get_property(LIBRARY_SEARCH_PATH DIRECTORY # Property Scope PROPERTY LINK_DIRECTORIES) - foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) + foreach(LIB_SEARCH_PATH ${include_dirs} ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() @@ -959,7 +961,8 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() endif() - if(EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) + get_source_file_property(_header_generated ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1} GENERATED) + if((EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) OR ${_header_generated}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) break() endif() From 13668d99a861201defd15bb700f40b66e5aa8873 Mon Sep 17 00:00:00 2001 From: Francois Campbell Date: Wed, 17 Feb 2016 01:25:07 -0500 Subject: [PATCH 17/29] Added ino and pde files to sources to enable refactorings in CLion. They will safely be ignored by the compiler since they don't end in .c or .cpp. Added library include directories for CLion compatibility. --- cmake/Platform/Arduino.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index ad05253..33e9f5c 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -953,14 +953,17 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) foreach(LIB_SEARCH_PATH ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) + include_directories(${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() endif() if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) + include_directories(${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src) break() endif() if(EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) + include_directories(${LIB_SEARCH_PATH}) break() endif() endforeach() @@ -1798,9 +1801,13 @@ function(SETUP_ARDUINO_SKETCH TARGET_NAME SKETCH_PATH OUTPUT_VAR) # Find all sketch files file(GLOB SKETCH_SOURCES ${SKETCH_PATH}/*.pde ${SKETCH_PATH}/*.ino) + set(ALL_SRCS ${SKETCH_SOURCES}) + list(REMOVE_ITEM SKETCH_SOURCES ${MAIN_SKETCH}) list(SORT SKETCH_SOURCES) + + generate_cpp_from_sketch("${MAIN_SKETCH}" "${SKETCH_SOURCES}" "${SKETCH_CPP}") # Regenerate build system if sketch changes From dbd4fe372b9a0120325b429b3ed23c311ab3dc66 Mon Sep 17 00:00:00 2001 From: Francois Campbell Date: Wed, 17 Feb 2016 02:47:58 -0500 Subject: [PATCH 18/29] Include directories when setting up the library. Added Servo_RECURSE. --- cmake/Platform/Arduino.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index b4fb293..42c6cbf 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -955,18 +955,15 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) foreach(LIB_SEARCH_PATH ${include_dirs} ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) - include_directories(${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() endif() if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) - include_directories(${LIB_SEARCH_PATH}/${INCLUDE_NAME}/src) break() endif() get_source_file_property(_header_generated ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1} GENERATED) if((EXISTS ${LIB_SEARCH_PATH}/${CMAKE_MATCH_1}) OR ${_header_generated}) - list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}) - include_directories(${LIB_SEARCH_PATH}) + list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() endif() endforeach() @@ -1002,6 +999,7 @@ endfunction() set(Wire_RECURSE True) set(Ethernet_RECURSE True) set(SD_RECURSE True) +set(Servo_RECURSE True) set(SPI_RECURSE True) set(SoftwareSerial_RECURSE True) set(EEPROM_RECURSE True) @@ -1028,6 +1026,9 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA message(STATUS "Generating ${TARGET_LIB_NAME} for library ${LIB_NAME}") arduino_debug_msg("Generating Arduino ${LIB_NAME} library") add_library(${TARGET_LIB_NAME} STATIC ${LIB_SRCS}) + include_directories(${LIB_PATH}) + include_directories(${LIB_PATH}/src) + include_directories(${LIB_PATH}/utility) get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) From 9d333b7d4bb8a1eb29efabcf5724d33ad8624427 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Fri, 26 Jan 2018 09:33:47 +0100 Subject: [PATCH 19/29] Improve arduino settings file loading to support more types Now it supports any number of subsettings, and also single setting values like `name=Arduino` Additionally this adds a method which allows to replace variables within a settings value. E.g. `tools.avrdude.path={runtime.tools.avrdude.path}` --- cmake/Platform/Arduino.cmake | 350 ++++++++++++++++++++++++----------- 1 file changed, 246 insertions(+), 104 deletions(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 42c6cbf..76c8cbb 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -476,10 +476,22 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) endif() required_variables(VARS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") + set(PLATFORM ${${INPUT_BOARD}.PLATFORM}) + + set(ALL_LIBS) set(ALL_SRCS ${INPUT_SRCS} ${INPUT_HDRS}) set(LIB_DEP_INCLUDES) + # set predefined variable values + + set(${INPUT_NAME}.build.path ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") + set(${INPUT_NAME}.build.project_name ${INPUT_NAME} CACHE INTERNAL "") + + string(TOLOWER "${PLATFORM}" PLATFORM_LOWER) + set(${INPUT_BOARD}.build.arch "${PLATFORM_LOWER}" CACHE INTERNAL "") + + if(NOT INPUT_MANUAL) setup_arduino_core(CORE_LIB ${INPUT_BOARD}) endif() @@ -654,6 +666,19 @@ function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) set(${PLATFORM}_PLATFORM_PATH ${PLATFORM_PATH} CACHE INTERNAL "The path to ${PLATFORM}") set(ARDUINO_PLATFORMS ${ARDUINO_PLATFORMS} ${PLATFORM} CACHE INTERNAL "A list of registered platforms") + + # Set some predefined variable values as defined in + # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification + + set(${PLATFORM}.runtime.platform.path ${PLATFORM_PATH} + CACHE INTERNAL "${PLATFORM} platform path") + + GET_FILENAME_COMPONENT(HARDWARE_PATH ${PLATFORM_PATH} DIRECTORY) + set(${PLATFORM}.runtime.hardware.path ${HARDWARE_PATH} + CACHE INTERNAL "${PLATFORM} hardware path") + + + find_file(${PLATFORM}_CORES_PATH NAMES cores PATHS ${PLATFORM_PATH} @@ -690,12 +715,28 @@ function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) DOC "Path to Arduino boards definition file." NO_SYSTEM_ENVIRONMENT_PATH) + find_file(${PLATFORM}_PLATFORM_PATH + NAMES platform.txt + PATHS ${PLATFORM_PATH} + DOC "Path to Arduino platform definition file." + NO_SYSTEM_ENVIRONMENT_PATH) + if(${PLATFORM}_BOARDS_PATH) - load_arduino_style_settings(${PLATFORM}_BOARDS "${PLATFORM_PATH}/boards.txt") + load_arduino_style_settings(${PLATFORM}_BOARDS "${PLATFORM_PATH}/boards.txt" "") + + # store the platform to which the board belongs + foreach(board IN LISTS ${PLATFORM}_BOARDS) + set(${board}.PLATFORM ${PLATFORM} CACHE INTERNAL "") + endforeach() + endif() if(${PLATFORM}_PROGRAMMERS_PATH) - load_arduino_style_settings(${PLATFORM}_PROGRAMMERS "${ARDUINO_PROGRAMMERS_PATH}") + load_arduino_style_settings(${PLATFORM}_PROGRAMMERS "${PLATFORM_PATH}/programmers.txt" "") + endif() + + if(${PLATFORM}_PLATFORM_PATH) + load_arduino_style_settings(${PLATFORM}_PLATFORM "${PLATFORM_PATH}/platform.txt" ${PLATFORM}) endif() if(${PLATFORM}_VARIANTS_PATH) @@ -797,26 +838,10 @@ endfunction() function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) set(BOARD_CORE ${${BOARD_ID}.build.core}) + + set(PLATFORM ${${BOARD_ID}.PLATFORM}) + if(BOARD_CORE) - if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)[.]([0-9]+)") - string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) - set(ARDUINO_VERSION_DEFINE "") - if(CMAKE_MATCH_1 GREATER 0) - set(ARDUINO_VERSION_DEFINE "${CMAKE_MATCH_1}") - endif() - if(CMAKE_MATCH_2 GREATER 10) - set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_2}") - else() - set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}") - endif() - if(CMAKE_MATCH_3 GREATER 10) - set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_3}") - else() - set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_3}") - endif() - else() - message("Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})") - endif() # output set(COMPILE_FLAGS "") @@ -1035,9 +1060,9 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "") foreach(LIB_DEP ${LIB_DEPS}) - if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME AND DEP_LIB_SRCS) - message(STATUS "Found library ${LIB_NAME} needs ${DEP_LIB_SRCS}") - endif() + if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME AND DEP_LIB_SRCS) + message(STATUS "Found library ${LIB_NAME} needs ${DEP_LIB_SRCS}") + endif() setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} "${COMPILE_FLAGS}" "${LINK_FLAGS}") # Do not link to this library. DEP_LIB_SRCS will always be only one entry @@ -1569,9 +1594,9 @@ endfunction() # # Settings have to following format: # -# entry.setting[.subsetting] = value +# entry[.setting][.subsetting] = value # -# where [.subsetting] is optional +# where [.setting] and [.subsetting] is optional # # For example, the following settings: # @@ -1590,89 +1615,174 @@ endfunction() # set(uno.build.core "arduino") # # set(uno.SETTINGS name upload build) # List of settings for uno -# set(uno.upload.SUBSETTINGS protocol maximum_size) # List of sub-settings for uno.upload -# set(uno.build.SUBSETTINGS mcu core) # List of sub-settings for uno.build +# set(uno.upload.SETTINGS protocol maximum_size) # List of sub-settings for uno.upload +# set(uno.build.SETTINGS mcu core) # List of sub-settings for uno.build # -# The ${ENTRY_NAME}.SETTINGS variable lists all settings for the entry, while -# ${ENTRY_NAME}.SUBSETTINGS variables lists all settings for a sub-setting of -# a entry setting pair. +# The ${ENTRY_NAME}.SETTINGS variable lists all settings for the entry # # These variables are generated in order to be able to programatically traverse # all settings (for a example see print_board_settings() function). # #=============================================================================# -function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH) +function(LOAD_ARDUINO_STYLE_SETTINGS SETTINGS_LIST SETTINGS_PATH SETTINGS_PREFIX) if(NOT ${SETTINGS_LIST} AND EXISTS ${SETTINGS_PATH}) - file(STRINGS ${SETTINGS_PATH} FILE_ENTRIES) # Settings file split into lines - - foreach(FILE_ENTRY ${FILE_ENTRIES}) - if("${FILE_ENTRY}" MATCHES "^[^#]+=.*") - string(REGEX MATCH "^[^=]+" SETTING_NAME ${FILE_ENTRY}) - string(REGEX MATCH "[^=]+$" SETTING_VALUE ${FILE_ENTRY}) - string(REPLACE "." ";" ENTRY_NAME_TOKENS ${SETTING_NAME}) - string(STRIP "${SETTING_VALUE}" SETTING_VALUE) - - list(LENGTH ENTRY_NAME_TOKENS ENTRY_NAME_TOKENS_LEN) - - # Add entry to settings list if it does not exist - list(GET ENTRY_NAME_TOKENS 0 ENTRY_NAME) - list(FIND ${SETTINGS_LIST} ${ENTRY_NAME} ENTRY_NAME_INDEX) - if(ENTRY_NAME_INDEX LESS 0) - # Add entry to main list - list(APPEND ${SETTINGS_LIST} ${ENTRY_NAME}) - endif() + file(STRINGS ${SETTINGS_PATH} FILE_ENTRIES) # Settings file split into lines + + foreach(FILE_ENTRY ${FILE_ENTRIES}) + if("${FILE_ENTRY}" MATCHES "^[^#]+=.*") - # Add entry setting to entry settings list if it does not exist - set(ENTRY_SETTING_LIST ${ENTRY_NAME}.SETTINGS) - list(GET ENTRY_NAME_TOKENS 1 ENTRY_SETTING) - set(PARAMETERS 2) - if(ENTRY_SETTING STREQUAL "menu") - list(GET ENTRY_NAME_TOKENS 3 CPUNAME) - if(ENTRY_NAME_TOKENS_LEN GREATER 4) - list(GET ENTRY_NAME_TOKENS 4 PROPERTYNAME) - set(ENTRY_SETTING "menu.cpu.${CPUNAME}.${PROPERTYNAME}") - set(PARAMETERS 5) - else() - set(ENTRY_SETTING "menu.cpu.${CPUNAME}") - set(PARAMETERS 4) - endif() - list(APPEND ${ENTRY_SETTING_LIST} "${ENTRY_SETTING}") - else() - list(FIND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING} ENTRY_SETTING_INDEX) - if(ENTRY_SETTING_INDEX LESS 0) - # Add setting to entry - list(APPEND ${ENTRY_SETTING_LIST} ${ENTRY_SETTING}) - set(${ENTRY_SETTING_LIST} ${${ENTRY_SETTING_LIST}} - CACHE INTERNAL "Arduino ${ENTRY_NAME} Board settings list") - endif() - endif() - - set(FULL_SETTING_NAME ${ENTRY_NAME}.${ENTRY_SETTING}) - - # Add entry sub-setting to entry sub-settings list if it does not exists - if(ENTRY_NAME_TOKENS_LEN GREATER ${PARAMETERS}) - set(ENTRY_SUBSETTING_LIST ${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) - list(GET ENTRY_NAME_TOKENS ${PARAMETERS} ENTRY_SUBSETTING) - list(FIND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING} ENTRY_SUBSETTING_INDEX) - if(ENTRY_SUBSETTING_INDEX LESS 0) - list(APPEND ${ENTRY_SUBSETTING_LIST} ${ENTRY_SUBSETTING}) - set(${ENTRY_SUBSETTING_LIST} ${${ENTRY_SUBSETTING_LIST}} - CACHE INTERNAL "Arduino ${ENTRY_NAME} Board sub-settings list") + string(REGEX MATCH "^([^=]*)=(.*)$" SETTING_SPLIT ${FILE_ENTRY}) + if(NOT DEFINED CMAKE_MATCH_1 OR NOT DEFINED CMAKE_MATCH_2) + MESSAGE(WARNING "Invalid setting: ${FILE_ENTRY}") + continue() endif() - set(FULL_SETTING_NAME ${FULL_SETTING_NAME}.${ENTRY_SUBSETTING}) - endif() - # Save setting value - set(${FULL_SETTING_NAME} ${SETTING_VALUE} - CACHE INTERNAL "Arduino ${ENTRY_NAME} Board setting") + set(SETTING_NAME ${CMAKE_MATCH_1}) + set(SETTING_VALUE ${CMAKE_MATCH_2}) + string(REPLACE "." ";" ENTRY_NAME_TOKENS ${SETTING_NAME}) + string(STRIP "${SETTING_VALUE}" SETTING_VALUE) + + list(LENGTH ENTRY_NAME_TOKENS ENTRY_NAME_TOKENS_LEN) + + # Add entry to settings list if it does not exist + list(GET ENTRY_NAME_TOKENS 0 ENTRY_NAME) + list(FIND ${SETTINGS_LIST} ${ENTRY_NAME} ENTRY_NAME_INDEX) + if(ENTRY_NAME_INDEX LESS 0) + # Add entry to main list + list(APPEND ${SETTINGS_LIST} ${ENTRY_NAME}) + endif() + + set(FULL_SETTING_NAME "${SETTINGS_PREFIX}") + + set(ENTRY_SETTING_LIST) + + foreach(subsetting ${ENTRY_NAME_TOKENS}) + + if (FULL_SETTING_NAME STREQUAL "") + set(FULL_SETTING_NAME "${subsetting}") + else() + set(FULL_SETTING_NAME ${FULL_SETTING_NAME}.${subsetting}) + endif() + + if(ENTRY_SETTING_LIST) + list(FIND ${ENTRY_SETTING_LIST} ${subsetting} ENTRY_SETTING_INDEX) + if(ENTRY_SETTING_INDEX LESS 0) + # Add setting to entry + list(APPEND ${ENTRY_SETTING_LIST} ${subsetting}) + set(${ENTRY_SETTING_LIST} ${${ENTRY_SETTING_LIST}} + CACHE INTERNAL "${PLATFORM} ${FULL_SETTING_NAME} Board settings list") + endif() + endif() + + set(ENTRY_SETTING_LIST ${FULL_SETTING_NAME}.SETTINGS) + + endforeach() + + # Save setting value + set(${FULL_SETTING_NAME} ${SETTING_VALUE} + CACHE INTERNAL "${PLATFORM} ${ENTRY_NAME} Board setting") + endif() + endforeach() + set(${SETTINGS_LIST} ${${SETTINGS_LIST}} + CACHE STRING "List of detected ${PLATFORM} Board configurations") + mark_as_advanced(${SETTINGS_LIST}) + endif() +endfunction() + +#=============================================================================# +# [PRIVATE/INTERNAL] +# +# GET_VARIABLE_VALUE_FILLED(SETTING_VALUE BOARD_ID) +# +# VARIABLE_RETURN - The name of the return variable +# SETTING_VALUE - the value of the variable with placeholders +# BOARD_ID - the id of the board to identify the correct placeholder replacements +# +# Replace placeholders in the variable value with the defined values from +# the cache. +# E.g. +# {runtime.tools.avrdude.path} +# will be replaced accordingly +#=============================================================================# +function(GET_VARIABLE_VALUE_FILLED VARIABLE_RETURN SETTING_VALUE BOARD_ID) + set(PLATFORM ${${BOARD_ID}.PLATFORM}) + set(VARIABLE_FILLED ${SETTING_VALUE} PARENT_SCOPE) + + if (NOT SETTING_VALUE STREQUAL "") + string(REGEX MATCHALL "{([^}]+)}" VARS_REPLACE ${SETTING_VALUE}) + LIST(LENGTH VARS_REPLACE MATCH_COUNT) + if(MATCH_COUNT GREATER 0) + FOREACH(i IN LISTS VARS_REPLACE) + string(REPLACE "}" "" i ${i}) + string(REPLACE "{" "" i ${i}) + + unset(VAR_VALUE) + set(PREFIXED_NAME_PLATFORM "${PLATFORM}.${i}") + set(PREFIXED_NAME_BOARD "${BOARD_ID}.${i}") + if (DEFINED ${PREFIXED_NAME_BOARD}) + set(VAR_VALUE "${${PREFIXED_NAME_BOARD}}") + elseif(DEFINED ${PREFIXED_NAME_PLATFORM}) + set(VAR_VALUE "${${PREFIXED_NAME_PLATFORM}}") + elseif(DEFINED ${i}) + set(VAR_VALUE "${${i}}") + else() + #MESSAGE(FATAL_ERROR "${i} not found in settings") + endif() + if(DEFINED VAR_VALUE) + #recursively replace + set(TMP_FILLED "") + get_variable_value_filled(TMP_FILLED "${VAR_VALUE}" ${BOARD_ID}) + string(REPLACE "{${i}}" "${TMP_FILLED}" SETTING_VALUE ${SETTING_VALUE}) + endif() + ENDFOREACH() + set(${VARIABLE_RETURN} ${SETTING_VALUE} PARENT_SCOPE) endif() - endforeach() - set(${SETTINGS_LIST} ${${SETTINGS_LIST}} - CACHE STRING "List of detected Arduino Board configurations") - mark_as_advanced(${SETTINGS_LIST}) + endif() +endfunction() + +#=============================================================================# +# [PRIVATE/INTERNAL] +# +# GET_VARIABLE_FILLED(VARIABLE_NAME BOARD_ID) +# +# VARIABLE_RETURN - The name of the return variable +# VARIABLE_NAME - the variable from which the value should be returned +# BOARD_ID - the id of the board to identify the correct placeholder replacements +# +# Replace placeholders in the variable value with the defined values from +# the cache. +# E.g. +# GET_VARIABLE_FILLED(SOME_VAR "recipe.c.o.pattern" "${${PROJECT_NAME}_BOARD}") +# MESSAGE(STATUS "Var = ${SOME_VAR}") +#=============================================================================# +function(GET_VARIABLE_FILLED VARIABLE_RETURN VARIABLE_NAME BOARD_ID) + + set(PLATFORM ${${BOARD_ID}.PLATFORM}) + + set(PREFIXED_NAME_PLATFORM "${PLATFORM}.${VARIABLE_NAME}") + set(PREFIXED_NAME_BOARD "${BOARD_ID}.${VARIABLE_NAME}") + if (DEFINED ${PREFIXED_NAME_BOARD}) + set(SETTING_VALUE "${${PREFIXED_NAME_BOARD}}") + elseif(DEFINED ${PREFIXED_NAME_PLATFORM}) + set(SETTING_VALUE "${${PREFIXED_NAME_PLATFORM}}") + elseif(DEFINED ${VARIABLE_NAME}) + set(SETTING_VALUE "${${VARIABLE_NAME}}") + endif() + + if (NOT DEFINED SETTING_VALUE) + MESSAGE(WARNING "Variable ${VARIABLE_NAME} is not set") + endif() + + + if (NOT SETTING_VALUE STREQUAL "") + set(VARIABLE_FILLED "") + get_variable_value_filled("VARIABLE_FILLED" "${SETTING_VALUE}" "${BOARD_ID}") + set(${VARIABLE_RETURN} ${VARIABLE_FILLED} PARENT_SCOPE) + else() + set(${VARIABLE_RETURN} ${SETTING_VALUE} PARENT_SCOPE) endif() endfunction() @@ -1688,17 +1798,10 @@ function(PRINT_SETTINGS ENTRY_NAME) if(${ENTRY_NAME}.SETTINGS) foreach(ENTRY_SETTING ${${ENTRY_NAME}.SETTINGS}) - if(${ENTRY_NAME}.${ENTRY_SETTING}) + if(DEFINED ${ENTRY_NAME}.${ENTRY_SETTING}) message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}}") endif() - if(${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS) - foreach(ENTRY_SUBSETTING ${${ENTRY_NAME}.${ENTRY_SETTING}.SUBSETTINGS}) - if(${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}) - message(STATUS " ${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}=${${ENTRY_NAME}.${ENTRY_SETTING}.${ENTRY_SUBSETTING}}") - endif() - endforeach() - endif() - message(STATUS "") + print_settings("${ENTRY_NAME}.${ENTRY_SETTING}") endforeach() endif() endfunction() @@ -2314,6 +2417,45 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) AVRSIZE_PROGRAM) endif() +# Set some predefined variable values as defined in +# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification + +set(RUNTIME_IDE_PATH_VAR "runtime.ide.path") +set(${RUNTIME_IDE_PATH_VAR} ${ARDUINO_SDK_PATH} CACHE INTERNAL "") + + + +if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)[.]([0-9]+)") + string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) + set(ARDUINO_VERSION_DEFINE "") + if(CMAKE_MATCH_1 GREATER 0) + set(ARDUINO_VERSION_DEFINE "${CMAKE_MATCH_1}") + endif() + if(CMAKE_MATCH_2 GREATER 10) + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_2}") + else() + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_2}") + endif() + if(CMAKE_MATCH_3 GREATER 10) + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}${CMAKE_MATCH_3}") + else() + set(ARDUINO_VERSION_DEFINE "${ARDUINO_VERSION_DEFINE}0${CMAKE_MATCH_3}") + endif() +else() + message("Invalid Arduino SDK Version (${ARDUINO_SDK_VERSION})") +endif() + +set(runtime.ide.version ${ARDUINO_VERSION_DEFINE} CACHE INTERNAL "") + +if (WIN32) + set(runtime.os "windows" CACHE INTERNAL "") +elseif(UNIX) + set(runtime.os "linux" CACHE INTERNAL "") +elseif(APPLE) + set(runtime.os "macosx" CACHE INTERNAL "") +endif() + + if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) set(ARDUINO_PLATFORM "AVR") else() From 77b6f3de69134ca3ecbd908a2d9af5acb3482929 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Fri, 26 Jan 2018 11:00:30 +0100 Subject: [PATCH 20/29] Load automatically all hardware and platform definitions from SDK_PATH/hardware This also adds support for 3-rd party hardware definitions like espressif/esp32 Note that this does not yet add support for compiling esp32 --- CMakeLists.txt | 1 + cmake/Platform/Arduino.cmake | 154 +++++++++++++++++++++-------------- 2 files changed, 95 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1dd28d..198525a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,3 +29,4 @@ link_directories(${ARDUINO_SDK}/libraries) # add the project directory into build add_subdirectory(example) +#add_subdirectory(example_esp32) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 76c8cbb..5c3d2a1 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -656,10 +656,14 @@ endfunction() #=============================================================================# function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) string(REGEX REPLACE "/$" "" PLATFORM_PATH ${PLATFORM_PATH}) - GET_FILENAME_COMPONENT(PLATFORM ${PLATFORM_PATH} NAME) + if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) + SET(PLATFORM "AVR") + else() + GET_FILENAME_COMPONENT(PLATFORM ${PLATFORM_PATH} NAME) + string(TOUPPER ${PLATFORM} PLATFORM) + endif() if(PLATFORM) - string(TOUPPER ${PLATFORM} PLATFORM) list(FIND ARDUINO_PLATFORMS ${PLATFORM} platform_exists) if (platform_exists EQUAL -1) @@ -673,9 +677,14 @@ function(REGISTER_HARDWARE_PLATFORM PLATFORM_PATH) set(${PLATFORM}.runtime.platform.path ${PLATFORM_PATH} CACHE INTERNAL "${PLATFORM} platform path") - GET_FILENAME_COMPONENT(HARDWARE_PATH ${PLATFORM_PATH} DIRECTORY) - set(${PLATFORM}.runtime.hardware.path ${HARDWARE_PATH} - CACHE INTERNAL "${PLATFORM} hardware path") + if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) + set(${PLATFORM}.runtime.hardware.path ${PLATFORM_PATH} + CACHE INTERNAL "${PLATFORM} hardware path") + else() + GET_FILENAME_COMPONENT(HARDWARE_PATH ${PLATFORM_PATH} DIRECTORY) + set(${PLATFORM}.runtime.hardware.path ${HARDWARE_PATH} + CACHE INTERNAL "${PLATFORM} hardware path") + endif() @@ -770,6 +779,30 @@ endfunction() # Internal Functions #=============================================================================# + +#=============================================================================# +# [PRIVATE/INTERNAL] +# +# subdirlist(RESULT DIR) +# +# RESULT - Variable name of list containing all the sub directories +# DIR - Parent directory where to iterate over +# +# Gets a list of all the direct subdirectories of the given directory +# see https://stackoverflow.com/a/7788165/869402 +# +#=============================================================================# +MACRO(SUBDIRLIST result curdir) + FILE(GLOB children RELATIVE ${curdir} ${curdir}/*) + SET(dirlist "") + FOREACH(child ${children}) + IF(IS_DIRECTORY ${curdir}/${child}) + LIST(APPEND dirlist ${child}) + ENDIF() + ENDFOREACH() + SET(${result} ${dirlist}) +ENDMACRO() + #=============================================================================# # [PRIVATE/INTERNAL] # @@ -2319,13 +2352,6 @@ set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "") # Initialization #=============================================================================# if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) - register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/) - - find_file(ARDUINO_LIBRARIES_PATH - NAMES libraries - PATHS ${ARDUINO_SDK_PATH} - DOC "Path to directory containing the Arduino libraries." - NO_SYSTEM_ENVIRONMENT_PATH) find_file(ARDUINO_VERSION_PATH NAMES lib/version.txt @@ -2333,6 +2359,43 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) DOC "Path to Arduino version file." NO_SYSTEM_ENVIRONMENT_PATH) + + detect_arduino_version(ARDUINO_SDK_VERSION) + set(ARDUINO_SDK_VERSION ${ARDUINO_SDK_VERSION} CACHE STRING "Arduino SDK Version") + set(ARDUINO_SDK_VERSION_MAJOR ${ARDUINO_SDK_VERSION_MAJOR} CACHE STRING "Arduino SDK Major Version") + set(ARDUINO_SDK_VERSION_MINOR ${ARDUINO_SDK_VERSION_MINOR} CACHE STRING "Arduino SDK Minor Version") + set(ARDUINO_SDK_VERSION_PATCH ${ARDUINO_SDK_VERSION_PATCH} CACHE STRING "Arduino SDK Patch Version") + + if(ARDUINO_SDK_VERSION VERSION_LESS 0.19) + message(FATAL_ERROR "Unsupported Arduino SDK (require version 0.19 or higher)") + endif() + + message(STATUS "Arduino SDK version ${ARDUINO_SDK_VERSION}: ${ARDUINO_SDK_PATH}") + + SUBDIRLIST(HARDWARES ${ARDUINO_SDK_PATH}/hardware/) + FOREACH(hardware ${HARDWARES}) + if("${hardware}" STREQUAL "tools") + continue() + endif() + + if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) + # SDK less than 1.5 does not have architecture subfolders + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/${hardware}) + else() + SUBDIRLIST(ARCHITECTURES ${ARDUINO_SDK_PATH}/hardware/${hardware}) + FOREACH(architecture ${ARCHITECTURES}) + register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/${hardware}/${architecture}) + ENDFOREACH() + endif() + + ENDFOREACH() + + find_file(ARDUINO_LIBRARIES_PATH + NAMES libraries + PATHS ${ARDUINO_SDK_PATH} + DOC "Path to directory containing the Arduino libraries." + NO_SYSTEM_ENVIRONMENT_PATH) + find_program(ARDUINO_AVRDUDE_PROGRAM NAMES avrdude PATHS ${ARDUINO_SDK_PATH} @@ -2368,31 +2431,19 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) # Ensure that all required paths are found required_variables(VARS - ARDUINO_PLATFORMS - ARDUINO_CORES_PATH - ARDUINO_BOOTLOADERS_PATH - ARDUINO_LIBRARIES_PATH - ARDUINO_BOARDS_PATH - ARDUINO_PROGRAMMERS_PATH - ARDUINO_VERSION_PATH - ARDUINO_AVRDUDE_FLAGS - ARDUINO_AVRDUDE_PROGRAM - ARDUINO_AVRDUDE_CONFIG_PATH - AVRSIZE_PROGRAM - ${ADDITIONAL_REQUIRED_VARS} - MSG "Invalid Arduino SDK path (${ARDUINO_SDK_PATH}).\n") - - detect_arduino_version(ARDUINO_SDK_VERSION) - set(ARDUINO_SDK_VERSION ${ARDUINO_SDK_VERSION} CACHE STRING "Arduino SDK Version") - set(ARDUINO_SDK_VERSION_MAJOR ${ARDUINO_SDK_VERSION_MAJOR} CACHE STRING "Arduino SDK Major Version") - set(ARDUINO_SDK_VERSION_MINOR ${ARDUINO_SDK_VERSION_MINOR} CACHE STRING "Arduino SDK Minor Version") - set(ARDUINO_SDK_VERSION_PATCH ${ARDUINO_SDK_VERSION_PATCH} CACHE STRING "Arduino SDK Patch Version") - - if(ARDUINO_SDK_VERSION VERSION_LESS 0.19) - message(FATAL_ERROR "Unsupported Arduino SDK (require version 0.19 or higher)") - endif() - - message(STATUS "Arduino SDK version ${ARDUINO_SDK_VERSION}: ${ARDUINO_SDK_PATH}") + ARDUINO_PLATFORMS + AVR_CORES_PATH + AVR_BOOTLOADERS_PATH + ARDUINO_LIBRARIES_PATH + AVR_BOARDS_PATH + AVR_PROGRAMMERS_PATH + ARDUINO_VERSION_PATH + ARDUINO_AVRDUDE_FLAGS + ARDUINO_AVRDUDE_PROGRAM + ARDUINO_AVRDUDE_CONFIG_PATH + AVRSIZE_PROGRAM + ${ADDITIONAL_REQUIRED_VARS} + MSG "Invalid Arduino SDK path (${ARDUINO_SDK_PATH}).\n") setup_arduino_size_script(ARDUINO_SIZE_SCRIPT) set(ARDUINO_SIZE_SCRIPT ${ARDUINO_SIZE_SCRIPT} CACHE INTERNAL "Arduino Size Script") @@ -2402,12 +2453,12 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) set(ARDUINO_FOUND True CACHE INTERNAL "Arduino Found") mark_as_advanced( - ARDUINO_CORES_PATH - ARDUINO_VARIANTS_PATH - ARDUINO_BOOTLOADERS_PATH + AVR_CORES_PATH + AVR_VARIANTS_PATH + AVR_BOOTLOADERS_PATH ARDUINO_LIBRARIES_PATH - ARDUINO_BOARDS_PATH - ARDUINO_PROGRAMMERS_PATH + AVR_BOARDS_PATH + AVR_PROGRAMMERS_PATH ARDUINO_VERSION_PATH ARDUINO_AVRDUDE_FLAGS ARDUINO_AVRDUDE_PROGRAM @@ -2460,23 +2511,6 @@ if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) set(ARDUINO_PLATFORM "AVR") else() if(NOT ARDUINO_PLATFORM) - register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/avr) - set(ARDUINO_PLATFORM "AVR") - else() - string(TOLOWER ${ARDUINO_PLATFORM} _platform) - register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/${_platform}) + set(ARDUINO_PLATFORM "AVR") endif() endif() - -if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) - set(ARDUINO_PLATFORM "AVR") -else() - if(NOT ARDUINO_PLATFORM) - register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/avr) - set(ARDUINO_PLATFORM "AVR") - else() - string(TOLOWER ${ARDUINO_PLATFORM} _platform) - register_hardware_platform(${ARDUINO_SDK_PATH}/hardware/arduino/${_platform}) - endif() -endif() - From d090c628930136af8eda11c745ac3849776c4841 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Tue, 30 Jan 2018 13:37:55 +0100 Subject: [PATCH 21/29] Use config files and recipes to generate Arduino burn and compile commands --- CMakeLists.txt | 3 +- cmake/ArduinoToolchain.cmake | 13 +- cmake/Platform/Arduino.cmake | 560 +++++++++++++++-------------------- example/CMakeLists.txt | 5 +- 4 files changed, 250 insertions(+), 331 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 198525a..a0aba17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,6 @@ # and this line should go before call to "cmake/ArduinoToolchain.cmake" # this is durty hack and should be fixed somewhen, because it should go to # particular cmake subdirectory -set(ARDUINO_CPU 16MHzatmega328) set(CMAKE_TOOLCHAIN_FILE cmake/ArduinoToolchain.cmake) # Arduino Toolchain @@ -19,7 +18,7 @@ cmake_minimum_required(VERSION 2.8) #====================================================================# # Setup Project # #====================================================================# -project(ArduinoExample C CXX) +project(ArduinoExample) print_board_list() print_programmer_list() diff --git a/cmake/ArduinoToolchain.cmake b/cmake/ArduinoToolchain.cmake index acda9cf..c531ba0 100644 --- a/cmake/ArduinoToolchain.cmake +++ b/cmake/ArduinoToolchain.cmake @@ -8,8 +8,12 @@ #=============================================================================# set(CMAKE_SYSTEM_NAME Arduino) -set(CMAKE_C_COMPILER avr-gcc) -set(CMAKE_CXX_COMPILER avr-g++) +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER avr-gcc) +endif() +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER avr-g++) +endif() # Add current directory to CMake Module path automatically if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/Platform/Arduino.cmake) @@ -82,8 +86,3 @@ else() message(FATAL_ERROR "Could not find Arduino SDK (set ARDUINO_SDK_PATH)!") endif() -set(ARDUINO_CPUMENU) -if(ARDUINO_CPU) - set(ARDUINO_CPUMENU ".menu.cpu.${ARDUINO_CPU}") -endif(ARDUINO_CPU) - diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 5c3d2a1..93c3823 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -455,7 +455,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) message(STATUS "Generating ${INPUT_NAME}") parse_generator_arguments(${INPUT_NAME} INPUT "NO_AUTOLIBS;MANUAL" # Options - "BOARD;PORT;SKETCH;PROGRAMMER" # One Value Keywords + "BOARD;PORT;SKETCH;PROGRAMMER;CPU" # One Value Keywords "SERIAL;SRCS;HDRS;LIBS;ARDLIBS;AFLAGS" # Multi Value Keywords ${ARGN}) @@ -468,14 +468,22 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) if(NOT INPUT_SERIAL) set(INPUT_SERIAL ${ARDUINO_DEFAULT_SERIAL}) endif() - if(NOT INPUT_PROGRAMMER) - set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) + if(NOT DEFINED INPUT_PROGRAMMER) + if(DEFINED ${INPUT_BOARD}.upload.tool) + set(INPUT_PROGRAMMER ${${INPUT_BOARD}.upload.tool}) + else() + set(INPUT_PROGRAMMER ${ARDUINO_DEFAULT_PROGRAMMER}) + endif() endif() if(NOT INPUT_MANUAL) set(INPUT_MANUAL FALSE) endif() required_variables(VARS INPUT_BOARD MSG "must define for target ${INPUT_NAME}") + if(INPUT_CPU) + set(ARDUINO_CPUMENU ".menu.cpu.${INPUT_CPU}") + endif(INPUT_CPU) + set(PLATFORM ${${INPUT_BOARD}.PLATFORM}) @@ -858,64 +866,55 @@ endfunction() #=============================================================================# # [PRIVATE/INTERNAL] # -# get_arduino_flags(COMPILE_FLAGS LINK_FLAGS BOARD_ID MANUAL) +# get_recipe_flags(COMPILE_CMD_VAR COMPILE_FLAGS_VAR BOARD_ID RECIPE_TYPE) # -# COMPILE_FLAGS_VAR -Variable holding compiler flags -# LINK_FLAGS_VAR - Variable holding linker flags +# COMPILE_CMD_VAR - Command for the given recipe (i.e. the first part of the string) +# COMPILE_FLAGS_VAR - compile flags for the recipe # BOARD_ID - The board id name -# MANUAL - (Advanced) Only use AVR Libc/Includes +# RECIPE_TYPE - name of the recipe, e.g. [recipe.c.o, recipe.cpp.o, recipe.ar, recipe.objcopy.eep, ...] # -# Configures the the build settings for the specified Arduino Board. +# Gets the recipe configuration for the given recipe type # #=============================================================================# -function(get_arduino_flags COMPILE_FLAGS_VAR LINK_FLAGS_VAR BOARD_ID MANUAL) - - set(BOARD_CORE ${${BOARD_ID}.build.core}) +function(get_recipe_flags COMPILE_CMD_VAR COMPILE_FLAGS_VAR BOARD_ID RECIPE_TYPE) set(PLATFORM ${${BOARD_ID}.PLATFORM}) - if(BOARD_CORE) + set(RECIPE_VAR_NAME "${PLATFORM}.${RECIPE_TYPE}.pattern") - # output - set(COMPILE_FLAGS "") + if(NOT DEFINED ${RECIPE_VAR_NAME}) + MESSAGE(FATAL_ERROR "Value for ${RECIPE_VAR_NAME} not defined") + endif() - if(${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DF_CPU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.f_cpu}") - else() - if(${BOARD_ID}.build.f_cpu) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DF_CPU=${${BOARD_ID}.build.f_cpu}") - else() - message(FATAL_ERROR "Can not find f_cpu in boards.txt for Arduino board ID (${BOARD_ID}), aborting.") - endif() - endif() + set(RECIPE_PATTERN ${${RECIPE_VAR_NAME}}) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DARDUINO=${ARDUINO_VERSION_DEFINE} -DARDUINO_${${BOARD_ID}.build.board} -DARDUINO_ARCH_AVR -mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") + # Split recipe into command part (first part in quotes or up to first space) and flags part + if("${RECIPE_PATTERN}" MATCHES "^[\"]*([^\"]+)[\"]*(.*)") + SET(RECPIE_CMD ${CMAKE_MATCH_1}) + SET(RECPIE_FLAGS ${CMAKE_MATCH_2}) - if(DEFINED ${BOARD_ID}.build.vid) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_VID=${${BOARD_ID}.build.vid}") - endif() - if(DEFINED ${BOARD_ID}.build.pid) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -DUSB_PID=${${BOARD_ID}.build.pid}") - endif() - if(NOT MANUAL) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${${BOARD_CORE}.path}\" -I\"${ARDUINO_LIBRARIES_PATH}\"") - endif() - set(LINK_FLAGS "-mmcu=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") - if(ARDUINO_SDK_VERSION VERSION_GREATER 1.0 OR ARDUINO_SDK_VERSION VERSION_EQUAL 1.0) - if(NOT MANUAL) - set(PIN_HEADER ${${${BOARD_ID}.build.variant}.path}) - if(PIN_HEADER) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -I\"${PIN_HEADER}\"") - endif() + # remove the files variables (this is a list of commonly used endings. It may be necessary to extend them + string(REPLACE "{includes} \"{source_file}\" -o \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) + string(REPLACE "\"{build.path}/arduino.ar\" \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) + + + if("${RECPIE_FLAGS}" MATCHES ".*{build.path}/{build.project_name}.*") + if(NOT DEFINED TARGET_PATH) + MESSAGE(FATAL_ERROR "TARGET_PATH must be defined to replace '{build.path}/{build.project_name}'") endif() + string(REPLACE "{build.path}/{build.project_name}" "${TARGET_PATH}" RECPIE_FLAGS ${RECPIE_FLAGS}) endif() - # output - set(${COMPILE_FLAGS_VAR} "${COMPILE_FLAGS}" PARENT_SCOPE) - set(${LINK_FLAGS_VAR} "${LINK_FLAGS}" PARENT_SCOPE) + string(STRIP "${RECPIE_FLAGS}" RECPIE_FLAGS) + + get_variable_value_filled(RECIPE_CMD_FULL "${RECPIE_CMD}" ${BOARD_ID} ${RECIPE_VAR_NAME}) + SET(${COMPILE_CMD_VAR} ${RECIPE_CMD_FULL} PARENT_SCOPE) + + get_variable_value_filled(RECIPE_FLAGS_FULL "${RECPIE_FLAGS}" ${BOARD_ID} ${RECIPE_VAR_NAME}) + SET(${COMPILE_FLAGS_VAR} ${RECIPE_FLAGS_FULL} PARENT_SCOPE) else() - message(FATAL_ERROR "Invalid Arduino board ID (${BOARD_ID}), aborting.") + MESSAGE(FATAL_ERROR "Recipe pattern for '${RECIPE_VAR_NAME}' in unexpected format ") endif() endfunction() @@ -941,7 +940,19 @@ function(setup_arduino_core VAR_NAME BOARD_ID) # Debian/Ubuntu fix list(REMOVE_ITEM CORE_SRCS "${BOARD_CORE_PATH}/main.cxx") add_library(${CORE_LIB_NAME} ${CORE_SRCS}) - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) + + get_recipe_flags(ARDUINO_COMPILE_CMD ARDUINO_COMPILE_FLAGS ${BOARD_ID} "recipe.c.o") + + if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${ARDUINO_COMPILE_CMD}") + MESSAGE(FATAL_ERROR "Your compiler needs to be manually set to\nCMAKE_C_COMPILER=\"${ARDUINO_COMPILE_CMD}\"") + endif() + + get_recipe_flags(ARDUINO_LINK_CMD ARDUINO_LINK_FLAGS ${BOARD_ID} "recipe.ar") + + if(NOT "${CMAKE_AR}" STREQUAL "${ARDUINO_LINK_CMD}") + MESSAGE(FATAL_ERROR "Your archiver needs to be manually set to\nCMAKE_AR=\"${ARDUINO_LINK_CMD}\"") + endif() + set_target_properties(${CORE_LIB_NAME} PROPERTIES COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS}" LINK_FLAGS "${ARDUINO_LINK_FLAGS}") @@ -1182,82 +1193,76 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA add_executable(${TARGET_NAME} ${ALL_SRCS}) set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".elf") - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} ${MANUAL}) + if(NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + endif() + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) + + get_recipe_flags(ARDUINO_COMPILE_CMD ARDUINO_COMPILE_FLAGS ${BOARD_ID} "recipe.cpp.o") + if(NOT DEFINED ARDUINO_COMPILE_FLAGS) + MESSAGE(FATAL_ERROR "Could not get 'recipe.cpp.o'") + endif() + + if(NOT "${CMAKE_CXX_COMPILER}" STREQUAL "${ARDUINO_COMPILE_CMD}") + MESSAGE(FATAL_ERROR "Your compiler needs to be manually set to\nCMAKE_CXX_COMPILER=\"${ARDUINO_COMPILE_CMD}\"") + endif() + + get_recipe_flags(ARDUINO_LINK_CMD ARDUINO_LINK_FLAGS ${BOARD_ID} "recipe.c.combine") + if(NOT DEFINED ARDUINO_LINK_FLAGS) + MESSAGE(FATAL_ERROR "Could not get 'recipe.c.combine'") + endif() set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") - target_link_libraries(${TARGET_NAME} ${ALL_LIBS} "-lc -lm") + target_link_libraries(${TARGET_NAME} ${ALL_LIBS}) - if(NOT EXECUTABLE_OUTPUT_PATH) - set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) - endif() - set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - message(STATUS "Using ${CMAKE_OBJCOPY} for converting firmware image to hex") + # Convert firmware image to EEP format + get_recipe_flags(ARDUINO_OBJCOPY_EEP_CMD ARDUINO_OBJCOPY_EEP_FLAGS ${BOARD_ID} "recipe.objcopy.eep") + if(NOT DEFINED ARDUINO_OBJCOPY_EEP_FLAGS) + MESSAGE(FATAL_ERROR "Could not get 'recipe.objcopy.eep'") + endif() + string(REPLACE " " ";" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_OBJCOPY} + COMMAND ${ARDUINO_OBJCOPY_EEP_CMD} ARGS ${ARDUINO_OBJCOPY_EEP_FLAGS} - ${TARGET_PATH}.elf - ${TARGET_PATH}.eep COMMENT "Generating EEP image" VERBATIM) # Convert firmware image to ASCII HEX format + get_recipe_flags(ARDUINO_OBJCOPY_HEX_CMD ARDUINO_OBJCOPY_HEX_FLAGS ${BOARD_ID} "recipe.objcopy.hex") + if(NOT DEFINED ARDUINO_OBJCOPY_HEX_FLAGS) + MESSAGE(FATAL_ERROR "Could not get 'recipe.objcopy.hex'") + endif() + string(REPLACE " " ";" ARDUINO_OBJCOPY_HEX_FLAGS ${ARDUINO_OBJCOPY_HEX_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_OBJCOPY} + COMMAND ${ARDUINO_OBJCOPY_HEX_CMD} ARGS ${ARDUINO_OBJCOPY_HEX_FLAGS} - ${TARGET_PATH}.elf - ${TARGET_PATH}.hex COMMENT "Generating HEX image" VERBATIM) # Display target size + get_recipe_flags(ARDUINO_SIZE_CMD ARDUINO_SIZE_FLAGS ${BOARD_ID} "recipe.size") + if(NOT DEFINED ARDUINO_SIZE_FLAGS) + MESSAGE(FATAL_ERROR "Could not get 'recipe.size'") + endif() + string(REPLACE " " ";" ARDUINO_SIZE_FLAGS ${ARDUINO_SIZE_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -DFIRMWARE_IMAGE=${TARGET_PATH}.elf - -DMCU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu} - -DEEPROM_IMAGE=${TARGET_PATH}.eep - -P ${ARDUINO_SIZE_SCRIPT} + COMMAND ${ARDUINO_SIZE_CMD} + ARGS ${ARDUINO_SIZE_FLAGS} COMMENT "Calculating image size" VERBATIM) # Create ${TARGET_NAME}-size target add_custom_target(${TARGET_NAME}-size - COMMAND ${CMAKE_COMMAND} - -DFIRMWARE_IMAGE=${TARGET_PATH}.elf - -DMCU=${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu} - -DEEPROM_IMAGE=${TARGET_PATH}.eep - -P ${ARDUINO_SIZE_SCRIPT} + COMMAND ${ARDUINO_SIZE_CMD} + ARGS ${ARDUINO_SIZE_FLAGS} DEPENDS ${TARGET_NAME} COMMENT "Calculating ${TARGET_NAME} image size") endfunction() -#=============================================================================# -# [PRIVATE/INTERNAL] -# -# setup_arduino_upload(BOARD_ID TARGET_NAME PORT) -# -# BOARD_ID - Arduino board id -# TARGET_NAME - Target name -# PORT - Serial port for upload -# PROGRAMMER_ID - Programmer ID -# AVRDUDE_FLAGS - avrdude flags -# -# Create an upload target (${TARGET_NAME}-upload) for the specified Arduino target. -# -#=============================================================================# -function(setup_arduino_upload BOARD_ID TARGET_NAME PORT PROGRAMMER_ID AVRDUDE_FLAGS) - setup_arduino_bootloader_upload(${TARGET_NAME} ${BOARD_ID} ${PORT} "${AVRDUDE_FLAGS}") - - # Add programmer support if defined - if(PROGRAMMER_ID AND ${PROGRAMMER_ID}.protocol) - setup_arduino_programmer_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") - setup_arduino_bootloader_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") - endif() -endfunction() - #=============================================================================# # [PRIVATE/INTERNAL] @@ -1266,36 +1271,36 @@ endfunction() # # TARGET_NAME - target name # BOARD_ID - board id +# PROGRAMMER_ID - the programmer # PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) # # Set up target for upload firmware via the bootloader. # # The target for uploading the firmware is ${TARGET_NAME}-upload . # #=============================================================================# -function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS) +function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PROGRAMMER_ID PORT) set(UPLOAD_TARGET ${TARGET_NAME}-upload) - set(AVRDUDE_ARGS) - - setup_arduino_bootloader_args(${BOARD_ID} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) - - if(NOT AVRDUDE_ARGS) - message("Could not generate default avrdude bootloader args, aborting!") - return() - endif() if(NOT EXECUTABLE_OUTPUT_PATH) - set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) endif() set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex:i") - list(APPEND AVRDUDE_ARGS "-Ueeprom:w:${TARGET_PATH}.eep:i") + get_recipe_flags(ARDUINO_UPLOAD_CMD ARDUINO_UPLOAD_FLAGS ${BOARD_ID} "tools.${PROGRAMMER_ID}.upload") + + string(REPLACE "{build.path}/{build.project_name}" "${TARGET_NAME}" ARDUINO_UPLOAD_FLAGS ${ARDUINO_UPLOAD_FLAGS}) + string(REPLACE "{serial.port}" "${PORT}" ARDUINO_UPLOAD_FLAGS ${ARDUINO_UPLOAD_FLAGS}) + + if(NOT ARDUINO_UPLOAD_FLAGS) + message(FATAL_ERROR "Could not generate bootloader args, aborting!") + endif() + + string(REPLACE " " ";" ARDUINO_UPLOAD_FLAGS ${ARDUINO_UPLOAD_FLAGS}) add_custom_target(${UPLOAD_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - DEPENDS ${TARGET_NAME}) + ${ARDUINO_UPLOAD_CMD} + ${ARDUINO_UPLOAD_FLAGS} + DEPENDS ${TARGET_NAME}) # Global upload target if(NOT TARGET upload) @@ -1305,6 +1310,32 @@ function(setup_arduino_bootloader_upload TARGET_NAME BOARD_ID PORT AVRDUDE_FLAGS add_dependencies(upload ${UPLOAD_TARGET}) endfunction() +#=============================================================================# +# [PRIVATE/INTERNAL] +# +# setup_arduino_upload(BOARD_ID TARGET_NAME PORT) +# +# BOARD_ID - Arduino board id +# TARGET_NAME - Target name +# PORT - Serial port for upload +# PROGRAMMER_ID - Programmer ID +# AVRDUDE_FLAGS - avrdude flags +# +# Create an upload target (${TARGET_NAME}-upload) for the specified Arduino target. +# +#=============================================================================# +function(setup_arduino_upload BOARD_ID TARGET_NAME PORT PROGRAMMER_ID AVRDUDE_FLAGS) + + setup_arduino_bootloader_upload(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT}) + + # Add programmer support if defined + if(PROGRAMMER_ID AND ${BOARD_ID}.upload.protocol) + setup_arduino_programmer_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") + setup_arduino_bootloader_burn(${TARGET_NAME} ${BOARD_ID} ${PROGRAMMER_ID} ${PORT} "${AVRDUDE_FLAGS}") + endif() +endfunction() + + #=============================================================================# # [PRIVATE/INTERNAL] # @@ -1314,36 +1345,35 @@ endfunction() # BOARD_ID - board id # PROGRAMMER - programmer id # PORT - serial port -# AVRDUDE_FLAGS - avrdude flags (override) # # Sets up target for burning firmware via a programmer. # # The target for burning the firmware is ${TARGET_NAME}-burn . # #=============================================================================# -function(setup_arduino_programmer_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) +function(setup_arduino_programmer_burn TARGET_NAME BOARD_ID PROGRAMMER PORT) set(PROGRAMMER_TARGET ${TARGET_NAME}-burn) - set(AVRDUDE_ARGS) - - setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) - - if(NOT AVRDUDE_ARGS) - message("Could not generate default avrdude programmer args, aborting!") - return() - endif() - if(NOT EXECUTABLE_OUTPUT_PATH) - set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) endif() set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - list(APPEND AVRDUDE_ARGS "-Uflash:w:${TARGET_PATH}.hex") + get_recipe_flags(ARDUINO_PROGRAM_CMD ARDUINO_PROGRAM_FLAGS ${BOARD_ID} "tools.${PROGRAMMER_ID}.program") + if(NOT ARDUINO_PROGRAM_FLAGS) + message(FATAL_ERROR "Could not generate programmer args, aborting!") + endif() + + string(REPLACE "{build.path}/{build.project_name}" "${TARGET_NAME}" ARDUINO_PROGRAM_FLAGS ${ARDUINO_PROGRAM_FLAGS}) + string(REPLACE "{program.extra_params}" "" ARDUINO_PROGRAM_FLAGS ${ARDUINO_PROGRAM_FLAGS}) + string(REPLACE "{protocol}" "${${BOARD_ID}.upload.protocol}" ARDUINO_PROGRAM_FLAGS ${ARDUINO_PROGRAM_FLAGS}) + string(REPLACE " " ";" ARDUINO_PROGRAM_FLAGS ${ARDUINO_PROGRAM_FLAGS}) add_custom_target(${PROGRAMMER_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - DEPENDS ${TARGET_NAME}) + ${ARDUINO_PROGRAM_CMD} + ${ARDUINO_PROGRAM_FLAGS} + DEPENDS ${TARGET_NAME}) + endfunction() #=============================================================================# @@ -1363,108 +1393,80 @@ endfunction() # #=============================================================================# function(setup_arduino_bootloader_burn TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) - set(BOOTLOADER_TARGET ${TARGET_NAME}-burn-bootloader) - - set(AVRDUDE_ARGS) - setup_arduino_programmer_args(${BOARD_ID} ${PROGRAMMER} ${TARGET_NAME} ${PORT} "${AVRDUDE_FLAGS}" AVRDUDE_ARGS) + set(PLATFORM ${${BOARD_ID}.PLATFORM}) - if(NOT AVRDUDE_ARGS) - message("Could not generate default avrdude programmer args, aborting!") - return() - endif() + setup_arduino_bootloader_erase("${TARGET_NAME}" "${BOARD_ID}" "${PROGRAMMER}" "${PORT}" "${AVRDUDE_FLAGS}") - foreach( ITEM unlock_bits high_fuses low_fuses path file) - if(NOT ${BOARD_ID}.bootloader.${ITEM}) - message("Missing ${BOARD_ID}.bootloader.${ITEM}, not creating bootloader burn target ${BOOTLOADER_TARGET}.") - return() - endif() - endforeach() + set(BOOTLOADER_TARGET ${TARGET_NAME}-burn-bootloader) - if(NOT EXISTS "${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}") - message("${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}") - message("Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.") - return() + if(NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) endif() + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - # Erase the chip - list(APPEND AVRDUDE_ARGS "-e") - - # Set unlock bits and fuses (because chip is going to be erased) - list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.unlock_bits}:m") - if(${BOARD_ID}.bootloader.extended_fuses) - list(APPEND AVRDUDE_ARGS "-Uefuse:w:${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.extended_fuses}:m") + get_recipe_flags(ARDUINO_BOOTLOADER_CMD ARDUINO_BOOTLOADER_FLAGS ${BOARD_ID} "tools.${PROGRAMMER_ID}.bootloader") + if(NOT ARDUINO_BOOTLOADER_FLAGS) + message(FATAL_ERROR "Could not generate bootloader args, aborting!") endif() - list(APPEND AVRDUDE_ARGS - "-Uhfuse:w:${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.high_fuses}:m" - "-Ulfuse:w:${${BOARD_ID}.bootloader.low_fuses}:m") - # Set bootloader image - list(APPEND AVRDUDE_ARGS "-Uflash:w:${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}:i") + string(REPLACE "{build.path}/{build.project_name}" "${TARGET_NAME}" ARDUINO_BOOTLOADER_FLAGS ${ARDUINO_BOOTLOADER_FLAGS}) + string(REPLACE "{program.extra_params}" "" ARDUINO_BOOTLOADER_FLAGS ${ARDUINO_BOOTLOADER_FLAGS}) + string(REPLACE "{protocol}" "${${BOARD_ID}.upload.protocol}" ARDUINO_BOOTLOADER_FLAGS ${ARDUINO_BOOTLOADER_FLAGS}) + string(REPLACE " " ";" ARDUINO_BOOTLOADER_FLAGS ${ARDUINO_BOOTLOADER_FLAGS}) - # Set lockbits - list(APPEND AVRDUDE_ARGS "-Ulock:w:${${BOARD_ID}.bootloader.lock_bits}:m") + if(NOT EXISTS "${${PLATFORM}_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}") + message("${${PLATFORM}_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path}/${${BOARD_ID}${ARDUINO_CPUMENU}.bootloader.file}") + message(FATAL_ERROR "Missing bootloader image, not creating bootloader burn target ${BOOTLOADER_TARGET}.") + endif() # Create burn bootloader target add_custom_target(${BOOTLOADER_TARGET} - ${ARDUINO_AVRDUDE_PROGRAM} - ${AVRDUDE_ARGS} - WORKING_DIRECTORY ${ARDUINO_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path} - DEPENDS ${TARGET_NAME}) + ${ARDUINO_BOOTLOADER_CMD} + ${ARDUINO_BOOTLOADER_FLAGS} + WORKING_DIRECTORY ${${PLATFORM}_BOOTLOADERS_PATH}/${${BOARD_ID}.bootloader.path} + DEPENDS ${TARGET_NAME}-erase-bootloader) endfunction() #=============================================================================# # [PRIVATE/INTERNAL] # -# setup_arduino_programmer_args(BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) +# setup_arduino_bootloader_erase(TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) # +# TARGET_NAME - name of target to erase # BOARD_ID - board id # PROGRAMMER - programmer id -# TARGET_NAME - target name # PORT - serial port # AVRDUDE_FLAGS - avrdude flags (override) -# OUTPUT_VAR - name of output variable for result # -# Sets up default avrdude settings for burning firmware via a programmer. +# Create a target for erasing the bootloader via a programmer. +# +# The target for erasing the bootloader is ${TARGET_NAME}-erase-bootloader +# #=============================================================================# -function(setup_arduino_programmer_args BOARD_ID PROGRAMMER TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) - set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) - - if(NOT AVRDUDE_FLAGS) - set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) - endif() - - list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}") - - #TODO: Check mandatory settings before continuing - if(NOT ${PROGRAMMER}.protocol) - message(FATAL_ERROR "Missing ${PROGRAMMER}.protocol, aborting!") - endif() - - list(APPEND AVRDUDE_ARGS "-c${${PROGRAMMER}.protocol}") # Set programmer +function(setup_arduino_bootloader_erase TARGET_NAME BOARD_ID PROGRAMMER PORT AVRDUDE_FLAGS) + set(ERASE_TARGET ${TARGET_NAME}-erase-bootloader) - if(${PROGRAMMER}.communication STREQUAL "usb") - list(APPEND AVRDUDE_ARGS "-Pusb") # Set USB as port - elseif(${PROGRAMMER}.communication STREQUAL "serial") - list(APPEND AVRDUDE_ARGS "-P${PORT}") # Set port - if(${PROGRAMMER}.speed) - list(APPEND AVRDUDE_ARGS "-b${${PROGRAMMER}.speed}") # Set baud rate - endif() - endif() - - if(${PROGRAMMER}.force) - list(APPEND AVRDUDE_ARGS "-F") # Set force + if(NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) endif() + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}) - if(${PROGRAMMER}.delay) - list(APPEND AVRDUDE_ARGS "-i${${PROGRAMMER}.delay}") # Set delay + get_recipe_flags(ARDUINO_ERASE_CMD ARDUINO_ERASE_FLAGS ${BOARD_ID} "tools.${PROGRAMMER_ID}.erase") + if(NOT ARDUINO_ERASE_FLAGS) + message(FATAL_ERROR "Could not generate ERASE args, aborting!") endif() - list(APPEND AVRDUDE_ARGS "-p${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}") # MCU Type + string(REPLACE "{build.path}/{build.project_name}" "${TARGET_NAME}" ARDUINO_ERASE_FLAGS ${ARDUINO_ERASE_FLAGS}) + string(REPLACE "{program.extra_params}" "" ARDUINO_ERASE_FLAGS ${ARDUINO_ERASE_FLAGS}) + string(REPLACE "{protocol}" "${${BOARD_ID}.upload.protocol}" ARDUINO_ERASE_FLAGS ${ARDUINO_ERASE_FLAGS}) + string(REPLACE " " ";" ARDUINO_ERASE_FLAGS ${ARDUINO_ERASE_FLAGS}) - list(APPEND AVRDUDE_ARGS ${AVRDUDE_FLAGS}) - - set(${OUTPUT_VAR} ${AVRDUDE_ARGS} PARENT_SCOPE) + # Create burn ERASE target + add_custom_target(${ERASE_TARGET} + ${ARDUINO_ERASE_CMD} + ${ARDUINO_ERASE_FLAGS} + DEPENDS ${TARGET_NAME}) endfunction() #=============================================================================# @@ -1483,10 +1485,6 @@ endfunction() function(setup_arduino_bootloader_args BOARD_ID TARGET_NAME PORT AVRDUDE_FLAGS OUTPUT_VAR) set(AVRDUDE_ARGS ${${OUTPUT_VAR}}) - if(NOT AVRDUDE_FLAGS) - set(AVRDUDE_FLAGS ${ARDUINO_AVRDUDE_FLAGS}) - endif() - list(APPEND AVRDUDE_ARGS "-C${ARDUINO_AVRDUDE_CONFIG_PATH}" # avrdude config "-p${${BOARD_ID}${ARDUINO_CPUMENU}.build.mcu}" # MCU Type @@ -1732,6 +1730,7 @@ endfunction() # VARIABLE_RETURN - The name of the return variable # SETTING_VALUE - the value of the variable with placeholders # BOARD_ID - the id of the board to identify the correct placeholder replacements +# SETTING_NAME - optional setting name # # Replace placeholders in the variable value with the defined values from # the cache. @@ -1739,9 +1738,9 @@ endfunction() # {runtime.tools.avrdude.path} # will be replaced accordingly #=============================================================================# -function(GET_VARIABLE_VALUE_FILLED VARIABLE_RETURN SETTING_VALUE BOARD_ID) +function(GET_VARIABLE_VALUE_FILLED VARIABLE_RETURN SETTING_VALUE BOARD_ID SETTING_NAME) set(PLATFORM ${${BOARD_ID}.PLATFORM}) - set(VARIABLE_FILLED ${SETTING_VALUE} PARENT_SCOPE) + set(${VARIABLE_RETURN} ${SETTING_VALUE} PARENT_SCOPE) if (NOT SETTING_VALUE STREQUAL "") string(REGEX MATCHALL "{([^}]+)}" VARS_REPLACE ${SETTING_VALUE}) @@ -1752,22 +1751,50 @@ function(GET_VARIABLE_VALUE_FILLED VARIABLE_RETURN SETTING_VALUE BOARD_ID) string(REPLACE "{" "" i ${i}) unset(VAR_VALUE) + unset(VAR_NAME) + set(PREFIXED_NAME_PLATFORM "${PLATFORM}.${i}") set(PREFIXED_NAME_BOARD "${BOARD_ID}.${i}") + set(PREFIXED_CPU "${BOARD_ID}${ARDUINO_CPUMENU}.${i}") if (DEFINED ${PREFIXED_NAME_BOARD}) set(VAR_VALUE "${${PREFIXED_NAME_BOARD}}") + set(VAR_NAME "${PREFIXED_NAME_BOARD}") elseif(DEFINED ${PREFIXED_NAME_PLATFORM}) set(VAR_VALUE "${${PREFIXED_NAME_PLATFORM}}") + set(VAR_NAME "${PREFIXED_NAME_PLATFORM}") + elseif(DEFINED ${PREFIXED_CPU} ) + set(VAR_VALUE "${${PREFIXED_CPU}}") + set(VAR_NAME "${PREFIXED_CPU}") elseif(DEFINED ${i}) set(VAR_VALUE "${${i}}") + set(VAR_NAME "${i}") else() #MESSAGE(FATAL_ERROR "${i} not found in settings") endif() + if(NOT DEFINED VAR_VALUE AND SETTING_NAME) + # check if the value is somewhere available along the path leading to this setting + # i.e. if the searched value is 'path' and the variable is called 'some.compiler.tool' check + # - some.compiler.path + # - some.path + if(SETTING_NAME MATCHES "^(.+)\\.[^\\.]+\$") + set(SETTING_NAME_BASE "${CMAKE_MATCH_1}") + while (SETTING_NAME_BASE MATCHES "^(.+)\\.[^\\.]+\$") + set(SETTING_NAME_BASE "${CMAKE_MATCH_1}") + set(CUR_VAR_NAME "${SETTING_NAME_BASE}.${i}") + if(DEFINED ${CUR_VAR_NAME}) + set(VAR_VALUE "${${CUR_VAR_NAME}}") + set(VAR_NAME "${CUR_VAR_NAME}") + break() + endif() + endwhile () + endif() + endif() + if(DEFINED VAR_VALUE) #recursively replace - set(TMP_FILLED "") - get_variable_value_filled(TMP_FILLED "${VAR_VALUE}" ${BOARD_ID}) + set(TMP_FILLED "${VAR_VALUE}") + get_variable_value_filled(TMP_FILLED "${VAR_VALUE}" ${BOARD_ID} ${VAR_NAME}) string(REPLACE "{${i}}" "${TMP_FILLED}" SETTING_VALUE ${SETTING_VALUE}) endif() ENDFOREACH() @@ -2070,99 +2097,6 @@ function(GENERATE_CPP_FROM_SKETCH MAIN_SKETCH_PATH SKETCH_SOURCES SKETCH_CPP) endforeach() endfunction() -#=============================================================================# -# [PRIVATE/INTERNAL] -# -# setup_arduino_size_script(OUTPUT_VAR) -# -# OUTPUT_VAR - Output variable that will contain the script path -# -# Generates script used to display the firmware size. -#=============================================================================# -function(SETUP_ARDUINO_SIZE_SCRIPT OUTPUT_VAR) - set(ARDUINO_SIZE_SCRIPT_PATH ${CMAKE_BINARY_DIR}/CMakeFiles/FirmwareSize.cmake) - - file(WRITE ${ARDUINO_SIZE_SCRIPT_PATH} " - set(AVRSIZE_PROGRAM \"${AVRSIZE_PROGRAM}\") - set(AVRSIZE_FLAGS -C --mcu=\${MCU}) - - execute_process(COMMAND \${AVRSIZE_PROGRAM} \${AVRSIZE_FLAGS} \${FIRMWARE_IMAGE} \${EEPROM_IMAGE} - OUTPUT_VARIABLE SIZE_OUTPUT) - - - string(STRIP \"\${SIZE_OUTPUT}\" RAW_SIZE_OUTPUT) - - # Convert lines into a list - string(REPLACE \"\\n\" \";\" SIZE_OUTPUT_LIST \"\${SIZE_OUTPUT}\") - - set(SIZE_OUTPUT_LINES) - foreach(LINE \${SIZE_OUTPUT_LIST}) - if(NOT \"\${LINE}\" STREQUAL \"\") - list(APPEND SIZE_OUTPUT_LINES \"\${LINE}\") - endif() - endforeach() - - function(EXTRACT LIST_NAME INDEX VARIABLE) - list(GET \"\${LIST_NAME}\" \${INDEX} RAW_VALUE) - string(STRIP \"\${RAW_VALUE}\" VALUE) - - set(\${VARIABLE} \"\${VALUE}\" PARENT_SCOPE) - endfunction() - function(PARSE INPUT VARIABLE_PREFIX) - if(\${INPUT} MATCHES \"([^:]+):[ \\t]*([0-9]+)[ \\t]*([^ \\t]+)[ \\t]*[(]([0-9.]+)%.*\") - set(ENTRY_NAME \${CMAKE_MATCH_1}) - set(ENTRY_SIZE \${CMAKE_MATCH_2}) - set(ENTRY_SIZE_TYPE \${CMAKE_MATCH_3}) - set(ENTRY_PERCENT \${CMAKE_MATCH_4}) - endif() - - set(\${VARIABLE_PREFIX}_NAME \${ENTRY_NAME} PARENT_SCOPE) - set(\${VARIABLE_PREFIX}_SIZE \${ENTRY_SIZE} PARENT_SCOPE) - set(\${VARIABLE_PREFIX}_SIZE_TYPE \${ENTRY_SIZE_TYPE} PARENT_SCOPE) - set(\${VARIABLE_PREFIX}_PERCENT \${ENTRY_PERCENT} PARENT_SCOPE) - endfunction() - - list(LENGTH SIZE_OUTPUT_LINES SIZE_OUTPUT_LENGTH) - #message(\"\${SIZE_OUTPUT_LINES}\") - #message(\"\${SIZE_OUTPUT_LENGTH}\") - if (\${SIZE_OUTPUT_LENGTH} STREQUAL 14) - EXTRACT(SIZE_OUTPUT_LINES 3 FIRMWARE_PROGRAM_SIZE_ROW) - EXTRACT(SIZE_OUTPUT_LINES 5 FIRMWARE_DATA_SIZE_ROW) - PARSE(FIRMWARE_PROGRAM_SIZE_ROW FIRMWARE_PROGRAM) - PARSE(FIRMWARE_DATA_SIZE_ROW FIRMWARE_DATA) - - set(FIRMWARE_STATUS \"Firmware Size: \") - set(FIRMWARE_STATUS \"\${FIRMWARE_STATUS} [\${FIRMWARE_PROGRAM_NAME}: \${FIRMWARE_PROGRAM_SIZE} \${FIRMWARE_PROGRAM_SIZE_TYPE} (\${FIRMWARE_PROGRAM_PERCENT}%)] \") - set(FIRMWARE_STATUS \"\${FIRMWARE_STATUS} [\${FIRMWARE_DATA_NAME}: \${FIRMWARE_DATA_SIZE} \${FIRMWARE_DATA_SIZE_TYPE} (\${FIRMWARE_DATA_PERCENT}%)]\") - set(FIRMWARE_STATUS \"\${FIRMWARE_STATUS} on \${MCU}\") - - EXTRACT(SIZE_OUTPUT_LINES 10 EEPROM_PROGRAM_SIZE_ROW) - EXTRACT(SIZE_OUTPUT_LINES 12 EEPROM_DATA_SIZE_ROW) - PARSE(EEPROM_PROGRAM_SIZE_ROW EEPROM_PROGRAM) - PARSE(EEPROM_DATA_SIZE_ROW EEPROM_DATA) - - set(EEPROM_STATUS \"EEPROM Size: \") - set(EEPROM_STATUS \"\${EEPROM_STATUS} [\${EEPROM_PROGRAM_NAME}: \${EEPROM_PROGRAM_SIZE} \${EEPROM_PROGRAM_SIZE_TYPE} (\${EEPROM_PROGRAM_PERCENT}%)] \") - set(EEPROM_STATUS \"\${EEPROM_STATUS} [\${EEPROM_DATA_NAME}: \${EEPROM_DATA_SIZE} \${EEPROM_DATA_SIZE_TYPE} (\${EEPROM_DATA_PERCENT}%)]\") - set(EEPROM_STATUS \"\${EEPROM_STATUS} on \${MCU}\") - - message(\"\${FIRMWARE_STATUS}\") - message(\"\${EEPROM_STATUS}\\n\") - - if(\$ENV{VERBOSE}) - message(\"\${RAW_SIZE_OUTPUT}\\n\") - elseif(\$ENV{VERBOSE_SIZE}) - message(\"\${RAW_SIZE_OUTPUT}\\n\") - endif() - else() - message(\"\${RAW_SIZE_OUTPUT}\") - endif() - ") - - set(${OUTPUT_VAR} ${ARDUINO_SIZE_SCRIPT_PATH} PARENT_SCOPE) -endfunction() - - #=============================================================================# # [PRIVATE/INTERNAL] # @@ -2340,14 +2274,6 @@ set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${ARDUINO_LINKER_FLAGS}" CACHE STR set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ARDUINO_LINKER_FLAGS}" CACHE STRING "") -#=============================================================================# -# Arduino Settings -#=============================================================================# -set(ARDUINO_OBJCOPY_EEP_FLAGS -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load - --no-change-warnings --change-section-lma .eeprom=0 CACHE STRING "") -set(ARDUINO_OBJCOPY_HEX_FLAGS -O ihex -R .eeprom CACHE STRING "") -set(ARDUINO_AVRDUDE_FLAGS -V CACHE STRING "") - #=============================================================================# # Initialization #=============================================================================# @@ -2417,13 +2343,6 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) DOC "Path to avrdude programmer configuration file." NO_SYSTEM_ENVIRONMENT_PATH) - if(NOT CMAKE_OBJCOPY) - find_program(AVROBJCOPY_PROGRAM - avr-objcopy) - set(ADDITIONAL_REQUIRED_VARS AVROBJCOPY_PROGRAM) - set(CMAKE_OBJCOPY ${AVROBJCOPY_PROGRAM} CACHE PATH "OBJCOPY Program for firmware convertion in hex") - endif(NOT CMAKE_OBJCOPY) - set(ARDUINO_DEFAULT_BOARD uno CACHE STRING "Default Arduino Board ID when not specified.") set(ARDUINO_DEFAULT_PORT CACHE STRING "Default Arduino port when not specified.") set(ARDUINO_DEFAULT_SERIAL CACHE STRING "Default Arduino Serial command when not specified.") @@ -2438,16 +2357,12 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) AVR_BOARDS_PATH AVR_PROGRAMMERS_PATH ARDUINO_VERSION_PATH - ARDUINO_AVRDUDE_FLAGS ARDUINO_AVRDUDE_PROGRAM ARDUINO_AVRDUDE_CONFIG_PATH AVRSIZE_PROGRAM ${ADDITIONAL_REQUIRED_VARS} MSG "Invalid Arduino SDK path (${ARDUINO_SDK_PATH}).\n") - setup_arduino_size_script(ARDUINO_SIZE_SCRIPT) - set(ARDUINO_SIZE_SCRIPT ${ARDUINO_SIZE_SCRIPT} CACHE INTERNAL "Arduino Size Script") - #print_board_list() #print_programmer_list() @@ -2460,19 +2375,18 @@ if(NOT ARDUINO_FOUND AND ARDUINO_SDK_PATH) AVR_BOARDS_PATH AVR_PROGRAMMERS_PATH ARDUINO_VERSION_PATH - ARDUINO_AVRDUDE_FLAGS ARDUINO_AVRDUDE_PROGRAM ARDUINO_AVRDUDE_CONFIG_PATH - ARDUINO_OBJCOPY_EEP_FLAGS - ARDUINO_OBJCOPY_HEX_FLAGS AVRSIZE_PROGRAM) endif() # Set some predefined variable values as defined in # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification -set(RUNTIME_IDE_PATH_VAR "runtime.ide.path") -set(${RUNTIME_IDE_PATH_VAR} ${ARDUINO_SDK_PATH} CACHE INTERNAL "") +set(runtime.ide.path ${ARDUINO_SDK_PATH} CACHE INTERNAL "") +set(runtime.tools.avr-gcc.path "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE INTERNAL "") +set(runtime.tools.avrdude.path "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE INTERNAL "") +set(runtime.tools.arduinoOTA.path "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE INTERNAL "") @@ -2497,6 +2411,10 @@ else() endif() set(runtime.ide.version ${ARDUINO_VERSION_DEFINE} CACHE INTERNAL "") +set(upload.verbose "-V" CACHE INTERNAL "") +set(program.verbose "-V" CACHE INTERNAL "") +set(bootloader.verbose "-V" CACHE INTERNAL "") +set(erase.verbose "-V" CACHE INTERNAL "") if (WIN32) set(runtime.os "windows" CACHE INTERNAL "") diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 2f6be93..c9ddf6f 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -2,7 +2,7 @@ set(PROJECT_NAME example) # Define your project and language -project(${PROJECT_NAME} C CXX) +project(${PROJECT_NAME}) set(${PROJECT_NAME}_BOARD pro) @@ -12,5 +12,8 @@ set(${PROJECT_NAME}_SRCS example.cpp) # Define the port for uploading code to the Arduino set(${PROJECT_NAME}_PORT COM6) + +set(${PROJECT_NAME}_CPU 16MHzatmega328) + # Command to generate code arduino firmware (.hex file) generate_arduino_firmware(${PROJECT_NAME}) From 7a00b9cab1341ae7ca8911eb6ac37a23c36ecca1 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Tue, 30 Jan 2018 15:24:53 +0100 Subject: [PATCH 22/29] Build for Arduino working --- cmake/Platform/Arduino.cmake | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 93c3823..1bc1707 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -379,6 +379,9 @@ function(GENERATE_ARDUINO_LIBRARY INPUT_NAME) if(NOT INPUT_MANUAL) setup_arduino_core(CORE_LIB ${INPUT_BOARD}) + set(BOARD_CORE ${${BOARD_ID}.build.core}) + set(BOARD_CORE_PATH ${${BOARD_CORE}.path}) + include_directories( ${BOARD_CORE_PATH}) endif() find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "") @@ -496,14 +499,22 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) set(${INPUT_NAME}.build.path ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") set(${INPUT_NAME}.build.project_name ${INPUT_NAME} CACHE INTERNAL "") - string(TOLOWER "${PLATFORM}" PLATFORM_LOWER) - set(${INPUT_BOARD}.build.arch "${PLATFORM_LOWER}" CACHE INTERNAL "") + string(TOUPPER "${PLATFORM}" PLATFORM_UPPER) + set(${INPUT_BOARD}.build.arch "${PLATFORM_UPPER}" CACHE INTERNAL "") if(NOT INPUT_MANUAL) setup_arduino_core(CORE_LIB ${INPUT_BOARD}) + + set(BOARD_CORE ${${INPUT_BOARD}.build.core}) + set(BOARD_CORE_PATH ${${BOARD_CORE}.path}) + include_directories( ${BOARD_CORE_PATH}) endif() + # Set include dir for variant + set(BOARD_VARIANT ${${INPUT_BOARD}.build.variant}) + include_directories( ${${BOARD_VARIANT}.path}) + if(NOT "${INPUT_SKETCH}" STREQUAL "") get_filename_component(INPUT_SKETCH "${INPUT_SKETCH}" ABSOLUTE) setup_arduino_sketch(${INPUT_NAME} ${INPUT_SKETCH} ALL_SRCS) @@ -895,6 +906,7 @@ function(get_recipe_flags COMPILE_CMD_VAR COMPILE_FLAGS_VAR BOARD_ID RECIPE_TYPE # remove the files variables (this is a list of commonly used endings. It may be necessary to extend them string(REPLACE "{includes} \"{source_file}\" -o \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) + string(REPLACE "-o \"{build.path}/{build.project_name}.elf\" {object_files} \"{build.path}/{archive_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) string(REPLACE "\"{build.path}/arduino.ar\" \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) @@ -950,7 +962,7 @@ function(setup_arduino_core VAR_NAME BOARD_ID) get_recipe_flags(ARDUINO_LINK_CMD ARDUINO_LINK_FLAGS ${BOARD_ID} "recipe.ar") if(NOT "${CMAKE_AR}" STREQUAL "${ARDUINO_LINK_CMD}") - MESSAGE(FATAL_ERROR "Your archiver needs to be manually set to\nCMAKE_AR=\"${ARDUINO_LINK_CMD}\"") + MESSAGE(FATAL_ERROR "Your archiver needs to be manually set. You then also need to update the CMAKE_RANLIB to point to the correct one.\nCMAKE_AR=\"${ARDUINO_LINK_CMD}\"") endif() set_target_properties(${CORE_LIB_NAME} PROPERTIES @@ -1212,9 +1224,20 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA MESSAGE(FATAL_ERROR "Could not get 'recipe.c.combine'") endif() + + string(REPLACE "\"{build.path}/{archive_file}\"" "" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) + string(REPLACE "{object_files}" "" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) + string(REPLACE "{build.path}" "${EXECUTABLE_OUTPUT_PATH}" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) + + message("Link flags = ${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") + set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" - LINK_FLAGS "${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") + LINK_FLAGS "${ARDUINO_LINK_FLAGS}" + ARCHIVE_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + LIBRARY_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + ) target_link_libraries(${TARGET_NAME} ${ALL_LIBS}) @@ -1223,6 +1246,7 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if(NOT DEFINED ARDUINO_OBJCOPY_EEP_FLAGS) MESSAGE(FATAL_ERROR "Could not get 'recipe.objcopy.eep'") endif() + string(REPLACE "\"" "" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) string(REPLACE " " ";" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${ARDUINO_OBJCOPY_EEP_CMD} @@ -1235,6 +1259,7 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if(NOT DEFINED ARDUINO_OBJCOPY_HEX_FLAGS) MESSAGE(FATAL_ERROR "Could not get 'recipe.objcopy.hex'") endif() + string(REPLACE "\"" "" ARDUINO_OBJCOPY_HEX_FLAGS ${ARDUINO_OBJCOPY_HEX_FLAGS}) string(REPLACE " " ";" ARDUINO_OBJCOPY_HEX_FLAGS ${ARDUINO_OBJCOPY_HEX_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${ARDUINO_OBJCOPY_HEX_CMD} @@ -1247,6 +1272,7 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if(NOT DEFINED ARDUINO_SIZE_FLAGS) MESSAGE(FATAL_ERROR "Could not get 'recipe.size'") endif() + string(REPLACE "\"" "" ARDUINO_SIZE_FLAGS ${ARDUINO_SIZE_FLAGS}) string(REPLACE " " ";" ARDUINO_SIZE_FLAGS ${ARDUINO_SIZE_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${ARDUINO_SIZE_CMD} From d2319e27ec64e3a129871e6381ddd0425d314928 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Tue, 30 Jan 2018 18:04:24 +0100 Subject: [PATCH 23/29] First successful build with esp32 --- CMakeLists.txt | 8 +-- cmake/Platform/Arduino.cmake | 87 +++++++++++++++++++-------------- example/CMakeLists.txt | 1 + example_esp32/CMakeLists.txt | 22 +++++++++ example_esp32/example_esp32.cpp | 23 +++++++++ 5 files changed, 100 insertions(+), 41 deletions(-) create mode 100644 example_esp32/CMakeLists.txt create mode 100644 example_esp32/example_esp32.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a0aba17..014b669 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,12 +20,12 @@ cmake_minimum_required(VERSION 2.8) #====================================================================# project(ArduinoExample) -print_board_list() -print_programmer_list() +#print_board_list() +#print_programmer_list() # add libraries to project link_directories(${ARDUINO_SDK}/libraries) # add the project directory into build -add_subdirectory(example) -#add_subdirectory(example_esp32) +#add_subdirectory(example) +add_subdirectory(example_esp32) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 1bc1707..c8ed1cd 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -900,15 +900,24 @@ function(get_recipe_flags COMPILE_CMD_VAR COMPILE_FLAGS_VAR BOARD_ID RECIPE_TYPE set(RECIPE_PATTERN ${${RECIPE_VAR_NAME}}) # Split recipe into command part (first part in quotes or up to first space) and flags part - if("${RECIPE_PATTERN}" MATCHES "^[\"]*([^\"]+)[\"]*(.*)") - SET(RECPIE_CMD ${CMAKE_MATCH_1}) - SET(RECPIE_FLAGS ${CMAKE_MATCH_2}) + if("${RECIPE_PATTERN}" MATCHES "^\"([^\"]+)\"(.*)\$|^([^ ]+) (.*)\$") + if(CMAKE_MATCH_1) + SET(RECPIE_CMD ${CMAKE_MATCH_1}) + SET(RECPIE_FLAGS ${CMAKE_MATCH_2}) + else() + SET(RECPIE_CMD ${CMAKE_MATCH_3}) + SET(RECPIE_FLAGS ${CMAKE_MATCH_4}) + endif() # remove the files variables (this is a list of commonly used endings. It may be necessary to extend them string(REPLACE "{includes} \"{source_file}\" -o \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) string(REPLACE "-o \"{build.path}/{build.project_name}.elf\" {object_files} \"{build.path}/{archive_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) string(REPLACE "\"{build.path}/arduino.ar\" \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) + # esp32 specific + string(REPLACE "\"{build.path}/arduino.ar\" \"{object_file}\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) + string(REPLACE "{object_files} \"{build.path}/arduino.ar\"" "" RECPIE_FLAGS ${RECPIE_FLAGS}) + if("${RECPIE_FLAGS}" MATCHES ".*{build.path}/{build.project_name}.*") if(NOT DEFINED TARGET_PATH) @@ -953,16 +962,16 @@ function(setup_arduino_core VAR_NAME BOARD_ID) list(REMOVE_ITEM CORE_SRCS "${BOARD_CORE_PATH}/main.cxx") add_library(${CORE_LIB_NAME} ${CORE_SRCS}) - get_recipe_flags(ARDUINO_COMPILE_CMD ARDUINO_COMPILE_FLAGS ${BOARD_ID} "recipe.c.o") + get_recipe_flags(ARDUINO_COMPILE_CMD ARDUINO_COMPILE_FLAGS ${BOARD_ID} "recipe.cpp.o") - if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${ARDUINO_COMPILE_CMD}") - MESSAGE(FATAL_ERROR "Your compiler needs to be manually set to\nCMAKE_C_COMPILER=\"${ARDUINO_COMPILE_CMD}\"") + if(NOT "${CMAKE_CXX_COMPILER}" STREQUAL "${ARDUINO_COMPILE_CMD}") + MESSAGE(WARNING "Your compiler needs to be manually set to\nCMAKE_CXX_COMPILER=\"${ARDUINO_COMPILE_CMD}\"") endif() get_recipe_flags(ARDUINO_LINK_CMD ARDUINO_LINK_FLAGS ${BOARD_ID} "recipe.ar") if(NOT "${CMAKE_AR}" STREQUAL "${ARDUINO_LINK_CMD}") - MESSAGE(FATAL_ERROR "Your archiver needs to be manually set. You then also need to update the CMAKE_RANLIB to point to the correct one.\nCMAKE_AR=\"${ARDUINO_LINK_CMD}\"") + MESSAGE(WARNING "Your archiver needs to be manually set. You then also need to update the CMAKE_RANLIB to point to the correct one.\nCMAKE_AR=\"${ARDUINO_LINK_CMD}\"") endif() set_target_properties(${CORE_LIB_NAME} PROPERTIES @@ -1229,8 +1238,6 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA string(REPLACE "{object_files}" "" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) string(REPLACE "{build.path}" "${EXECUTABLE_OUTPUT_PATH}" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) - message("Link flags = ${ARDUINO_LINK_FLAGS} ${LINK_FLAGS}") - set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" LINK_FLAGS "${ARDUINO_LINK_FLAGS}" @@ -1246,6 +1253,12 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if(NOT DEFINED ARDUINO_OBJCOPY_EEP_FLAGS) MESSAGE(FATAL_ERROR "Could not get 'recipe.objcopy.eep'") endif() + + if ("${ARDUINO_OBJCOPY_EEP_CMD}" MATCHES "^python \"(.*)\"$") + set(ARDUINO_OBJCOPY_EEP_CMD ${CMAKE_MATCH_1}) + endif() + string(REPLACE "\"" "" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) + string(REPLACE "\"" "" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) string(REPLACE " " ";" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD @@ -1259,6 +1272,9 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if(NOT DEFINED ARDUINO_OBJCOPY_HEX_FLAGS) MESSAGE(FATAL_ERROR "Could not get 'recipe.objcopy.hex'") endif() + if ("${ARDUINO_OBJCOPY_HEX_CMD}" MATCHES "^python \"(.*)\"$") + set(ARDUINO_OBJCOPY_HEX_CMD ${CMAKE_MATCH_1}) + endif() string(REPLACE "\"" "" ARDUINO_OBJCOPY_HEX_FLAGS ${ARDUINO_OBJCOPY_HEX_FLAGS}) string(REPLACE " " ";" ARDUINO_OBJCOPY_HEX_FLAGS ${ARDUINO_OBJCOPY_HEX_FLAGS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD @@ -1779,24 +1795,24 @@ function(GET_VARIABLE_VALUE_FILLED VARIABLE_RETURN SETTING_VALUE BOARD_ID SETTIN unset(VAR_VALUE) unset(VAR_NAME) - set(PREFIXED_NAME_PLATFORM "${PLATFORM}.${i}") - set(PREFIXED_NAME_BOARD "${BOARD_ID}.${i}") - set(PREFIXED_CPU "${BOARD_ID}${ARDUINO_CPUMENU}.${i}") - if (DEFINED ${PREFIXED_NAME_BOARD}) - set(VAR_VALUE "${${PREFIXED_NAME_BOARD}}") - set(VAR_NAME "${PREFIXED_NAME_BOARD}") - elseif(DEFINED ${PREFIXED_NAME_PLATFORM}) - set(VAR_VALUE "${${PREFIXED_NAME_PLATFORM}}") - set(VAR_NAME "${PREFIXED_NAME_PLATFORM}") - elseif(DEFINED ${PREFIXED_CPU} ) - set(VAR_VALUE "${${PREFIXED_CPU}}") - set(VAR_NAME "${PREFIXED_CPU}") - elseif(DEFINED ${i}) - set(VAR_VALUE "${${i}}") - set(VAR_NAME "${i}") - else() - #MESSAGE(FATAL_ERROR "${i} not found in settings") - endif() + set(VARIABLES_TO_CHECK + "${BOARD_ID}${ARDUINO_CPUMENU}.${i}.${runtime.os}" + "${BOARD_ID}${ARDUINO_CPUMENU}.${i}" + "${BOARD_ID}.${i}.${runtime.os}" + "${BOARD_ID}.${i}" + "${PLATFORM}.${i}.${runtime.os}" + "${PLATFORM}.${i}" + "${i}.${runtime.os}" + "${i}" + ) + + foreach(VAR_CHECK ${VARIABLES_TO_CHECK}) + if (DEFINED ${VAR_CHECK}) + set(VAR_VALUE "${${VAR_CHECK}}") + set(VAR_NAME "${VAR_CHECK}") + break() + endif() + endforeach() if(NOT DEFINED VAR_VALUE AND SETTING_NAME) # check if the value is somewhere available along the path leading to this setting @@ -1808,7 +1824,11 @@ function(GET_VARIABLE_VALUE_FILLED VARIABLE_RETURN SETTING_VALUE BOARD_ID SETTIN while (SETTING_NAME_BASE MATCHES "^(.+)\\.[^\\.]+\$") set(SETTING_NAME_BASE "${CMAKE_MATCH_1}") set(CUR_VAR_NAME "${SETTING_NAME_BASE}.${i}") - if(DEFINED ${CUR_VAR_NAME}) + if(DEFINED ${CUR_VAR_NAME}.${runtime.os}) + set(VAR_VALUE "${${CUR_VAR_NAME}.${runtime.os}}") + set(VAR_NAME "${CUR_VAR_NAME}.${runtime.os}") + break() + elseif(DEFINED ${CUR_VAR_NAME}) set(VAR_VALUE "${${CUR_VAR_NAME}}") set(VAR_NAME "${CUR_VAR_NAME}") break() @@ -2414,7 +2434,8 @@ set(runtime.tools.avr-gcc.path "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE IN set(runtime.tools.avrdude.path "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE INTERNAL "") set(runtime.tools.arduinoOTA.path "${ARDUINO_SDK_PATH}/hardware/tools/avr" CACHE INTERNAL "") - +#TODO Fixme for windows +set(runtime.os "linux" CACHE INTERNAL "") if(ARDUINO_SDK_VERSION MATCHES "([0-9]+)[.]([0-9]+)[.]([0-9]+)") string(REPLACE "." "" ARDUINO_VERSION_DEFINE "${ARDUINO_SDK_VERSION}") # Normalize version (remove all periods) @@ -2442,14 +2463,6 @@ set(program.verbose "-V" CACHE INTERNAL "") set(bootloader.verbose "-V" CACHE INTERNAL "") set(erase.verbose "-V" CACHE INTERNAL "") -if (WIN32) - set(runtime.os "windows" CACHE INTERNAL "") -elseif(UNIX) - set(runtime.os "linux" CACHE INTERNAL "") -elseif(APPLE) - set(runtime.os "macosx" CACHE INTERNAL "") -endif() - if(ARDUINO_SDK_VERSION VERSION_LESS 1.5) set(ARDUINO_PLATFORM "AVR") diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index c9ddf6f..961ef54 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -17,3 +17,4 @@ set(${PROJECT_NAME}_CPU 16MHzatmega328) # Command to generate code arduino firmware (.hex file) generate_arduino_firmware(${PROJECT_NAME}) + diff --git a/example_esp32/CMakeLists.txt b/example_esp32/CMakeLists.txt new file mode 100644 index 0000000..3e69ea2 --- /dev/null +++ b/example_esp32/CMakeLists.txt @@ -0,0 +1,22 @@ +# Set a variable for commands below +set(PROJECT_NAME example_esp32) + +# Define your project and language +project(${PROJECT_NAME}) + +set(${PROJECT_NAME}_BOARD featheresp32) + +# Define the source code +set(${PROJECT_NAME}_SRCS example_esp32.cpp) + +# Define the port for uploading code to the Arduino +set(${PROJECT_NAME}_PORT COM6) + +# Select a specific upload speed for the board +set(${${PROJECT_NAME}_BOARD}.upload.speed 921600) + +# Select a specific flash frequence for the board +set(${${PROJECT_NAME}_BOARD}.build.flash_freq 80m) + +# Command to generate code arduino firmware (.hex file) +generate_arduino_firmware(${PROJECT_NAME}) diff --git a/example_esp32/example_esp32.cpp b/example_esp32/example_esp32.cpp new file mode 100644 index 0000000..797a864 --- /dev/null +++ b/example_esp32/example_esp32.cpp @@ -0,0 +1,23 @@ +#include "Arduino.h" + +#define LED_PIN 13 + +void setup() { + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); + + Serial.begin(9600); +} + +void loop() { + Serial.println("Example arduino project in CLion"); + + for (int i = 0; i < 2; i++) { + digitalWrite(LED_PIN, HIGH); + delay(100); + digitalWrite(LED_PIN, LOW); + delay(100); + } + + delay(1000); +} From 1421d0bc1b4a34bea71cf00b3149ab73b70d79f2 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Fri, 2 Feb 2018 17:57:26 +0100 Subject: [PATCH 24/29] Compile with ap example. Not yet working --- CMakeLists.txt | 3 +- cmake/Platform/Arduino.cmake | 74 ++++-- example_ap/CMakeLists.txt | 26 +++ example_ap/aes.c | 390 ++++++++++++++++++++++++++++++++ example_ap/wifi_ap.cpp | 83 +++++++ example_esp32/CMakeLists.txt | 2 +- example_esp32/example_esp32.cpp | 9 +- 7 files changed, 564 insertions(+), 23 deletions(-) create mode 100644 example_ap/CMakeLists.txt create mode 100644 example_ap/aes.c create mode 100644 example_ap/wifi_ap.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 014b669..d909530 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,4 +28,5 @@ link_directories(${ARDUINO_SDK}/libraries) # add the project directory into build #add_subdirectory(example) -add_subdirectory(example_esp32) +#add_subdirectory(example_esp32) +add_subdirectory(example_ap) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index c8ed1cd..c33b299 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -459,7 +459,7 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) parse_generator_arguments(${INPUT_NAME} INPUT "NO_AUTOLIBS;MANUAL" # Options "BOARD;PORT;SKETCH;PROGRAMMER;CPU" # One Value Keywords - "SERIAL;SRCS;HDRS;LIBS;ARDLIBS;AFLAGS" # Multi Value Keywords + "SERIAL;SRCS;HDRS;LIBS;ARDLIBS;ARDLIBS_PATH;AFLAGS" # Multi Value Keywords ${ARGN}) if(NOT INPUT_BOARD) @@ -528,14 +528,14 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) required_variables(VARS ALL_SRCS MSG "must define SRCS or SKETCH for target ${INPUT_NAME}") - find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "${INPUT_ARDLIBS}") + find_arduino_libraries(TARGET_LIBS "${ALL_SRCS}" "${INPUT_ARDLIBS}" "${INPUT_ARDLIBS_PATH}") foreach(LIB_DEP ${TARGET_LIBS}) arduino_debug_msg("Arduino Library: ${LIB_DEP}") set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} -I\"${LIB_DEP}\" -I\"${LIB_DEP}/src\"") endforeach() if(NOT INPUT_NO_AUTOLIBS) - setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${INPUT_ARDLIBS}" "${LIB_DEP_INCLUDES}" "") + setup_arduino_libraries(ALL_LIBS ${INPUT_BOARD} "${ALL_SRCS}" "${INPUT_ARDLIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_ARDLIBS_PATH}") foreach(LIB_INCLUDES ${ALL_LIBS_INCLUDES}) arduino_debug_msg("Arduino Library Includes: ${LIB_INCLUDES}") set(LIB_DEP_INCLUDES "${LIB_DEP_INCLUDES} ${LIB_INCLUDES}") @@ -543,7 +543,6 @@ function(GENERATE_ARDUINO_FIRMWARE INPUT_NAME) endif() list(APPEND ALL_LIBS ${CORE_LIB} ${INPUT_LIBS}) - setup_arduino_target(${INPUT_NAME} ${INPUT_BOARD} "${ALL_SRCS}" "${ALL_LIBS}" "${LIB_DEP_INCLUDES}" "" "${INPUT_MANUAL}") if(INPUT_PORT) @@ -990,6 +989,8 @@ endfunction() # VAR_NAME - Variable name which will hold the results # SRCS - Sources that will be analized # ARDLIBS - Arduino libraries identified by name (e.g., Wire, SPI, Servo) +# PATH_OVERRIDE - Optional override search path for library to have unique path for libs with the same name. +# e.g. Arduino provides its WiFi lib, as well as ESP32 # # returns a list of paths to libraries found. # @@ -1011,7 +1012,7 @@ endfunction() # to be part of that Arduino library. # #=============================================================================# -function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) +function(find_arduino_libraries VAR_NAME SRCS ARDLIBS PATH_OVERRIDE) get_property(include_dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES) set(ARDUINO_LIBS ) @@ -1036,13 +1037,20 @@ function(find_arduino_libraries VAR_NAME SRCS ARDLIBS) list(APPEND SRC_CONTENTS "#include <${LIBNAME}.h>") endforeach() + if(PATH_OVERRIDE) + set(LIB_SEARCH_PATHS ${PATH_OVERRIDE}) + else() + set(LIB_SEARCH_PATHS ${include_dirs} ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) + endif() + + get_property(LIBRARY_SEARCH_PATH + DIRECTORY # Property Scope + PROPERTY LINK_DIRECTORIES) + foreach(SRC_LINE ${SRC_CONTENTS}) if("#${SRC_LINE}#" MATCHES "^#[ \t]*#[ \t]*include[ \t]*[<\"]([^>\"]*)[>\"]#") get_filename_component(INCLUDE_NAME ${CMAKE_MATCH_1} NAME_WE) - get_property(LIBRARY_SEARCH_PATH - DIRECTORY # Property Scope - PROPERTY LINK_DIRECTORIES) - foreach(LIB_SEARCH_PATH ${include_dirs} ${LIBRARY_SEARCH_PATH} ${ARDUINO_LIBRARIES_PATH} ${${ARDUINO_PLATFORM}_LIBRARIES_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libraries ${ARDUINO_EXTRA_LIBRARIES_PATH}) + foreach(LIB_SEARCH_PATH ${LIB_SEARCH_PATHS}) if(EXISTS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}/${CMAKE_MATCH_1}) list(APPEND ARDUINO_LIBS ${LIB_SEARCH_PATH}/${INCLUDE_NAME}) break() @@ -1097,12 +1105,19 @@ set(LiquidCrystal_RECURSE True) set(TFT_RECURSE True) set(WiFi_RECURSE True) set(Robot_Control_RECURSE True) -function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS) +function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLAGS PATH_OVERRIDE) set(LIB_TARGETS) set(LIB_INCLUDES) get_filename_component(LIB_NAME ${LIB_PATH} NAME) set(TARGET_LIB_NAME ${BOARD_ID}_${LIB_NAME}) + + + if(NOT EXECUTABLE_OUTPUT_PATH) + set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + endif() + set(TARGET_PATH ${EXECUTABLE_OUTPUT_PATH}/${TARGET_LIB_NAME}) + if(NOT TARGET ${TARGET_LIB_NAME}) string(REGEX REPLACE ".*/" "" LIB_SHORT_NAME ${LIB_NAME}) @@ -1120,16 +1135,42 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA include_directories(${LIB_PATH}/src) include_directories(${LIB_PATH}/utility) - get_arduino_flags(ARDUINO_COMPILE_FLAGS ARDUINO_LINK_FLAGS ${BOARD_ID} FALSE) - find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "") + get_recipe_flags(ARDUINO_COMPILE_CMD ARDUINO_COMPILE_FLAGS ${BOARD_ID} "recipe.cpp.o") + if(NOT DEFINED ARDUINO_COMPILE_FLAGS) + MESSAGE(FATAL_ERROR "Could not get 'recipe.cpp.o'") + endif() + + if(NOT "${CMAKE_CXX_COMPILER}" STREQUAL "${ARDUINO_COMPILE_CMD}") + MESSAGE(WARNING "Your compiler needs to be manually set to\nCMAKE_CXX_COMPILER=\"${ARDUINO_COMPILE_CMD}\"") + endif() + + get_recipe_flags(ARDUINO_LINK_CMD ARDUINO_LINK_FLAGS ${BOARD_ID} "recipe.c.combine") + if(NOT DEFINED ARDUINO_LINK_FLAGS) + MESSAGE(WARNING "Could not get 'recipe.c.combine'") + endif() + + + string(REPLACE "\"{build.path}/{archive_file}\"" "" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) + string(REPLACE "{object_files}" "" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) + string(REPLACE "{build.path}" "${EXECUTABLE_OUTPUT_PATH}" ARDUINO_LINK_FLAGS ${ARDUINO_LINK_FLAGS}) + + set_target_properties(${TARGET_NAME} PROPERTIES + COMPILE_FLAGS "${ARDUINO_COMPILE_FLAGS} ${COMPILE_FLAGS}" + LINK_FLAGS "${ARDUINO_LINK_FLAGS}" + ARCHIVE_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + LIBRARY_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" + ) + + find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "" ${PATH_OVERRIDE}) foreach(LIB_DEP ${LIB_DEPS}) if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME AND DEP_LIB_SRCS) message(STATUS "Found library ${LIB_NAME} needs ${DEP_LIB_SRCS}") endif() - setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} "${COMPILE_FLAGS}" "${LINK_FLAGS}") + setup_arduino_library(DEP_LIB_SRCS ${BOARD_ID} ${LIB_DEP} "${COMPILE_FLAGS}" "${LINK_FLAGS}" "${PATH_OVERRIDE}") # Do not link to this library. DEP_LIB_SRCS will always be only one entry # if we are looking at the same library. if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME) @@ -1176,14 +1217,14 @@ endfunction() # Finds and creates all dependency libraries based on sources. # #=============================================================================# -function(setup_arduino_libraries VAR_NAME BOARD_ID SRCS ARDLIBS COMPILE_FLAGS LINK_FLAGS) +function(setup_arduino_libraries VAR_NAME BOARD_ID SRCS ARDLIBS COMPILE_FLAGS LINK_FLAGS PATH_OVERRIDE) set(LIB_TARGETS) set(LIB_INCLUDES) - find_arduino_libraries(TARGET_LIBS "${SRCS}" ARDLIBS) + find_arduino_libraries(TARGET_LIBS "${SRCS}" "${ARDLIBS}" "${PATH_OVERRIDE}") foreach(TARGET_LIB ${TARGET_LIBS}) # Create static library instead of returning sources - setup_arduino_library(LIB_DEPS ${BOARD_ID} ${TARGET_LIB} "${COMPILE_FLAGS}" "${LINK_FLAGS}") + setup_arduino_library(LIB_DEPS ${BOARD_ID} ${TARGET_LIB} "${COMPILE_FLAGS}" "${LINK_FLAGS}" "${PATH_OVERRIDE}") list(APPEND LIB_TARGETS ${LIB_DEPS}) list(APPEND LIB_INCLUDES ${LIB_DEPS_INCLUDES}) endforeach() @@ -1257,7 +1298,6 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if ("${ARDUINO_OBJCOPY_EEP_CMD}" MATCHES "^python \"(.*)\"$") set(ARDUINO_OBJCOPY_EEP_CMD ${CMAKE_MATCH_1}) endif() - string(REPLACE "\"" "" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) string(REPLACE "\"" "" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) string(REPLACE " " ";" ARDUINO_OBJCOPY_EEP_FLAGS ${ARDUINO_OBJCOPY_EEP_FLAGS}) diff --git a/example_ap/CMakeLists.txt b/example_ap/CMakeLists.txt new file mode 100644 index 0000000..77f7c59 --- /dev/null +++ b/example_ap/CMakeLists.txt @@ -0,0 +1,26 @@ +# Set a variable for commands below +set(PROJECT_NAME example_ap) + +# Define your project and language +project(${PROJECT_NAME}) + +set(${PROJECT_NAME}_BOARD featheresp32) + +# Define the source code +set(${PROJECT_NAME}_SRCS wifi_ap.cpp aes.c) + +# Define the port for uploading code to the Arduino +set(${PROJECT_NAME}_PORT /dev/ttyUSB0) + +# Select a specific upload speed for the board +set(${${PROJECT_NAME}_BOARD}.upload.speed 921600) + +# Select a specific flash frequence for the board +set(${${PROJECT_NAME}_BOARD}.build.flash_freq 80m) + +set(${PROJECT_NAME}_LIBS esp32 mbedtls wpa_supplicant) +#set(${PROJECT_NAME}_ARDLIBS WiFi) +#set(${PROJECT_NAME}_ARDLIBS_PATH ${ESP32_LIBRARIES_PATH}) + +# Command to generate code arduino firmware (.hex file) +generate_arduino_firmware(${PROJECT_NAME}) diff --git a/example_ap/aes.c b/example_ap/aes.c new file mode 100644 index 0000000..59ff4cd --- /dev/null +++ b/example_ap/aes.c @@ -0,0 +1,390 @@ +/** + * \brief AES block cipher, ESP32 hardware accelerated version + * Based on mbedTLS FIPS-197 compliant version. + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Additions Copyright (C) 2016-2017, Espressif Systems (Shanghai) PTE Ltd + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +// hardcoded since somehow the quotes are remove from the value +#define MBEDTLS_CONFIG_FILE "mbedtls/esp_config.h" + +#include +#include "mbedtls/aes.h" +#include "hwcrypto/aes.h" +#include "soc/dport_reg.h" +#include "soc/hwcrypto_reg.h" +#include + +#include + +#include "soc/cpu.h" +#include + + +/* AES uses a spinlock mux not a lock as the underlying block operation + only takes 208 cycles (to write key & compute block), +600 cycles + for DPORT protection but +3400 cycles again if you use a full sized lock. + + For CBC, CFB, etc. this may mean that interrupts are disabled for a longer + period of time for bigger lengths. However at the moment this has to happen + anyway due to DPORT protection... +*/ +static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED; + +void esp_aes_acquire_hardware( void ) +{ + /* newlib locks lazy initialize on ESP-IDF */ + portENTER_CRITICAL(&aes_spinlock); + + DPORT_STALL_OTHER_CPU_START(); + { + /* Enable AES hardware */ + _DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES); + /* Clear reset on digital signature & secure boot units, + otherwise AES unit is held in reset also. */ + _DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG, + DPORT_PERI_EN_AES + | DPORT_PERI_EN_DIGITAL_SIGNATURE + | DPORT_PERI_EN_SECUREBOOT); + } + DPORT_STALL_OTHER_CPU_END(); +} + +void esp_aes_release_hardware( void ) +{ + DPORT_STALL_OTHER_CPU_START(); + { + /* Disable AES hardware */ + _DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES); + /* Don't return other units to reset, as this pulls + reset on RSA & SHA units, respectively. */ + _DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES); + } + DPORT_STALL_OTHER_CPU_END(); + + portEXIT_CRITICAL(&aes_spinlock); +} + +void esp_aes_init( esp_aes_context *ctx ) +{ + bzero( ctx, sizeof( esp_aes_context ) ); +} + +void esp_aes_free( esp_aes_context *ctx ) +{ + if ( ctx == NULL ) { + return; + } + + bzero( ctx, sizeof( esp_aes_context ) ); +} + +/* + * AES key schedule (same for encryption or decryption, as hardware handles schedule) + * + */ +int esp_aes_setkey( esp_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + if (keybits != 128 && keybits != 192 && keybits != 256) { + return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; + } + ctx->key_bytes = keybits / 8; + memcpy(ctx->key, key, ctx->key_bytes); + return 0; +} + +/* + * Helper function to copy key from esp_aes_context buffer + * to hardware key registers. + * + * Call only while holding esp_aes_acquire_hardware(). + */ +static inline void esp_aes_setkey_hardware( esp_aes_context *ctx, int mode) +{ + const uint32_t MODE_DECRYPT_BIT = 4; + unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT; + + memcpy((uint32_t *)AES_KEY_BASE, ctx->key, ctx->key_bytes); + DPORT_REG_WRITE(AES_MODE_REG, mode_reg_base + ((ctx->key_bytes / 8) - 2)); +} + +/* Run a single 16 byte block of AES, using the hardware engine. + * + * Call only while holding esp_aes_acquire_hardware(). + */ +static inline void esp_aes_block(const void *input, void *output) +{ + const uint32_t *input_words = (const uint32_t *)input; + uint32_t *output_words = (uint32_t *)output; + uint32_t *mem_block = (uint32_t *)AES_TEXT_BASE; + + for(int i = 0; i < 4; i++) { + mem_block[i] = input_words[i]; + } + + DPORT_REG_WRITE(AES_START_REG, 1); + + DPORT_STALL_OTHER_CPU_START(); + { + while (_DPORT_REG_READ(AES_IDLE_REG) != 1) { } + for (int i = 0; i < 4; i++) { + output_words[i] = mem_block[i]; + } + } + DPORT_STALL_OTHER_CPU_END(); +} + +/* + * AES-ECB block encryption + */ +void esp_aes_encrypt( esp_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + esp_aes_acquire_hardware(); + esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT); + esp_aes_block(input, output); + esp_aes_release_hardware(); +} + +/* + * AES-ECB block decryption + */ + +void esp_aes_decrypt( esp_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + esp_aes_acquire_hardware(); + esp_aes_setkey_hardware(ctx, ESP_AES_DECRYPT); + esp_aes_block(input, output); + esp_aes_release_hardware(); +} + + +/* + * AES-ECB block encryption/decryption + */ +int esp_aes_crypt_ecb( esp_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + esp_aes_acquire_hardware(); + esp_aes_setkey_hardware(ctx, mode); + esp_aes_block(input, output); + esp_aes_release_hardware(); + + return 0; +} + + +/* + * AES-CBC buffer encryption/decryption + */ +int esp_aes_crypt_cbc( esp_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + uint32_t *output_words = (uint32_t *)output; + const uint32_t *input_words = (const uint32_t *)input; + uint32_t *iv_words = (uint32_t *)iv; + unsigned char temp[16]; + + if ( length % 16 ) { + return ( ERR_ESP_AES_INVALID_INPUT_LENGTH ); + } + + esp_aes_acquire_hardware(); + + esp_aes_setkey_hardware(ctx, mode); + + if ( mode == ESP_AES_DECRYPT ) { + while ( length > 0 ) { + memcpy(temp, input_words, 16); + esp_aes_block(input_words, output_words); + + for ( i = 0; i < 4; i++ ) { + output_words[i] = output_words[i] ^ iv_words[i]; + } + + memcpy( iv_words, temp, 16 ); + + input_words += 4; + output_words += 4; + length -= 16; + } + } else { // ESP_AES_ENCRYPT + while ( length > 0 ) { + + for ( i = 0; i < 4; i++ ) { + output_words[i] = input_words[i] ^ iv_words[i]; + } + + esp_aes_block(output_words, output_words); + memcpy( iv_words, output_words, 16 ); + + input_words += 4; + output_words += 4; + length -= 16; + } + } + + esp_aes_release_hardware(); + + return 0; +} + +/* + * AES-CFB128 buffer encryption/decryption + */ +int esp_aes_crypt_cfb128( esp_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + esp_aes_acquire_hardware(); + + esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT); + + if ( mode == ESP_AES_DECRYPT ) { + while ( length-- ) { + if ( n == 0 ) { + esp_aes_block(iv, iv ); + } + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } else { + while ( length-- ) { + if ( n == 0 ) { + esp_aes_block(iv, iv ); + } + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + esp_aes_release_hardware(); + + return 0; +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +int esp_aes_crypt_cfb8( esp_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + esp_aes_acquire_hardware(); + + esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT); + + while ( length-- ) { + memcpy( ov, iv, 16 ); + esp_aes_block(iv, iv); + + if ( mode == ESP_AES_DECRYPT ) { + ov[16] = *input; + } + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if ( mode == ESP_AES_ENCRYPT ) { + ov[16] = c; + } + + memcpy( iv, ov + 1, 16 ); + } + + esp_aes_release_hardware(); + + return 0; +} + +/* + * AES-CTR buffer encryption/decryption + */ +int esp_aes_crypt_ctr( esp_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + esp_aes_acquire_hardware(); + + esp_aes_setkey_hardware(ctx, ESP_AES_ENCRYPT); + + while ( length-- ) { + if ( n == 0 ) { + esp_aes_block(nonce_counter, stream_block); + + for ( i = 16; i > 0; i-- ) + if ( ++nonce_counter[i - 1] != 0 ) { + break; + } + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + esp_aes_release_hardware(); + + return 0; +} diff --git a/example_ap/wifi_ap.cpp b/example_ap/wifi_ap.cpp new file mode 100644 index 0000000..31ac9e3 --- /dev/null +++ b/example_ap/wifi_ap.cpp @@ -0,0 +1,83 @@ + +#include "Arduino.h" +#include +//#include "freertos/FreeRTOS.h" +#include "esp_wifi.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_event_loop.h" +#include "nvs_flash.h" +#include "driver/gpio.h" +#include + + +#define LED_PIN 5 + +esp_err_t event_handler(void *ctx, system_event_t *event) +{ + return ESP_OK; +} + + +void setup() { + + + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); + + nvs_flash_init(); + tcpip_adapter_init(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); + wifi_config_t sta_config; + sta_config.ap.authmode = WIFI_AUTH_WPA2_PSK; + sta_config.ap.channel = 0; + + sta_config.ap.ssid[0] = 'E'; + sta_config.ap.ssid[1] = 'S'; + sta_config.ap.ssid[2] = 'P'; + sta_config.ap.ssid[3] = '3'; + sta_config.ap.ssid[4] = '2'; + sta_config.ap.ssid[5] = 'A'; + sta_config.ap.ssid[6] = 'P'; + sta_config.ap.ssid[7] = '0'; + sta_config.ap.ssid_len = 7; + + sta_config.ap.password[0] = 'f'; + sta_config.ap.password[1] = 'o'; + sta_config.ap.password[2] = 'r'; + sta_config.ap.password[3] = 't'; + sta_config.ap.password[4] = 'i'; + sta_config.ap.password[5] = 's'; + sta_config.ap.password[6] = 's'; + sta_config.ap.password[7] = '1'; + sta_config.ap.password[8] = '2'; + sta_config.ap.password[9] = '3'; + sta_config.ap.password[10] = 0; + + + sta_config.ap.ssid_hidden = 0; + sta_config.ap.max_connection = 1; + sta_config.ap.beacon_interval = 100; + ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) ); + ESP_ERROR_CHECK( esp_wifi_start() ); + ESP_ERROR_CHECK( esp_wifi_connect() ); + + gpio_set_direction(GPIO_NUM_13, GPIO_MODE_OUTPUT); +} + +void loop() { + + for (int i = 0; i < 2; i++) { + digitalWrite(LED_PIN, HIGH); + delay(1000); + digitalWrite(LED_PIN, LOW); + delay(1000); + } + + //vTaskDelay(300 / portTICK_PERIOD_MS); + +} \ No newline at end of file diff --git a/example_esp32/CMakeLists.txt b/example_esp32/CMakeLists.txt index 3e69ea2..9e6c110 100644 --- a/example_esp32/CMakeLists.txt +++ b/example_esp32/CMakeLists.txt @@ -10,7 +10,7 @@ set(${PROJECT_NAME}_BOARD featheresp32) set(${PROJECT_NAME}_SRCS example_esp32.cpp) # Define the port for uploading code to the Arduino -set(${PROJECT_NAME}_PORT COM6) +set(${PROJECT_NAME}_PORT /dev/ttyUSB2) # Select a specific upload speed for the board set(${${PROJECT_NAME}_BOARD}.upload.speed 921600) diff --git a/example_esp32/example_esp32.cpp b/example_esp32/example_esp32.cpp index 797a864..d492b31 100644 --- a/example_esp32/example_esp32.cpp +++ b/example_esp32/example_esp32.cpp @@ -1,22 +1,23 @@ #include "Arduino.h" -#define LED_PIN 13 +#define LED_PIN 23 void setup() { pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); Serial.begin(9600); + Serial.println("Example arduino start"); } void loop() { - Serial.println("Example arduino project in CLion"); + Serial.println("loop"); for (int i = 0; i < 2; i++) { digitalWrite(LED_PIN, HIGH); - delay(100); + delay(1000); digitalWrite(LED_PIN, LOW); - delay(100); + delay(1000); } delay(1000); From cd982e7a72601fb480becaa70aeb6cfb7b3243ee Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Fri, 2 Feb 2018 18:26:59 +0100 Subject: [PATCH 25/29] Working example for WLAN led --- example_ap/CMakeLists.txt | 7 +- example_ap/wifi_ap.cpp | 181 +++++++++++++++++++++++--------------- 2 files changed, 116 insertions(+), 72 deletions(-) diff --git a/example_ap/CMakeLists.txt b/example_ap/CMakeLists.txt index 77f7c59..4dcc567 100644 --- a/example_ap/CMakeLists.txt +++ b/example_ap/CMakeLists.txt @@ -18,9 +18,10 @@ set(${${PROJECT_NAME}_BOARD}.upload.speed 921600) # Select a specific flash frequence for the board set(${${PROJECT_NAME}_BOARD}.build.flash_freq 80m) -set(${PROJECT_NAME}_LIBS esp32 mbedtls wpa_supplicant) -#set(${PROJECT_NAME}_ARDLIBS WiFi) -#set(${PROJECT_NAME}_ARDLIBS_PATH ${ESP32_LIBRARIES_PATH}) + +set(${PROJECT_NAME}_ARDLIBS WiFi) +set(${PROJECT_NAME}_ARDLIBS_PATH ${ESP32_LIBRARIES_PATH}) +set(${PROJECT_NAME}_LIBS esp32 wpa_supplicant lwip) # Command to generate code arduino firmware (.hex file) generate_arduino_firmware(${PROJECT_NAME}) diff --git a/example_ap/wifi_ap.cpp b/example_ap/wifi_ap.cpp index 31ac9e3..1492d95 100644 --- a/example_ap/wifi_ap.cpp +++ b/example_ap/wifi_ap.cpp @@ -1,83 +1,126 @@ +/* + WiFi Web Server LED Blink -#include "Arduino.h" -#include -//#include "freertos/FreeRTOS.h" -#include "esp_wifi.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_event_loop.h" -#include "nvs_flash.h" -#include "driver/gpio.h" -#include + A simple web server that lets you blink an LED via the web. + This sketch will print the IP address of your WiFi Shield (once connected) + to the Serial monitor. From there, you can open that address in a web browser + to turn on and off the LED on pin 5. + If the IP address of your shield is yourAddress: + http://yourAddress/H turns the LED on + http://yourAddress/L turns it off -#define LED_PIN 5 + This example is written for a network using WPA encryption. For + WEP or WPA, change the Wifi.begin() call accordingly. -esp_err_t event_handler(void *ctx, system_event_t *event) -{ - return ESP_OK; -} + Circuit: + * WiFi shield attached + * LED attached to pin 5 + created for arduino 25 Nov 2012 + by Tom Igoe -void setup() { - - - pinMode(LED_PIN, OUTPUT); - digitalWrite(LED_PIN, LOW); - - nvs_flash_init(); - tcpip_adapter_init(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - wifi_config_t sta_config; - sta_config.ap.authmode = WIFI_AUTH_WPA2_PSK; - sta_config.ap.channel = 0; - - sta_config.ap.ssid[0] = 'E'; - sta_config.ap.ssid[1] = 'S'; - sta_config.ap.ssid[2] = 'P'; - sta_config.ap.ssid[3] = '3'; - sta_config.ap.ssid[4] = '2'; - sta_config.ap.ssid[5] = 'A'; - sta_config.ap.ssid[6] = 'P'; - sta_config.ap.ssid[7] = '0'; - sta_config.ap.ssid_len = 7; - - sta_config.ap.password[0] = 'f'; - sta_config.ap.password[1] = 'o'; - sta_config.ap.password[2] = 'r'; - sta_config.ap.password[3] = 't'; - sta_config.ap.password[4] = 'i'; - sta_config.ap.password[5] = 's'; - sta_config.ap.password[6] = 's'; - sta_config.ap.password[7] = '1'; - sta_config.ap.password[8] = '2'; - sta_config.ap.password[9] = '3'; - sta_config.ap.password[10] = 0; - - - sta_config.ap.ssid_hidden = 0; - sta_config.ap.max_connection = 1; - sta_config.ap.beacon_interval = 100; - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); - ESP_ERROR_CHECK( esp_wifi_connect() ); - - gpio_set_direction(GPIO_NUM_13, GPIO_MODE_OUTPUT); -} +ported for sparkfun esp32 +31.01.2017 by Jan Hendrik Berlin + + */ + +#include "WiFi.h" -void loop() { +const char* ssid = "your_ssid"; +const char* password = "your_pwd"; - for (int i = 0; i < 2; i++) { - digitalWrite(LED_PIN, HIGH); +WiFiServer server(80); + +void setup() +{ + Serial.begin(115200); + pinMode(5, OUTPUT); // set the LED pin mode + for (int i = 0; i < 5; i++) { + digitalWrite(5, HIGH); delay(1000); - digitalWrite(LED_PIN, LOW); + digitalWrite(5, LOW); delay(1000); } - //vTaskDelay(300 / portTICK_PERIOD_MS); + // We start by connecting to a WiFi network + + Serial.println(); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.flush(); + + server.begin(); + +} + +int value = 0; + +void loop(){ + + + WiFiClient client = server.available(); // listen for incoming clients + + + + if (client) { // if you get a client, + Serial.println("New Client."); // print a message out the serial port + String currentLine = ""; // make a String to hold incoming data from the client + while (client.connected()) { // loop while the client's connected + if (client.available()) { // if there's bytes to read from the client, + char c = client.read(); // read a byte, then + Serial.write(c); // print it out the serial monitor + if (c == '\n') { // if the byte is a newline character + + // if the current line is blank, you got two newline characters in a row. + // that's the end of the client HTTP request, so send a response: + if (currentLine.length() == 0) { + // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) + // and a content-type so the client knows what's coming, then a blank line: + client.println("HTTP/1.1 200 OK"); + client.println("Content-type:text/html"); + client.println(); + + // the content of the HTTP response follows the header: + client.print("Click here to turn the LED on pin 5 on.
"); + client.print("Click here to turn the LED on pin 5 off.
"); + + // The HTTP response ends with another blank line: + client.println(); + // break out of the while loop: + break; + } else { // if you got a newline, then clear currentLine: + currentLine = ""; + } + } else if (c != '\r') { // if you got anything else but a carriage return character, + currentLine += c; // add it to the end of the currentLine + } + + // Check to see if the client request was "GET /H" or "GET /L": + if (currentLine.endsWith("GET /H")) { + digitalWrite(5, HIGH); // GET /H turns the LED on + } + if (currentLine.endsWith("GET /L")) { + digitalWrite(5, LOW); // GET /L turns the LED off + } + } + } + // close the connection: + client.stop(); + Serial.println("Client Disconnected."); + } } \ No newline at end of file From 650a0c09109eaf3ee78198d9c4d6e90625b2384a Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Wed, 14 Feb 2018 15:44:09 +0100 Subject: [PATCH 26/29] Add the corresponding compiler settings for esp32 --- example_ap/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/example_ap/CMakeLists.txt b/example_ap/CMakeLists.txt index 4dcc567..cc63aa5 100644 --- a/example_ap/CMakeLists.txt +++ b/example_ap/CMakeLists.txt @@ -1,3 +1,12 @@ +# ESP32 needs some special compilers. Set them here +SET(CMAKE_C_COMPILER "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc") +SET(CMAKE_C_COMPILER_WORKS 1) +SET(CMAKE_CXX_COMPILER "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-g++") +SET(CMAKE_CXX_COMPILER_WORKS 1) +SET(CMAKE_AR "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-ar") +SET(CMAKE_RANLIB "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-ranlib") + + # Set a variable for commands below set(PROJECT_NAME example_ap) From 55c2bfd2737b818394e5bd61be4a13f774b4f736 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Fri, 16 Feb 2018 19:17:18 +0100 Subject: [PATCH 27/29] Add percentage output for avr-size script --- CMakeLists.txt | 4 +- cmake/Platform/Arduino.cmake | 84 +++++++++++++------ cmake/Platform/size_script.py | 153 ++++++++++++++++++++++++++++++++++ example/CMakeLists.txt | 7 ++ example_esp32/CMakeLists.txt | 9 ++ 5 files changed, 229 insertions(+), 28 deletions(-) create mode 100644 cmake/Platform/size_script.py diff --git a/CMakeLists.txt b/CMakeLists.txt index d909530..4f349ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,6 @@ project(ArduinoExample) link_directories(${ARDUINO_SDK}/libraries) # add the project directory into build -#add_subdirectory(example) +add_subdirectory(example) #add_subdirectory(example_esp32) -add_subdirectory(example_ap) +#add_subdirectory(example_ap) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index c33b299..6abd041 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -285,7 +285,7 @@ cmake_minimum_required(VERSION 2.8.5) include(CMakeParseArguments) - +find_package(PythonInterp REQUIRED) @@ -1252,6 +1252,9 @@ endfunction() #=============================================================================# function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLAGS LINK_FLAGS MANUAL) + + set(PLATFORM ${${BOARD_ID}.PLATFORM}) + add_executable(${TARGET_NAME} ${ALL_SRCS}) set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".elf") @@ -1328,21 +1331,38 @@ function(setup_arduino_target TARGET_NAME BOARD_ID ALL_SRCS ALL_LIBS COMPILE_FLA if(NOT DEFINED ARDUINO_SIZE_FLAGS) MESSAGE(FATAL_ERROR "Could not get 'recipe.size'") endif() - string(REPLACE "\"" "" ARDUINO_SIZE_FLAGS ${ARDUINO_SIZE_FLAGS}) - string(REPLACE " " ";" ARDUINO_SIZE_FLAGS ${ARDUINO_SIZE_FLAGS}) - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${ARDUINO_SIZE_CMD} - ARGS ${ARDUINO_SIZE_FLAGS} - COMMENT "Calculating image size" - VERBATIM) + + get_variable_filled(REGEX_SIZE "recipe.size.regex" ${BOARD_ID}) + get_variable_filled(REGEX_SIZE_DATA "recipe.size.regex.data" ${BOARD_ID}) + get_variable_filled(REGEX_SIZE_EEPROM "recipe.size.regex.eeprom" ${BOARD_ID}) + get_variable_filled(MAX_SIZE "upload.maximum_size" ${BOARD_ID}) + get_variable_filled(MAX_SIZE_DATA "upload.maximum_data_size" ${BOARD_ID}) + get_variable_filled(MAX_SIZE_FLASH "build.flash_size" ${BOARD_ID}) # Create ${TARGET_NAME}-size target add_custom_target(${TARGET_NAME}-size - COMMAND ${ARDUINO_SIZE_CMD} - ARGS ${ARDUINO_SIZE_FLAGS} - DEPENDS ${TARGET_NAME} - COMMENT "Calculating ${TARGET_NAME} image size") + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/Platform/size_script.py + "-c" "\"${ARDUINO_SIZE_CMD}\"" + "-p" "\"${ARDUINO_SIZE_FLAGS}\"" + "-r" "\"${REGEX_SIZE}\"" + "-rd" "\"${REGEX_SIZE_DATA}\"" + "-re" "\"${REGEX_SIZE_EEPROM}\"" + "-s" "\"${MAX_SIZE}\"" + "-sd" "\"${MAX_SIZE_DATA}\"" + "-sf" "\"${MAX_SIZE_FLASH}\"") + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/Platform/size_script.py + "-c" "${ARDUINO_SIZE_CMD}" + "-p" "${ARDUINO_SIZE_FLAGS}" + "-r" "${REGEX_SIZE}" + "-rd" "${REGEX_SIZE_DATA}" + "-re" "${REGEX_SIZE_EEPROM}" + "-s" "${MAX_SIZE}" + "-sd" "${MAX_SIZE_DATA}" + "-sf" "${MAX_SIZE_FLASH}" + COMMENT "Calculating image size" + VERBATIM) endfunction() @@ -1908,24 +1928,36 @@ function(GET_VARIABLE_FILLED VARIABLE_RETURN VARIABLE_NAME BOARD_ID) set(PLATFORM ${${BOARD_ID}.PLATFORM}) - set(PREFIXED_NAME_PLATFORM "${PLATFORM}.${VARIABLE_NAME}") - set(PREFIXED_NAME_BOARD "${BOARD_ID}.${VARIABLE_NAME}") - if (DEFINED ${PREFIXED_NAME_BOARD}) - set(SETTING_VALUE "${${PREFIXED_NAME_BOARD}}") - elseif(DEFINED ${PREFIXED_NAME_PLATFORM}) - set(SETTING_VALUE "${${PREFIXED_NAME_PLATFORM}}") - elseif(DEFINED ${VARIABLE_NAME}) - set(SETTING_VALUE "${${VARIABLE_NAME}}") - endif() + unset(VAR_VALUE) + unset(VAR_NAME) + + set(VARIABLES_TO_CHECK + "${BOARD_ID}${ARDUINO_CPUMENU}.${VARIABLE_NAME}.${runtime.os}" + "${BOARD_ID}${ARDUINO_CPUMENU}.${VARIABLE_NAME}" + "${BOARD_ID}.${VARIABLE_NAME}.${runtime.os}" + "${BOARD_ID}.${VARIABLE_NAME}" + "${PLATFORM}.${VARIABLE_NAME}.${runtime.os}" + "${PLATFORM}.${VARIABLE_NAME}" + "${VARIABLE_NAME}.${runtime.os}" + "${VARIABLE_NAME}" + ) - if (NOT DEFINED SETTING_VALUE) - MESSAGE(WARNING "Variable ${VARIABLE_NAME} is not set") - endif() + foreach(VAR_CHECK ${VARIABLES_TO_CHECK}) + if (DEFINED ${VAR_CHECK}) + set(VAR_VALUE "${${VAR_CHECK}}") + set(VAR_NAME "${VAR_CHECK}") + break() + endif() + endforeach() + #if (NOT DEFINED SETTING_VALUE) + # MESSAGE(WARNING "Variable ${VARIABLE_NAME} is not set") + #endif() - if (NOT SETTING_VALUE STREQUAL "") + + if (NOT VAR_VALUE STREQUAL "") set(VARIABLE_FILLED "") - get_variable_value_filled("VARIABLE_FILLED" "${SETTING_VALUE}" "${BOARD_ID}") + get_variable_value_filled("VARIABLE_FILLED" "${VAR_VALUE}" "${BOARD_ID}" "${VAR_NAME}") set(${VARIABLE_RETURN} ${VARIABLE_FILLED} PARENT_SCOPE) else() set(${VARIABLE_RETURN} ${SETTING_VALUE} PARENT_SCOPE) diff --git a/cmake/Platform/size_script.py b/cmake/Platform/size_script.py new file mode 100644 index 0000000..1ce3a37 --- /dev/null +++ b/cmake/Platform/size_script.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +from __future__ import print_function +import sys + +import argparse +import subprocess +import re + +print(sys.argv) + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + +parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter) + +parser.add_argument('-c', '--cmd', + type=str, + help='The command of the size script') + +parser.add_argument('-p', '--param', + type=str, + help='The parameters for the size script') + +parser.add_argument('-r', '--regex', + type=str, + default=None, + help='The value of recipe.size.regex') + +parser.add_argument('-rd', '--regex-data', + dest="regex_data", + type=str, + default=None, + help='The value of recipe.size.regex.data') + +parser.add_argument('-re', '--regex-eeprom', + dest="regex_eeprom", + type=str, + default=None, + help='The value of recipe.size.regex.eeprom') + +parser.add_argument('-s', '--max-size', + type=str, + dest="max_size", + default=None, + help='Maximum allowed upload size to the dram. See upload.maximum_size') + +parser.add_argument('-sd', '--max-size-data', + type=str, + dest="max_size_data", + default=None, + help='Maximum allowed data size to the dram. See upload.maximum_data_size') + +parser.add_argument('-sf', '--max-size-flash', + type=str, + dest="max_size_flash", + default=None, + help='Maximum allowed flash size. See build.flash_size') + +args = parser.parse_args() +m = re.search(r"^[\"'](.*)[\"']$", args.param) +if m: + args.param = m.group(1) +args.param = args.param.replace("\\","") +output = subprocess.check_output(args.cmd + " " + args.param, shell=True) + +#print("Output:\n" + output + "\n\n") + +#args.regex = args.regex.replace('\'','') +#args.regex_data = args.regex_data.replace('\'','') +#args.regex_eeprom = args.regex_eeprom.replace('\'','') + +size_complete = 0 +if args.regex and args.regex != "": + nums = re.findall(args.regex + "", output, re.MULTILINE) + if nums: + size_complete = sum(map(int, nums)) + else: + print(output) + exit(0) + +size_data = 0 +if args.regex_data and args.regex_data != "": + nums = re.findall(args.regex_data + "", output, re.MULTILINE) + if nums: + size_data = sum(map(int, nums)) + +size_eeprom = 0 +if args.regex_eeprom and args.regex_eeprom != "": + nums = re.findall(args.regex_eeprom + "", output, re.MULTILINE) + if nums: + size_eeprom = sum(map(int, nums)) + + +def human_readable_to_bytes(size): + """Given a human-readable byte string (e.g. 2G, 10GB, 30MB, 20KB), + return the number of bytes. Will return 0 if the argument has + unexpected form. + """ + if size == "": + return 0 + if (size[-1] == 'B'): + size = size[:-1] + if (size.isdigit()): + bytes = int(size) + else: + bytes = size[:-1] + unit = size[-1] + if (bytes.isdigit()): + bytes = int(bytes) + if (unit == 'G'): + bytes *= 1073741824 + elif (unit == 'M'): + bytes *= 1048576 + elif (unit == 'K'): + bytes *= 1024 + else: + bytes = 0 + else: + bytes = 0 + return bytes + +def sizeof_fmt(num, suffix='B'): + for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']: + if abs(num) < 1024.0: + return "%3.1f%s%s" % (num, unit, suffix) + num /= 1024.0 + return "%.1f%s%s" % (num, 'Yi', suffix) + +max_size = human_readable_to_bytes(args.max_size) +max_size_data = human_readable_to_bytes(args.max_size_data) +max_size_flash = human_readable_to_bytes(args.max_size_flash) + +totalSizeStr = "Firmware size: \t{} bytes".format(size_complete) +if max_size > 0: + totalSizeStr += " \t({:.1f}%)".format(size_complete/float(max_size)*100.0) + if size_complete/float(max_size) > 1: + eprint("\nWARNING: Firmware size may not fit!\n") +print(totalSizeStr) + +if size_data > 0: + dataSizeStr = "Data size: \t\t{} bytes".format(size_data) + if max_size_data > 0: + dataSizeStr += " \t({:.1f}%)".format(size_data/float(max_size_data)*100.0) + if size_data/float(max_size_data) > 1: + eprint("\nWARNING: Data size may not fit!\n") + print(dataSizeStr) + +if size_eeprom > 0: + eepromSizeStr = "EEPROM size: \t\t{} bytes".format(size_eeprom) + print(eepromSizeStr) \ No newline at end of file diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 961ef54..66b6504 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,3 +1,10 @@ +# ESP32 needs some special compilers. Set them here +SET(CMAKE_C_COMPILER "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin/avr-gcc") +SET(CMAKE_CXX_COMPILER "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin/avr-g++") +SET(CMAKE_AR "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin/avr-gcc-ar") +SET(CMAKE_RANLIB "${ARDUINO_SDK_PATH}/hardware/tools/avr/bin/avr-gcc-ranlib") + + # Set a variable for commands below set(PROJECT_NAME example) diff --git a/example_esp32/CMakeLists.txt b/example_esp32/CMakeLists.txt index 9e6c110..7dfac4a 100644 --- a/example_esp32/CMakeLists.txt +++ b/example_esp32/CMakeLists.txt @@ -1,3 +1,12 @@ +# ESP32 needs some special compilers. Set them here +SET(CMAKE_C_COMPILER "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc") +SET(CMAKE_C_COMPILER_WORKS 1) +SET(CMAKE_CXX_COMPILER "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-g++") +SET(CMAKE_CXX_COMPILER_WORKS 1) +SET(CMAKE_AR "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-ar") +SET(CMAKE_RANLIB "${ARDUINO_SDK_PATH}/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-ranlib") + + # Set a variable for commands below set(PROJECT_NAME example_esp32) From baa6bc26f36c2f47063f0cec5b3f0c7ba071c604 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Tue, 17 Apr 2018 13:03:19 +0200 Subject: [PATCH 28/29] Allow empty override path --- cmake/Platform/Arduino.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Platform/Arduino.cmake b/cmake/Platform/Arduino.cmake index 6abd041..478a34f 100644 --- a/cmake/Platform/Arduino.cmake +++ b/cmake/Platform/Arduino.cmake @@ -1163,7 +1163,7 @@ function(setup_arduino_library VAR_NAME BOARD_ID LIB_PATH COMPILE_FLAGS LINK_FLA RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}" ) - find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "" ${PATH_OVERRIDE}) + find_arduino_libraries(LIB_DEPS "${LIB_SRCS}" "" "${PATH_OVERRIDE}") foreach(LIB_DEP ${LIB_DEPS}) if(NOT DEP_LIB_SRCS STREQUAL TARGET_LIB_NAME AND DEP_LIB_SRCS) From 2f069184b029dbe5f91dd55e24b854ee79641510 Mon Sep 17 00:00:00 2001 From: Stefan Profanter Date: Tue, 17 Apr 2018 13:45:43 +0200 Subject: [PATCH 29/29] Allow setting ARDUINO_SDK_PATH as environment variable --- cmake/ArduinoToolchain.cmake | 4 ++++ cmake/Platform/size_script.py | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/ArduinoToolchain.cmake b/cmake/ArduinoToolchain.cmake index c531ba0..8fd0393 100644 --- a/cmake/ArduinoToolchain.cmake +++ b/cmake/ArduinoToolchain.cmake @@ -40,6 +40,10 @@ endif() #=============================================================================# # Detect Arduino SDK # #=============================================================================# +if(NOT DEFINED ARDUINO_SDK_PATH AND DEFINED ENV{ARDUINO_SDK_PATH}) + set(ARDUINO_SDK_PATH $ENV{ARDUINO_SDK_PATH}) +endif() + if(NOT ARDUINO_SDK_PATH) set(ARDUINO_PATHS) diff --git a/cmake/Platform/size_script.py b/cmake/Platform/size_script.py index 1ce3a37..31dc37d 100644 --- a/cmake/Platform/size_script.py +++ b/cmake/Platform/size_script.py @@ -9,7 +9,7 @@ import subprocess import re -print(sys.argv) +#print(sys.argv) def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) @@ -150,4 +150,4 @@ def sizeof_fmt(num, suffix='B'): if size_eeprom > 0: eepromSizeStr = "EEPROM size: \t\t{} bytes".format(size_eeprom) - print(eepromSizeStr) \ No newline at end of file + print(eepromSizeStr)