diff --git a/CMakeLists.txt b/CMakeLists.txt index 95cb91398a..918e5bd875 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,10 +277,12 @@ foreach(module ${config_module_list}) endforeach() add_subdirectory(src/firmware/${OS}) + if (config_io_board) add_subdirectory(src/modules/px4iofirmware) endif() + #============================================================================= # generate git version # diff --git a/Makefile b/Makefile index db133aea51..5041ff4c51 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,7 @@ clean: rm -rf build_*/ # targets handled by cmake -cmake_targets = test upload package package_source debug check_weak +cmake_targets = test upload package package_source debug debug_io check_weak $(foreach targ,$(cmake_targets),$(eval $(call cmake-targ,$(targ)))) .PHONY: clean diff --git a/cmake/common/px4_base.cmake b/cmake/common/px4_base.cmake index 022261a58d..54ab915bfd 100644 --- a/cmake/common/px4_base.cmake +++ b/cmake/common/px4_base.cmake @@ -551,7 +551,7 @@ function(px4_add_common_flags) endif() set(c_compile_flags - -g3 + -g -std=gnu99 -fno-common ) @@ -560,7 +560,7 @@ function(px4_add_common_flags) -Wno-missing-field-initializers ) set(cxx_compile_flags - -g3 + -g -fno-exceptions -fno-rtti -std=gnu++0x @@ -735,4 +735,54 @@ function(px4_generate_parameters) set(${OUT} ${generated_files} PARENT_SCOPE) endfunction() +#============================================================================= +# +# px4_copy_tracked +# +# Copy files to a directory and keep track of dependencies. +# +# Usage: +# px4_copy_tracked(OUT FILES DIR ) +# +# Input: +# FILES : the source files +# DEST : the directory to copy files to +# RELATIVE : relative directory for source files +# +# Output: +# OUT : the copied files +# +# Example: +# px4_copy_tracked(OUT copied_files FILES src_files DEST path RELATIVE path_rel) +# +function(px4_copy_tracked) + px4_parse_function_args( + NAME px4_copy_tracked + ONE_VALUE DEST OUT RELATIVE + MULTI_VALUE FILES + REQUIRED DEST OUT FILES + ARGN ${ARGN}) + set(files) + # before build, make sure dest directory exists + execute_process( + COMMAND cmake -E make_directory ${DEST}) + # create rule to copy each file and set dependency as source file + set(_files_out) + foreach(_file ${FILES}) + if (RELATIVE) + file(RELATIVE_PATH _file_path ${RELATIVE} ${_file}) + else() + set(_file_path ${_file}) + endif() + set(_dest_file ${DEST}/${_file_path}) + #message(STATUS "copy ${_file} -> ${_dest_file}") + add_custom_command(OUTPUT ${_dest_file} + COMMAND cmake -E copy ${_file} ${_dest_file} + DEPENDS ${_file}) + list(APPEND _files_out ${_dest_file}) + endforeach() + set(${OUT} ${_files_out} PARENT_SCOPE) +endfunction() + + # vim: set noet fenc=utf-8 ff=unix nowrap: diff --git a/cmake/nuttx/px4_impl_nuttx.cmake b/cmake/nuttx/px4_impl_nuttx.cmake index 8b82ed1704..7533e139f1 100644 --- a/cmake/nuttx/px4_impl_nuttx.cmake +++ b/cmake/nuttx/px4_impl_nuttx.cmake @@ -40,7 +40,7 @@ # * px4_nuttx_add_firmware # * px4_nuttx_generate_builtin_commands # * px4_nuttx_add_export -# * px4_nuttx_generate_romfs +# * px4_nuttx_add_romfs # # Required OS Inteface Functions # @@ -260,61 +260,106 @@ endfunction() #============================================================================= # -# px4_nuttx_generate_romfs +# px4_nuttx_create_bin # -# The functions generates the ROMFS filesystem for nuttx. +# The functions generates a bin image for nuttx. # # Usage: -# px4_nuttx_generate_romfs(OUT ROOT ) +# px4_nuttx_create_bin(BIN EXE ) +# +# Input: +# EXE : the exe file +# +# Output: +# OUT : the binary output file +# +# Example: +# px4_nuttx_create_bin(OUT my_exe.bin EXE my_exe) +# +function(px4_nuttx_create_bin) + + px4_parse_function_args( + NAME px4_nuttx_create_bin + ONE_VALUE EXE OUT + REQUIRED EXE OUT + ARGN ${ARGN}) + + add_custom_command(OUTPUT ${OUT} + COMMAND ${OBJCOPY} -O binary ${EXE} ${EXE}.bin + DEPENDS ${EXE}) + + set(${OUT} ${${OUT}} PARENT_SCOPE) + +endfunction() + + +#============================================================================= +# +# px4_nuttx_add_romfs +# +# The functions creates a ROMFS filesystem for nuttx. +# +# Usage: +# px4_nuttx_add_romfs( +# OUT +# ROOT +# EXTRAS ) # # Input: # ROOT : the root of the ROMFS +# EXTRAS : list of extra files # # Output: -# OUT : the generated ROMFS +# OUT : the ROMFS library target # # Example: -# px4_nuttx_generate_romfs(OUT my_romfs ROOT "ROMFS/my_board") +# px4_nuttx_add_romfs(OUT my_romfs ROOT "ROMFS/my_board") # -function(px4_nuttx_generate_romfs) +function(px4_nuttx_add_romfs) px4_parse_function_args( - NAME px4_nuttx_generate_romfs + NAME px4_nuttx_add_romfs ONE_VALUE OUT ROOT + MULTI_VALUE EXTRAS REQUIRED OUT ROOT ARGN ${ARGN}) - file(GLOB_RECURSE romfs_files ${ROOT}/*) - set(romfs_temp_dir ${CMAKE_BINARY_DIR}/${ROOT}) + set(romfs_temp_dir ${CMAKE_BINARY_DIR}/tmp/${ROOT}) set(romfs_src_dir ${CMAKE_SOURCE_DIR}/${ROOT}) - set(romfs_autostart ${CMAKE_SOURCE_DIR}/Tools/px_process_airframes.py) set(romfs_pruner ${CMAKE_SOURCE_DIR}/Tools/px_romfs_pruner.py) set(bin_to_obj ${CMAKE_SOURCE_DIR}/cmake/nuttx/bin_to_obj.py) + set(extras_dir ${CMAKE_CURRENT_BINARY_DIR}/extras) - #message(STATUS "temp_dir: ${romfs_temp_dir}") - #message(STATUS "src_dir: ${romfs_src_dir}") + file(GLOB_RECURSE romfs_src_files ${romfs_src_dir} ${romfs_src_dir}/*) - add_custom_command(OUTPUT rc.autostart - COMMAND ${PYTHON_EXECUTABLE} ${romfs_autostart} - -a ${romfs_src_dir}/init.d - -s rc.autostart - ) + set(cmake_test ${CMAKE_SOURCE_DIR}/cmake/test/cmake_tester.py) - add_custom_command(OUTPUT romfs.bin + + set(extras) + foreach(extra ${EXTRAS}) + get_filename_component(file_name ${extra} NAME) + set(file_dest ${extras_dir}/${file_name}) + add_custom_command(OUTPUT ${file_dest} + COMMAND cmake -E copy ${extra} ${file_dest} + DEPENDS ${extra} + ) + list(APPEND extras ${file_dest}) + endforeach() + add_custom_target(collect_extras DEPENDS ${extras}) + + add_custom_command(OUTPUT romfs.o COMMAND cmake -E remove_directory ${romfs_temp_dir} COMMAND cmake -E copy_directory ${romfs_src_dir} ${romfs_temp_dir} - COMMAND cmake -E copy rc.autostart ${romfs_temp_dir}/init.d - #TODO add romfs cleanup of temp file .~, .swp etc + COMMAND cmake -E copy_directory ${extras_dir} ${romfs_temp_dir}/extras + COMMAND ${PYTHON_EXECUTABLE} ${romfs_autostart} + -a ${romfs_temp_dir}/init.d + -s ${romfs_temp_dir}/init.d/rc.autostart COMMAND ${PYTHON_EXECUTABLE} ${romfs_pruner} --folder ${romfs_temp_dir} COMMAND ${GENROMFS} -f ${CMAKE_CURRENT_BINARY_DIR}/romfs.bin -d ${romfs_temp_dir} -V "NSHInitVol" - DEPENDS ${romfs_files} rc.autostart - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - - add_custom_command(OUTPUT romfs.o + #COMMAND cmake -E remove_directory ${romfs_temp_dir} COMMAND ${PYTHON_EXECUTABLE} ${bin_to_obj} --ld ${LD} --c_flags ${CMAKE_C_FLAGS} --c_compiler ${CMAKE_C_COMPILER} @@ -322,11 +367,12 @@ function(px4_nuttx_generate_romfs) --obj romfs.o --var romfs_img --bin romfs.bin - DEPENDS romfs.bin + DEPENDS ${romfs_src_files} ${extras} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - - set(${OUT} romfs.o PARENT_SCOPE) + add_library(${OUT} STATIC romfs.o) + set_target_properties(${OUT} PROPERTIES LINKER_LANGUAGE C) + set(${OUT} ${${OUT}} PARENT_SCOPE) endfunction() diff --git a/cmake/test/cmake_tester.py b/cmake/test/cmake_tester.py new file mode 100755 index 0000000000..34bebacb9d --- /dev/null +++ b/cmake/test/cmake_tester.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +""" +The module facilitates testing in cmake. +It takes a command and a regex for failure ok passing. +It passes if: + * No stderr output. + * Stdout doesn't match failure regex. + * Stdout matches ok regex if given. +""" +from __future__ import print_function +import argparse +import subprocess +import re +import sys + +#pylint: disable=invalid-name + +parser = argparse.ArgumentParser() + +parser.add_argument('cmd') +parser.add_argument('--re-fail') +parser.add_argument('--re-ok') +parser.add_argument('--verbose', '-v', dest='verbose', action='store_true') + +parser.set_defaults(verbose=False) +args = parser.parse_args() + +proc = subprocess.Popen(args.cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) +stdout, stderr = proc.communicate() + +if stderr != "": + print(stderr) + sys.exit(1) + +if args.re_fail is not None: + fail_match = re.search(args.re_fail, stdout) + if fail_match is not None: + print(stdout) + sys.exit(1) + +if args.re_ok is not None: + ok_match = re.search(args.re_ok, stdout) + if re.match(args.re_ok, stdout) is None: + print(stdout) + sys.exit(1) + +if args.verbose: + print(stdout) + +sys.exit(0) + +# vim: set et ft=python fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : diff --git a/cmake/toolchains/Toolchain-arm-none-eabi.cmake b/cmake/toolchains/Toolchain-arm-none-eabi.cmake index 80da3ad1a2..45da0d965c 100644 --- a/cmake/toolchains/Toolchain-arm-none-eabi.cmake +++ b/cmake/toolchains/Toolchain-arm-none-eabi.cmake @@ -37,7 +37,7 @@ endif() cmake_force_cxx_compiler(${CXX_COMPILER} GNU) # compiler tools -foreach(tool objcopy nm ld gdb) +foreach(tool objcopy nm ld) string(TOUPPER ${tool} TOOL) find_program(${TOOL} arm-none-eabi-${tool}) if(NOT ${TOOL}) @@ -45,6 +45,12 @@ foreach(tool objcopy nm ld gdb) endif() endforeach() +# optional compiler tools +foreach(tool gdb gdbtui) + string(TOUPPER ${tool} TOOL) + find_program(${TOOL} arm-none-eabi-${tool}) +endforeach() + # os tools foreach(tool echo patch grep rm mkdir nm genromfs cp touch make unzip) string(TOUPPER ${tool} TOOL) diff --git a/src/firmware/nuttx/CMakeLists.txt b/src/firmware/nuttx/CMakeLists.txt index bb9aac3113..bf50a33814 100644 --- a/src/firmware/nuttx/CMakeLists.txt +++ b/src/firmware/nuttx/CMakeLists.txt @@ -5,17 +5,22 @@ px4_nuttx_generate_builtin_commands( ${config_extra_builtin_cmds} ) -px4_nuttx_generate_romfs(OUT romfs.o - ROOT ROMFS/px4fmu_common) +px4_nuttx_add_romfs(OUT romfs + ROOT ROMFS/px4fmu_common + EXTRAS ${CMAKE_BINARY_DIR}/src/modules/px4iofirmware/${config_io_board}_${LABEL}.bin + ) + +add_dependencies(romfs fw_io) # add executable add_executable(firmware_nuttx - builtin_commands.c - romfs.o) + builtin_commands.c) + + set(nuttx_export_dir ${CMAKE_BINARY_DIR}/${BOARD}/NuttX/nuttx-export) set(link_libs - apps nuttx m gcc + romfs apps nuttx m gcc ) if(NOT ${BOARD} STREQUAL "sim") @@ -56,7 +61,14 @@ if(NOT ${BOARD} STREQUAL "sim") configure_file(gdbinit.in .gdbinit) add_custom_target(debug - COMMAND ${GDB} ${CMAKE_CURRENT_BINARY_DIR}/firmware_nuttx + COMMAND ${GDBTUI} ${CMAKE_CURRENT_BINARY_DIR}/firmware_nuttx + DEPENDS firmware_nuttx + ${CMAKE_CURRENT_BINARY_DIR}/.gdbinit + ) + + add_custom_target(debug_io + COMMAND ${GDBTUI} + ${CMAKE_BINARY_DIR}/src/modules/px4iofirmware/${config_io_board}_${LABEL} DEPENDS firmware_nuttx ${CMAKE_CURRENT_BINARY_DIR}/.gdbinit ) diff --git a/src/modules/px4iofirmware/CMakeLists.txt b/src/modules/px4iofirmware/CMakeLists.txt index d5183bb04e..43c59fb2db 100644 --- a/src/modules/px4iofirmware/CMakeLists.txt +++ b/src/modules/px4iofirmware/CMakeLists.txt @@ -103,10 +103,12 @@ elseif(${config_io_board} STREQUAL "px4io-v2") ) endif() -add_executable(firmware_io_nuttx +set(fw_io_name ${config_io_board}_${LABEL}) + +add_executable(${fw_io_name} ${srcs}) -add_dependencies(firmware_io_nuttx +add_dependencies(${fw_io_name} nuttx_export_${config_io_board} msg_gen io_prebuild_targets @@ -119,20 +121,20 @@ set(main_link_flags "-Wl,-Map=${CMAKE_BINARY_DIR}/${config_io_board}/main.map" ) px4_join(OUT main_link_flags LIST ${main_link_flags} GLUE " ") -set_target_properties(firmware_io_nuttx PROPERTIES LINK_FLAGS ${main_link_flags}) +set_target_properties(${fw_io_name} PROPERTIES LINK_FLAGS ${main_link_flags}) -set(io_fw_file ${CMAKE_CURRENT_BINARY_DIR}/${config_io_board}.px4) - -target_link_libraries(firmware_io_nuttx +target_link_libraries(${fw_io_name} -Wl,--start-group apps nuttx nosys m gcc ${config_io_extra_libs} -Wl,--end-group) -px4_nuttx_add_firmware(OUT ${io_fw_file} - BOARD ${config_io_board} - EXE ${CMAKE_CURRENT_BINARY_DIR}/firmware_io_nuttx - ${config_firmware_options} +px4_nuttx_create_bin(OUT ${CMAKE_CURRENT_BINARY_DIR}/${fw_io_name}.bin + EXE ${fw_io_name} ) +add_custom_target(fw_io + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${fw_io_name}.bin) + + # vim: set noet ft=cmake fenc=utf-8 ff=unix :