Giter Site home page Giter Site logo

nrf5-cmake-scripts's Introduction

nRF5-cmake-scripts

CMake scripts for developing projects with Nordic Semiconductor nRF5 series SoCs, utilising the CMake scripts found in the Nordic nRF5 Mesh SDK.

This project originally forked from cmake-nRF5x which is a self-contained nRF5 CMake solution. As this project takes a different approach (using Nordic Mesh SDK) it was set up as a new project.

Currently supports:

  • nRF5 SDK v17.1.0
  • nRF5 Mesh SDK v5.0.0

Dependencies

The script makes use of the following dependencies which are downloaded by the script:

  • nRF5 SDK by Nordic Semiconductor - SoC specific drivers and libraries (also includes a lot of examples)
  • nRF5 mesh SDK by Nordic Semiconductor - A mesh SDK which uses CMake, and is used for its CMake configuration

The script depends on the following external dependencies:

  • JLink by Segger - interface software for the JLink familiy of programmers
  • Nordic command line tools (nrfjprog and mergehex) by Nordic Semiconductor - Wrapper utility around JLink
  • Python
  • Nordic nrfutil by Nordic Semiconductor - a utility for generating DFU packages. Install with pip install nrfutil.
  • ARM GNU Toolchain by ARM and the GCC Team - compiler toolchain for embedded (= bare metal) ARM chips. On Windows, download directly. On a Mac, can be installed with homebrew:
    brew tap ArmMbed/homebrew-formulae
    brew install arm-none-eabi-gcc

Setup

The script depends on the nRF5 SDK and the nRF5 mesh SDK. It can download these dependencies for you.

After setting up your CMakeLists.txt as described below, or using the example project, to download the dependencies run:

cmake -Bcmake-build-download -G "Unix Makefiles"
cmake --build cmake-build-download/ --target download
cmake -Bcmake-build-debug --toolchain nRF5-cmake-scripts/nRF5-cmake-toolchain.cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug

This will download the dependencies and then generate the build files using the toolchain.

Creating your own project

Note: You can also follow the tutorial on the NRB Tech blog.

  1. Download this repo (or add as submodule) to the directory nRF5-cmake-scripts in your project

  2. It is recommended that you copy the example CMakeLists.txt and src/CMakeLists.txt into your project, but you can inspect these and change the structure or copy as you need

  3. Search the SDK example directory for a sdk_config.h, main.c and a linker script (normally named <project_name>_gcc_<chip familly>.ld) that fits your chip and project needs

  4. Copy the sdk_config.h and the project main.c into a new directory src. Modify them as required for your project

  5. Copy the linker script from the example's armgcc directory into your project

  6. Adjust the example CMakeList.txt files for your requirements, and to point at your source files

    Note: By default, C and assembly languages are enabled. You can add C++ with enable_language(C ASM)

  7. Optionally add additional libraries:

    Many drivers and libraries are wrapped with macros to include them in your project, see includes/libraries.cmake. If you need one isn't implemented, please create an issue or pull request.

    To include BLE services, use nRF5_addBLEService(<service name>).

Build

After setup you can use cmake as usual:

  1. Generate the build files:

    cmake -Bcmake-build-debug --toolchain nRF5-cmake-scripts/nRF5-cmake-toolchain.cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
  2. Build your app:

    cmake --build cmake-build-debug --target <your target name>

There are also other targets available:

  • merge_<your target name>: Builds the application and merges the SoftDevice
  • secure_bootloader_<your target name>: Builds the secure bootloader for this target
  • uECC: Builds the uECC library
  • bl_merge_<your target name>: Builds your application and the secure bootloader, merges these and the softdevice
  • pkg_<your target name>: Builds and packages your application for DFU
  • pkg_bl_sd_<your target name>: Builds and packages your application, the SoftDevice, and bootloader for DFU.

Enabling C++

Immediately after the call to nRF5_setup() in your root CMakeLists.txt, add the line:

enable_language(CXX)

SEGGER RTT logging in bootloader and app

By default, SEGGER RTT will be init in the bootloader, and then re-init in the app at a different memory location. The RTT client reads memory directly from RAM, so will only pick up on the App's RTT memory. To make RTT work across bootloader and app you need to only init in the bootloader and ensure the App continues to use the same RAM location for RTT.

To do this, create a new header rtt_config.h, add:

#define SEGGER_RTT_SECTION ".rtt"

and also copy in all the SEGGER_RTT_CONFIG_... defines from sdk_config.h/app_config.h. Include this file in your sdk_config.h/app_config.h and the bootloader sdk_config.h/app_config.h.

