[HowTo] NRF9160 Development with CLion

Hi

I want to share how quickly start developing for NRF9160 with CLion, just in case someone tried and struggled, or someone really annoyed with Segger development experience.

Notice: All the instructions are given using Mac OS Mojave and it might be a little bit different for Windows or Linux.

What's working

  • Navigating through your project and SDK libraries
  • Building the project for 9160 board
  • Downloading the project onto the board

Steps

1. Download & install CLion

2. Install the Bash Support plugin (used for the download script)

3. Go to Preferences -> Cmake and add the following variables to the Environment (Specify your own paths here)

ZEPHYR_BASE=/path/to/ncs/zephyr
GNUARMEMB_TOOLCHAIN_PATH=/path/to/gnuarmemb

4. Open your project's directory containing CMakeLists.txt  as a project (File -> Open)

5. Open CMakeLists.txt in the editor and add the following lines right after the cmake_minimum_required line

set(ENV{BOARD} nrf9160_pca10090ns)
set(ENV{BOARD_DIR} $ENV{ZEPHYR_BASE}/boards/arm/nrf9160_pca10090)

set(ENV{ZEPHYR_TOOLCHAIN_VARIANT} gnuarmemb)

set(ENV{CMAKE_AR} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-ar)
set(ENV{CMAKE_AS} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-as)
set(ENV{CMAKE_ASM_COMPILER} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc)
set(ENV{CMAKE_ASM_COMPILER_AR} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc-ar)
set(ENV{CMAKE_ASM_COMPILER_RANLIB} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc-ranlib)

set(ENV{CMAKE_ASM_FLAGS_DEBUG} -g)
set(ENV{CMAKE_ASM_FLAGS_MINSIZEREL} -Os -DNDEBUG)
set(ENV{CMAKE_ASM_FLAGS_RELEASE} -O3 -DNDEBUG)
set(ENV{CMAKE_ASM_FLAGS_RELWITHDEBINFO} -O2 -g -DNDEBUG)

set(ENV{CMAKE_CXX_COMPILER} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-g++)
set(ENV{CMAKE_CXX_COMPILER_AR} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc-ar)
set(ENV{CMAKE_CXX_COMPILER_RANLIB} $ENV{GNUARMEMB_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc-ranlib)

Note: This will lock your project for NS (Non Secure) board, but that's what I use most of the time. If you want to change it, just change the first two lines to accommodate the board you want to use

6. Click Reload CMake Project in the CMake tool window

7. If everything goes successfully, you should see something like:

Running Partition Manager...
-- Configuring done
-- Generating done
-- Build files have been written to: /your/project/path/cmake-build-debug

[Finished]

8. After that use Build -> Build Project to build the project

9. You should see this if it was built:

Scanning dependencies of target linker_pass_final_script_target
[ 98%] Generating linker_pass_final.cmd
[ 98%] Built target linker_pass_final_script_target
[ 98%] Generating isr_tables.c
Scanning dependencies of target zephyr_final
[100%] Building C object zephyr/CMakeFiles/zephyr_final.dir/isr_tables.c.obj
[100%] Linking C executable zephyr.elf
Generating files from zephyr.elf for board: nrf9160_pca10090ns
[100%] Built target zephyr_final
[100%] Generating zephyr/merged.hex
Merged /your/project/path/cmake-build-debug/spm/zephyr/zephyr.hex
Merged /your/project/path/cmake-build-debug/zephyr/zephyr.hex
[100%] Built target merged_hex

10. Now you have merged.hex that is located at /your/project/path/cmake-build-debug/zephyr/merged.hex so you can use any of your favorite ways to upload it to the board.

11. For quick download, I used a simple Bash script that will flash your merged.hex to the connected board:

#!/usr/bin/env bash

nrfjprog --program $(PWD)/cmake-build-debug/zephyr/merged.hex -f NRF91 --sectorerase

12. You can run it from CLion and it should flash your board like so:

/usr/bin/env bash /your/project/path/download.sh
Parsing hex file.
Erasing page at address 0x0.
Erasing page at address 0x1000.
Erasing page at address 0x2000.
Erasing page at address 0x3000.
Erasing page at address 0x4000.
Erasing page at address 0x5000.
Erasing page at address 0x6000.
Erasing page at address 0x7000.
Erasing page at address 0xC000.
Erasing page at address 0xD000.
Erasing page at address 0xE000.
Erasing page at address 0xF000.
Erasing page at address 0x10000.
Erasing page at address 0x11000.
Erasing page at address 0x12000.
Erasing page at address 0x13000.
Erasing page at address 0x14000.
Erasing page at address 0x15000.
Erasing page at address 0x16000.
Erasing page at address 0x17000.
Erasing page at address 0x18000.
Erasing page at address 0x19000.
Erasing page at address 0x1A000.
Erasing page at address 0x1B000.
Erasing page at address 0x1C000.
Erasing page at address 0x1D000.
Erasing page at address 0x1E000.
Erasing page at address 0x1F000.
Erasing page at address 0x20000.
Erasing page at address 0x21000.
Erasing page at address 0x22000.
Erasing page at address 0x23000.
Erasing page at address 0x24000.
Erasing page at address 0x25000.
Erasing page at address 0x26000.
Erasing page at address 0x27000.
Erasing page at address 0x28000.
Erasing page at address 0x29000.
Erasing page at address 0x2A000.
Erasing page at address 0x2B000.
Erasing page at address 0x2C000.
Erasing page at address 0x2D000.
Erasing page at address 0x2E000.
Erasing page at address 0x2F000.
Erasing page at address 0x30000.
Erasing page at address 0x31000.
Erasing page at address 0x32000.
Erasing page at address 0x33000.
Erasing page at address 0x34000.
Erasing page at address 0x35000.
Erasing page at address 0x36000.
Erasing page at address 0x37000.
Erasing page at address 0x38000.
Erasing page at address 0x39000.
Erasing page at address 0x3A000.
Erasing page at address 0x3B000.
Applying system reset.
Checking that the area to write is not protected.
Programming device.

Process finished with exit code 0

Voila!

If you have any questions, please ask

P.S. If few people are interested, I might add a plugin for CLion to allow downloading the file straight from IDE without a need for a script.