ARM Embedded Development: add_custom_target to generate custom 'deploy/program' steps without warnings/errors.
Greetings,
I'm currently setting up a CLion project for embedded ARM v4 development (NRF52832_XXAA from Nordic Semi).
Inside the CMakeLists.txt file I try to add custom build targets for the device which perform the following tasks:
- size (show size output of built output)
- createhex (convert output to Intel hex format)
- flash (program the microcontroller via the attached J-Link debugger/programmer
- flash_softdevice (programs the microcontroller with another prebuilt hex file)
I used the "add_custom_target" command of CMake. When loading the CMake Project the commands are parsed and the custom targets are created (Run -> Run... -> <CHOOSE TARGET>).
When I execute them the IDE always throws an error "Error: Executable is not specified" and the "Edit configuration" window pops up. Inside the "Edit configuration" window I am able to click "Run" even without specifying an executable. Then the "Configuration is still incorrect. Do you wand to edit it again? window comes up and if I then click "Continue Anyway" my target is successfully run.
Running the target works but to jump throuh several errors/warnings everytime I run my application is quite annoying. Is there a workaround?
I also already tried choosing my "main" application for the microcontroller as Executable. Then the Error "Cannot run program <path_to_my_built_file> (in directory <directory of my built file>): CreateProcess error=193, %1 is not a valid Win32 application.
Many thanks for your help!
My CmakeLists.txt:
cmake_minimum_required(VERSION 3.6)
project(Pavo C ASM)
SET (CMAKE_SYSTEM_NAME Generic) # (target is embedded -> Generic, see: https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling
#SET(CMAKE_VERBOSE_MAKEFILE ON) # show full build output
SET(CMAKE_C_COMPILER_FORCED TRUE) # force compiler to avoid failing compiler tests
SET(CMAKE_TOOLCHAIN_FILE pavo.cmake)
include(CMakeForceCompiler)
# set paths
SET(COMPILER_PATH "C:/Program Files (x86)/GNU Tools Arm Embedded/7 2018-q2-update")
set(NRF_SDK_ROOT "C:/modum/dev/repo/nrf52-sdk-15.3.0")
SET(SOFTDEVICE_PATH ${NRF_SDK_ROOT}/components/softdevice/s132/hex/s132_nrf52_6.1.1_softdevice.hex)
set (CC ${COMPILER_PATH}/bin/arm-none-eabi-gcc.exe)
set (CXX ${COMPILER_PATH}/bin/arm-none-eabi-g++.exe)
set (OBJCOPY ${COMPILER_PATH}/bin/arm-none-eabi-objcopy.exe)
set (SIZE ${COMPILER_PATH}/bin/arm-none-eabi-size.exe)
set(CMAKE_C_COMPILER ${CC})
set(CMAKE_CXX_COMPILER ${CXX})
set(CMAKE_ASM_COMPILER ${CC})
set(CMAKE_SYSTEM_NAME Generic)
# typically "CmakeLists.txt" should be in the same directory as "main.c", at this project it differs,
# therefore we modify "PROJECT_SOURCE_DIR". Please do not modify "CMAKE_SOURCE_DIR" as this could lead to errors.
set(PROJECT_SOURCE_DIR ..)
# NRF5x Configuration
set(NRF_FAMILY NRF52)
include(pavo.cmake)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_C_STANDARD 99)
set(SOURCE_FILES ${SRC_FILES})
include_directories(
./
${INC_FOLDERS})
message("CMAKE_C_FLAGS:\n")
message("${CMAKE_C_FLAGS}")
set(CMAKE_C_FLAGS ${__NRF52_C_FLAGS})
message("CMAKE_C_FLAGS:\n")
message("${CMAKE_C_FLAGS}")
set(CMAKE_ASM_FLAGS ${__NRF_ASM_FLAGS})
set(CMAKE_EXE_LINKER_FLAGS ${__NRF_LINKER_FLAGS})
add_executable(main ${SOURCE_FILES})
set_target_properties(
main
PROPERTIES
OUTPUT_NAME "build"
SUFFIX ".out"
)
#add_library(LIB_ECC STATIC ${NRF_SDK_ROOT}/external/micro-ecc/nrf52hf_armgcc/armgcc/micro_ecc_lib_nrf52.a)
#add_library(LIB_NFC STATIC ${NRF_SDK_ROOT}/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a)
#SET_TARGET_PROPERTIES(LIB_ECC PROPERTIES LINKER_LANGUAGE C)
#SET_TARGET_PROPERTIES(LIB_NFC PROPERTIES LINKER_LANGUAGE C)
#target_link_libraries(main LIB_ECC)
#target_link_libraries(main LIB_NFC)
add_library(LIB_ECC STATIC IMPORTED)
add_library(LIB_NFC STATIC IMPORTED)
SET_TARGET_PROPERTIES(LIB_ECC PROPERTIES IMPORTED_LOCATION ${NRF_SDK_ROOT}/external/micro-ecc/nrf52hf_armgcc/armgcc/micro_ecc_lib_nrf52.a)
SET_TARGET_PROPERTIES(LIB_NFC PROPERTIES IMPORTED_LOCATION ${NRF_SDK_ROOT}/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a)
SET_TARGET_PROPERTIES(LIB_ECC PROPERTIES LINKER_LANGUAGE C)
SET_TARGET_PROPERTIES(LIB_NFC PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(main LIB_ECC)
target_link_libraries(main LIB_NFC)
target_link_libraries(main m)
message("CMAKE_BINARY_DIR:\n")
message("${CMAKE_BINARY_DIR}")
add_custom_target(size
DEPENDS main
COMMAND ${SIZE} build.out
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target(createhex
DEPENDS size main
COMMAND ${OBJCOPY} -O ihex build.out build.hex
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target(flash
DEPENDS createhex size main
COMMAND nrfjprog --program build.hex -f ${__NRF_FAMILY} --sectorerase
COMMAND nrfjprog --reset -f ${__NRF_FAMILY}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target(flash_softdevice
COMMAND nrfjprog --eraseall -f ${__NRF_FAMILY}
COMMAND nrfjprog --program ${SOFTDEVICE_PATH} -f ${__NRF_FAMILY} --sectorerase
COMMAND nrfjprog --reset -f ${__NRF_FAMILY}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
Please sign in to leave a comment.
I forgot to write that chaining Run configurations is also impossible if it fails.
E.g. 'createhex' before 'flash'