In the nRF52 SDK, modules/nrfx/mdk/nrf_common.ld, add the following before .data : AT (__etext):

.rtt:
{
} > RAM

This symbol must be removed from the hex file, to do this ensure ".rtt" is in the list of symbols to remove from hex passed to nRF5_addExecutable (see example project).

Ensure the RAM start and size are aligned in the app and bootloader linker scripts.

In the nRF52 SDK, external/segger_rtt/SEGGER_RTT.c, change the SEGGER_RTT_Init function to:

void SEGGER_RTT_Init (void) {
    INIT();
}

This ensures that RTT is not re-init in the App if already init in the bootloader.

Ensure all the SEGGER files are compiled in your bootloader โ€“ refer to the _debug makefiles to see what is required.

Ensure the bootloader sdk_config.h/app_config.h is configured to use RTT.

You should then see continuous RTT output from the bootloader and App.

Flash

In addition to the build targets the script adds some support targets:

  • FLASH_SOFTDEVICE: Flashes the nRF softdevice to the SoC (typically done only once for each SoC if not using DFU flash target)
  • flash_<your target name>: Builds and flashes your application
  • flash_bl_merge_<your target name>: Builds the bootloader and application, and flashes both and the softdevice
  • FLASH_ERASE: Erases the SoC flash

JLink Applications

To start the gdb server and RTT terminal, build the target START_JLINK_ALL:

cmake --build "cmake-build" --target START_JLINK_ALL

There are also the targets START_JLINK_RTT and START_JLINK_GDBSERVER to start these independently.

License

MIT.

Please note that the nRF5 SDK and mesh SDK by Nordic Semiconductor are covered by their own licenses and shouldn't be re-distributed.

nrf5-cmake-scripts's People

Contributors

guillaumejchauveau avatar nrbrook avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nrf5-cmake-scripts's Issues

JLink targets for Ubuntu 18.04 and gnome-terminal version 3.28.2

I am using the template project in order to build for Nordic 52840 chip in CLion on Ubuntu 18.04. My version of gnome-terminal is 3.28.2 and the following commands doesn't work:

COMMAND ${TERMINAL} "${nRF5_CMAKE_PATH}/runJLink...${COMMAND_SUFFIX}" ${POST_OPTIONS}

This is due to updated syntax as far as I understand, see this.

That means that following change would work:

COMMAND ${TERMINAL} -- "${nRF5_CMAKE_PATH}/runJLink...${COMMAND_SUFFIX}" ${POST_OPTIONS}

I have updated nRF5-cmake-scripts locally in another branch by adding "COMMAND_PREFIX" variable that would contain "--" for unix distros:

