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})
1 comment
Comment actions Permalink

I forgot to write that chaining Run configurations is also impossible if it fails.

E.g. 'createhex' before 'flash'

1

Please sign in to leave a comment.