diff --git a/.gitignore b/.gitignore index f82baaad13..4444ace738 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ lib*.so lib*.so.* *.a -build +build*/ .dep __pycache__ *.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt index 23597466c7..70daa80a4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,29 +4,75 @@ cmake_minimum_required(VERSION 2.8) -if(DEFINED CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Debug Release RelWithDebInfo MinSizeRel") -else() - set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug Release RelWithDebInfo MinSizeRel") -endif() +project(uavcan C CXX) -project(uavcan) +#============================================================================= +# build options +# +# options are listed in a table format below +set(opts + # name: type: default value: string options list : description + "CMAKE_BUILD_TYPE:STRING:RelWithDebInfo:Debug Release RelWithDebInfo MinSizeRel:Build type." + "CMAKE_CXX_FLAGS:STRING:::C++ flags." + "CMAKE_C_FLAGS:STRING:::C flags." + "UAVCAN_USE_CPP03:BOOL:OFF::Use cpp03 standard." + "UAVCAN_PLATFORM:STRING:generic:generic linux stm32:Platform." + ) +foreach(_opt ${opts}) + # arguments are : delimited + string(REPLACE ":" ";" _opt ${_opt}) + list(GET _opt 0 _name) + list(GET _opt 1 _type) + list(GET _opt 2 _default) + list(GET _opt 3 _options) + list(GET _opt 4 _descr) + # options are space delimited + string(REPLACE " " ";" _options "${_options}") + # if a default has not already been defined, use default from table + if(NOT DEFINED DEFAULT_${_name}) + set(DEFAULT_${_name} ${_default}) + endif() + # option has not been set already or it is empty, set it with the default + if(NOT DEFINED ${_name} OR ${_name} STREQUAL "") + set(${_name} ${DEFAULT_${_name}}) + endif() + # create a cache from the variable and force it to set + message(STATUS "${_name}\t: ${${_name}} : ${_descr}") + set("${_name}" "${${_name}}" CACHE "${_type}" "${_descr}" FORCE) + # if an options list is provided for the cache, set it + if("${_type}" STREQUAL "STRING" AND NOT "${_options}" STREQUAL "") + set_property(CACHE ${_name} PROPERTY STRINGS ${_options}) + endif() +endforeach() +#============================================================================= +# set flags +# +include_directories( + ./libuavcan/include/ + ./libuavcan/include/dsdlc_generated + ) + +#============================================================================= +# install # # DSDL definitions -# install(DIRECTORY dsdl DESTINATION share/uavcan) +#============================================================================= +# subdirectories # -# libuavcan -# +# library add_subdirectory(libuavcan) -# -# libuavcan drivers -# -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") +# drivers +add_subdirectory(libuavcan_drivers/posix) + +if (${UAVCAN_PLATFORM} STREQUAL "linux") message(STATUS "Adding Linux support library") - add_subdirectory(libuavcan_drivers/posix) add_subdirectory(libuavcan_drivers/linux) -endif () +elseif(${UAVCAN_PLATFORM} STREQUAL "stm32") + add_subdirectory(libuavcan_drivers/stm32/driver) +endif() + +# vim: set et ft=cmake fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : diff --git a/README.md b/README.md index d804371028..4bf26cbeea 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,15 @@ make -j8 sudo make install ``` +For cross-compiling the procedure is similar. + +```bash +mkdir build +cd build +cmake .. -D CMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-stm32-cortex-m4.cmake +make -j8 +``` + The following components will be installed into the system: * Libuavcan headers and the static library diff --git a/cmake/Toolchain-stm32-cortex-m4.cmake b/cmake/Toolchain-stm32-cortex-m4.cmake new file mode 100644 index 0000000000..403c50cd11 --- /dev/null +++ b/cmake/Toolchain-stm32-cortex-m4.cmake @@ -0,0 +1,173 @@ +# defines: +# +# NM +# OBJCOPY +# LD +# CXX_COMPILER +# C_COMPILER +# CMAKE_SYSTEM_NAME +# CMAKE_SYSTEM_VERSION +# GENROMFS +# LINKER_FLAGS +# CMAKE_EXE_LINKER_FLAGS +# CMAKE_FIND_ROOT_PATH +# CMAKE_FIND_ROOT_PATH_MODE_PROGRAM +# CMAKE_FIND_ROOT_PATH_MODE_LIBRARY +# CMAKE_FIND_ROOT_PATH_MODE_INCLUDE + +include(CMakeForceCompiler) + +# this one is important +set(CMAKE_SYSTEM_NAME Generic) + +#this one not so much +set(CMAKE_SYSTEM_VERSION 1) + +# specify the cross compiler +find_program(C_COMPILER arm-none-eabi-gcc) +if(NOT C_COMPILER) + message(FATAL_ERROR "could not find arm-none-eabi-gcc compiler") +endif() +cmake_force_c_compiler(${C_COMPILER} GNU) + +find_program(CXX_COMPILER arm-none-eabi-g++) +if(NOT CXX_COMPILER) + message(FATAL_ERROR "could not find arm-none-eabi-g++ compiler") +endif() +cmake_force_cxx_compiler(${CXX_COMPILER} GNU) + +set(LINKER_FLAGS "-Wl,-gc-sections") +set(CMAKE_EXE_LINKER_FLAGS ${LINKER_FLAGS}) + +# where is the target environment +set(CMAKE_FIND_ROOT_PATH get_file_component(${C_COMPILER} PATH)) + +# search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(warnings + -Wall + -Wno-sign-compare + -Wextra + #-Wshadow # very verbose due to eigen + -Wfloat-equal + -Wpointer-arith + -Wmissing-declarations + -Wpacked + -Wno-unused-parameter + -Werror=format-security + -Werror=array-bounds + -Wfatal-errors + -Werror=unused-variable + -Werror=reorder + -Werror=uninitialized + -Werror=init-self + #-Wcast-qual - generates spurious noreturn attribute warnings, + # try again later + #-Wconversion - would be nice, but too many "risky-but-safe" + # conversions in the code + #-Wcast-align - would help catch bad casts in some cases, + # but generates too many false positives + ) + +set(max_optimization -Os) + +set(optimization_flags + -fno-strict-aliasing + -fomit-frame-pointer + -funsafe-math-optimizations + -ffunction-sections + -fdata-sections + ) + +set(c_warnings + -Wbad-function-cast + -Wstrict-prototypes + -Wmissing-prototypes + -Wnested-externs + ) + +set(c_compile_flags + -g + -fno-common + -nodefaultlibs + -nostdlib + -DCONFIG_WCHAR_BUILTIN + ) + +set(cxx_warnings + -Wno-missing-field-initializers + ) +set(cxx_compile_flags + -g + -fno-exceptions + -fno-rtti + -fno-threadsafe-statics + -DCONFIG_WCHAR_BUILTIN + -nodefaultlibs + -nostdlib + ) + +set(cpu_flags + -mcpu=cortex-m4 + -mthumb + -march=armv7e-m + -mfpu=fpv4-sp-d16 + -mfloat-abi=hard + ) + +find_path(NUTTX_EXPORT_DIR libs/libnuttx.a + PATHS + $ENV{HOME}/git/px4/Firmware/build_px4fmu-v2_default/px4fmu-v2/NuttX/nuttx-export + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) +if(NOT NUTTX_EXPORT_DIR) + message(FATAL_ERROR "failed to find NUTTX_EXPORT_DIR, please set") +else() + message(STATUS "nuttx export: ${NUTTX_EXPORT_DIR}") +endif() + +set(uavcan_extra_flags + -DUAVCAN_NO_ASSERTIONS + -DUAVCAN_STM32_NUM_IFACES=2 + -DUAVCAN_USE_EXTERNAL_SNPRINT + -DUAVCAN_MEM_POOL_BLOCK_SIZE=48 + -DUAVCAN_MAX_NETWORK_SIZE_HINT=16 + -DUAVCAN_STM32_TIMER_NUMBER=5 + -DUAVCAN_STM32_NUTTX=1 + -DUAVCAN_CPP_VERSION=UAVCAN_CPP03 + -I${NUTTX_EXPORT_DIR}/include + -I${NUTTX_EXPORT_DIR}/include/cxx + -I${NUTTX_EXPORT_DIR}/arch/chip + -I${NUTTX_EXPORT_DIR}/arch/common + ) + +set(added_c_flags + ${cpu_flags} + ${c_compile_flags} + ${warnings} + ${c_warnings} + ${max_optimization} + ${optimization_flags} + ${uavcan_extra_flags} + ) + +set(added_cxx_flags + ${cpu_flags} + ${cxx_compile_flags} + ${warnings} + ${cxx_warnings} + ${max_optimization} + ${optimization_flags} + ${uavcan_extra_flags} + ) + +string (REPLACE ";" " " DEFAULT_CMAKE_CXX_FLAGS "${added_cxx_flags}") +string (REPLACE ";" " " DEFAULT_CMAKE_C_FLAGS "${added_c_flags}") +set(DEFAULT_CMAKE_BUILD_TYPE "RelWithDebInfo") +set(DEFAULT_UAVCAN_PLATFORM "stm32") +set(DEFAULT_UAVCAN_USE_CPP03 ON) diff --git a/libuavcan/CMakeLists.txt b/libuavcan/CMakeLists.txt index 5058e65b55..0298b4b7ea 100644 --- a/libuavcan/CMakeLists.txt +++ b/libuavcan/CMakeLists.txt @@ -43,7 +43,7 @@ include_directories(${DSDLC_OUTPUT}) # if (COMPILER_IS_GCC_COMPATIBLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef") - if (USE_CPP03) + if (UAVCAN_USE_CPP03) message(STATUS "Using C++03") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03 -Wno-variadic-macros -Wno-long-long") else () @@ -128,3 +128,5 @@ if (DEBUG_BUILD) else () message(STATUS "Release build type: " ${CMAKE_BUILD_TYPE}) endif () + +# vim: set et ft=cmake fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : diff --git a/libuavcan_drivers/stm32/driver/CMakeLists.txt b/libuavcan_drivers/stm32/driver/CMakeLists.txt new file mode 100644 index 0000000000..b89746c34b --- /dev/null +++ b/libuavcan_drivers/stm32/driver/CMakeLists.txt @@ -0,0 +1,18 @@ +include_directories( + ./src + ./include + ) + +add_library(uavcan_stm32_driver STATIC + ./src/uc_stm32_can.cpp + ./src/uc_stm32_clock.cpp + ./src/uc_stm32_thread.cpp + ) + +add_dependencies(uavcan_stm32_driver uavcan) + +install(DIRECTORY include/uavcan_stm32 DESTINATION include) +install(TARGETS uavcan_stm32_driver DESTINATION lib) + +# vim: set et ft=cmake fenc=utf-8 ff=unix sts=4 sw=4 ts=4 :) +