if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
        set(TERMINAL "open")
        set(COMMAND_PREFIX "")
        set(COMMAND_SUFFIX "")
    elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
        find_program(CMD cmd)
        set(TERMINAL ${CMD} /c start powershell -noexit -ExecutionPolicy Bypass -File)
        set(POST_OPTIONS -JLinkPath ${JLINK} -JLinkGDBServerPath ${JLINKGDBSERVER} -JLinkRTTClientPath ${JLINKRTTCLIENT})
        set(COMMAND_PREFIX "")
        set(COMMAND_SUFFIX ".ps1")
    else()
        set(TERMINAL "gnome-terminal")
        set(COMMAND_PREFIX "--")
        set(COMMAND_SUFFIX "")
    endif()

    if(EXISTS "${JLINK}")
        if(EXISTS "${JLINKGDBSERVER}" AND EXISTS "${JLINKRTTCLIENT}")
            add_custom_target(START_JLINK_ALL ALL
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkGDBServer${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkExe${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMAND cmake -E sleep 2
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkRTTClient${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMENT "started JLink commands"
                    VERBATIM
                    )
        endif()
        if(EXISTS "${JLINKRTTCLIENT}")
            add_custom_target(START_JLINK_RTT ALL
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkExe${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMAND cmake -E sleep 2
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkRTTClient${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMENT "started JLink RTT terminal"
                    VERBATIM
                    )
        else()
            message(WARNING "The path to the JLinkRTTClient utility (JLINKRTTCLIENT) is not set or does not exist, so START_JLINK_RTT and START_JLINK_ALL targets will not be available")
        endif()
        if(EXISTS "${JLINKGDBSERVER}")
            add_custom_target(START_JLINK_GDBSERVER ALL
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkExe${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMAND cmake -E sleep 2
                    COMMAND ${TERMINAL} ${COMMAND_PREFIX} "${nRF5_CMAKE_PATH}/runJLinkGDBServer${COMMAND_SUFFIX}" ${POST_OPTIONS}
                    COMMENT "started JLink GDB server"
                    VERBATIM
                    )
        else()
            message(WARNING "The path to the JLinkGDBServer utility (JLINKGDBSERVER) is not set or does not exist, so START_JLINK_GDBSERVER and START_JLINK_ALL targets will not be available")
        endif()
    else()
        message(WARNING "The path to the JLink utility (JLINK) is not set or does not exist, so START_JLINK_* targets will not be available")
    endif()

But I suppose that this probably needs another thought on how to keep it backward compatible?

mergehex is used with more than 3 files

mergehex utility is used with 4 files when nRF5_addBootloaderSoftDeviceAppMergeTarget is invoked, should be done sequentially instead. The command in nRF5-cmake.cmake that causes the problem:

COMMAND ${MERGEHEX} -m ${BOOTLOADER_HEX} "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE_NAME}_bootloader_setting.hex" "${${SOFTDEVICE}_HEX_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE_NAME}.hex" -o "${OP_FILE}

I suggest the following replacement:

COMMAND ${MERGEHEX} -m ${BOOTLOADER_HEX} "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE_NAME}_bootloader_setting.hex" "${${SOFTDEVICE}_HEX_FILE}" -o "${OP_FILE}"
COMMAND ${MERGEHEX} -m "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE_NAME}.hex" "${OP_FILE}" -o "${OP_FILE}"

Add ability to include multiple AES ciphers

I use backend mbedtls w/ nRF5 SDK. I want to include files so both AES256CCM as well as AES256ECB gets compiled. AES 256 CCM cipher is in mbedtls_backend_aes_aead.c and AES 256 ECB cipher is in mbedtls_backend_aes.c. My suspicion is that they the if-statement used here is broken up because of the additional "_" in case of the aead.

Would the best way be to change:

macro(nRF5_addCryptoBackend TYPE BACKEND)

to something like:

macro(nRF5_addCryptoBackend TYPE BACKEND USE_AEAD)

Is there any harm in calling setup macro twice?

nRF5_addCryptoBackend("aes" "mbedtls")
nRF5_addCryptoBackend("aead" "mbedtls")

If not, no change may be needed. If there is an issue, I can create a PR with the change when I finished setting up my project because I'll have to get it working anyways.

FLASH still overflowed with .data and user data after modify modules/nrfx/mdk/nrf_common.ld

diff --git a/example/toolchains/nRF5/nRF5_SDK_17.1.0_ddde560/examples/dfu/secure_bootloader/pca10040_s132_ble/config/sdk_config.h b/example/toolchains/nRF5/nRF5_SDK_17.1.0_ddde560/examples/dfu/secure_bootloader/pca10040_s132_ble/config/sdk_config.h
index b00ff5e..88b54bf 100644
--- a/example/toolchains/nRF5/nRF5_SDK_17.1.0_ddde560/examples/dfu/secure_bootloader/pca10040_s132_ble/config/sdk_config.h
+++ b/example/toolchains/nRF5/nRF5_SDK_17.1.0_ddde560/examples/dfu/secure_bootloader/pca10040_s132_ble/config/sdk_config.h
@@ -42,6 +42,30 @@

#ifndef SDK_CONFIG_H
#define SDK_CONFIG_H
+
+#define SEGGER_RTT_SECTION ".rtt"
+
+#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
+#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 512
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
+#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
+#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
+#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
+#endif
+
+#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
+#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0
+#endif

cmake --build cmake-build-debug --target BlinkyExample_bl

Linking target: _build_Debug_BlinkyExample/nrf52832_xxaa_s132.out
/usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/bin/ld: region FLASH overflowed with .data and user data

Readme out of date - how to flash app

The readme is out of date - states we can use flash_ and a number of other targets that do not exist.

I'm going off what's generated in the makefile:

	@echo "The following are some of the valid targets for this Makefile:"
	@echo "... all (the default if no target is provided)"
	@echo "... clean"
	@echo "... depend"
	@echo "... edit_cache"
	@echo "... rebuild_cache"
	@echo "... BlinkyExample_bl"
	@echo "... BlinkyExample_bl_sd_app_merge"
	@echo "... BlinkyExample_bl_sd_app_merge_flash"
	@echo "... BlinkyExample_bl_sd_app_pkg"
	@echo "... BlinkyExample_pkg"
	@echo "... FLASH_ERASE"
	@echo "... FLASH_SOFTDEVICE"
	@echo "... START_JLINK_ALL"
	@echo "... START_JLINK_GDBSERVER"
	@echo "... START_JLINK_RTT"
	@echo "... uECC"
	@echo "... BlinkyExample"

But I don't see anyway to flash just the app, or app plus SD.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.