August 01, 2019   |   6min read

How to Set up the Open Source IDE for nRF5x Development

In my work as a Bluetooth Low Energy expert I sometimes need to dive into some C code written for BLE peripherals. Embedded development is mostly tied to very specific toolchains. Most of them are developed only for Windows Operating System. As my day-to-day computer is a Macbook I usually end up with a virtual OS.

I really like to work with the Nordic Semiconductor company devices as they opted for an open source toolchain alternative that can be used on different OSes. Being able to compile the code on a platform of choice is one thing. It should also be easy to get a decent development ecosystem at the same time.

Recently a new open source IDE is getting good traction—Visual Studio Code. In this article I will guide you how to set up the environment that helps with writing and debugging your nRF5x firmware! Let’s begin.

Before We Start

This tutorial is a continuation of the Open Source Toolchain for nRF5x article. Here is the list of the needed software(in brackets I mention the versions available at the time of writing):

  1. Visual Studio Code (1.33.1)
  2. Visual Studio Code Extension: C/C++ (0.22.1)
  3. Visual Studio Code Extension: CMake Tools (1.1.3)
  4. Visual Studio Code Extension: Cortex-Debug (0.2.3)
  5. SEGGER J-Link

You will get the best out of this tutorial if you have already set up your project, nRF SDK and compiler the same way as it’s described in the article linked above. You should be able to compile and upload your firmware onto nRF5 device using CMake. I will start the walkthrough from here.



First, download and install Visual Studio Code. Installing extensions is a breeze thanks to the built-in Extensions Marketplace. After opening the VSCode look at the bar on the left. The square icon is the one you need.


Click it and search for the following extensions to install:

  • C/C++
  • CMake Tools
  • Cortex-Debug

Now we can proceed and open your project directory in VSCode. You will be greeted with CMake Tools popup, which won’t be sure what compiler should it use to execute CMakeLists.txt.


CMake Tools

Unfortunately, this extension does not know how to get the proper compiler path if you have not put the gcc-arm-none-eabi in the $PATH. To fix this according to the CMake Tools docs we need to add cmake-kits.json file inside .vscode directory inside your project. Kits config file has to contain information on how to find gcc compiler and look like this:

    "name": "gcc",
    "compilers": {
      "CC": "/path/to/your/compiler/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-gcc",
      "CXX": "/path/to/your/compiler/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-g++"

Now, when you click on “No Kit Selected” on the bottom bar of VSCode you should be able to pick gcc.


Clicking “build” should start building your project. You can change the target just next to the “build” button.


At this point you should be able to build all the targets right from the IDE. But what about changing the source code? Open, for instance, main.c file and you will see that most of the #include statements are underlined with a green squiggle. What is even worse for me is that the following function navigation does not work. The IDE does not know where to find the files.



This extension comes with IntelliSense which is a helper for code navigation and code completion. There is an easy way to make it aware of all configuration related to CMake though. Just change the configuration provider to CMake Tools!

Open Command Palette (View => Command Palette or Cmd+Shift+P), type “change configuration provider”, open the option and choose CMake Tools.


Wait for the red flame in the bottom right corner to disappear. You should now see that most of the squiggles have disappeared as well and that the navigation works! Yay!


Changing the code is now super easy. Unfortunately, my code is usually not perfect from the beginning…


It is very important to run debugging once the code is downloaded on the nRF chip. And setting it all up is quite simple! Just open the Command Palette and type “Debug: Open launch.json” and pick “Cortex Debug” from the next window.


A launch.json file should open with one configuration. There are two things that need to be changed here:

  1. Executable—should point to the file built by CMake. In my case (I named the project TEST) it is “\\\\\${workspaceRoot}/build/TEST.out”
  2. Device—I have performed tests on the nRF51 Development Kit which sports nRF51422xxAC chip. This needs to be set in the configuration file “nRF51422xxAC”. The full list of supported chips is available under this link.


The last step is to inform the extension where the debugger and arm toolchain are installed (you have installed SEGGER J-Link, right? If not I will wait for you just here). Open settings.json file. It should already be created by previous steps. You need to add two entries:

  1. Path to J-Link GDB Server (“cortex-debug.JLinkGDBServerPath”) which in my case is “/Applications/SEGGER/JLink_V622g/JLinkGDBServer”. Yours may be slightly different depending on the J-Link version you downloaded
  2. Path to the ARM Toolchain yet again (“cortex-debug.armToolchainPath”)

It should now look like this:

  "C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
  "cortex-debug.JLinkGDBServerPath": "/Applications/SEGGER/JLink_V646a/JLinkGDBServer",
  "cortex-debug.armToolchainPath": "/Users/dariuszseweryn/Projects/nRF5x-toolchain/gcc-arm-none-eabi-7-2017-q4-major/bin",


And now we are all set to try it out! Just remember to use the built-in debugger:


While it is not a perfect solution we can set up a decent IDE which relies solely on products created by open source development.


Before you go—known issues

This is what I use for Low Energy Bluetooth devices development and it works for me just fine. There are of course some things that could be improved with VisualStudio Code:

  • Error squiggles under includes using built-in files like stdio.h/string.h. Technically it is possible to add appropriate includes to the CMake setup.

    includedirectories(SYSTEM ”${ARMNONEEABITOOLCHAIN_PATH}/arm-none-eabi/include” )

But then IntelliSense started to complain about function APP_ERROR_CHECK function in the app_error.h of Nordic SDK file. There IntelliSense found LOCAL_ERROR_CODE function not being initialized. LOCAL_ERROR_CODE is just a variable, not a function. I could not make it work correctly. Since APP_ERROR_CHECK is more widespread than #include statements of stdio.h or similar files — I decided to leave it this way.

  • CMake Tools debugger integration to use a single place in the UI to build and run it all. It seems that the current version of the integration always tries to look for gcc-none-eabi-lldb which is not available in the toolchain. No attempts to change the debugger used to gdb fixed the situation.
  • CMake default build target ALL tries to execute all targets in parallel by default where FLASH_ERASE, FLASH_SOFTDEVICE and FLASH_${your target name} should be done serially. It’s best not to use the default target at all.

If you find ways to improve these issues or would like to chat about Bluetooth Low Energy feel free to let me know via Twitter! You can reach me at @DSeweryn.

Darek Seweryn

Staff Software Engineer

Did you enjoy the read?

If you have any questions, don’t hesitate to ask!