Electronics Design AU
nRF

How Do You Set Up the nRF Connect SDK and Zephyr RTOS for nRF52 Development?

Last updated 28 June 2026 · 9 min read

Direct Answer

The nRF Connect SDK (NCS) uses west, a command-line meta-tool, to manage a multi-repository Zephyr RTOS workspace. The recommended install path is nRF Connect for Desktop — install the Toolchain Manager add-on, then open VS Code with the nRF Connect extension and the toolchain path set automatically. From the command line: west init a workspace pointing to the sdk-nrf manifest, run west update to fetch all dependencies, then build with west build -b <board-target> and flash with west flash. A minimal project requires only three files: CMakeLists.txt, prj.conf, and src/main.c.

Detailed Explanation

The nRF Connect SDK (NCS) is Nordic Semiconductor's unified development framework for nRF52, nRF53, nRF91 (LTE-M/NB-IoT), and nRF70 (Wi-Fi) series devices. It is built on the Zephyr RTOS — an open-source real-time operating system governed by the Linux Foundation — and uses CMake, Python, and a meta-tool called west to manage a workspace of interconnected Git repositories.

Before using any nRF52 peripheral, BLE GATT profile, or power management feature, you need a working NCS workspace. This page covers the full setup process: tool installation, workspace creation, project structure, build, and flash. All commands assume a recent stable NCS release; refer to Nordic's Getting Started Guide for version-specific notes.


Which SDK to Use

All new nRF52 projects should use the nRF Connect SDK, not the legacy nRF5 SDK. Nordic has moved the nRF5 SDK (with SoftDevice BLE stack) to maintenance-only status — no new features, and it does not support the nRF53, nRF91, or nRF70 product families. NCS covers the entire current nRF product line in one toolchain and is the only path to Zephyr BLE, MCUboot OTA, and Zephyr's power management framework.

See nRF52 Variants: Which Should You Choose? for the interaction between SDK choice and variant — the nRF52840, nRF52833, and nRF52832 are all supported in NCS, while the nRF52811 and nRF52810 (24 KB RAM) are too constrained for Zephyr.


Step 1 — Install the Toolchain

Option A — nRF Connect for Desktop and VS Code (recommended)

  1. Download and install nRF Connect for Desktop from Nordic's website. This is a GUI application manager — install the Toolchain Manager add-on from within it.
  2. In Toolchain Manager, install the latest stable NCS version. The installer downloads the Arm GCC toolchain, CMake, Python (including a managed virtual environment), and west automatically.
  3. From Toolchain Manager, open VS Code using the installed toolchain — this sets the environment variables the workspace needs. Install the nRF Connect for VS Code extension, which provides build, flash, and debug integration.

This path handles Python virtual environment management and toolchain path configuration automatically and is the recommended starting point for new developers.

Option B — Command line (CI or advanced users)

Install prerequisites manually: Python 3.10 or later (in a virtual environment), west, CMake 3.20 or later, and the Arm GNU Toolchain (arm-none-eabi-gcc). Nordic's Getting Started Guide lists exact minimum versions for each NCS release.

pip install west

Step 2 — Create the West Workspace

A west workspace is a directory containing the manifest repository (sdk-nrf) and all its dependencies, each pinned to a specific Git commit. The pinned revisions ensure reproducible builds across machines and CI environments.

Initialise from the command line:

west init -m https://github.com/nrfconnect/sdk-nrf --mr v2.7.0 ncs
cd ncs
west update

Replace v2.7.0 with the NCS version you are targeting. west update fetches all repositories listed in sdk-nrf/west.yml. On first run this downloads several hundred megabytes and typically takes a few minutes.

The resulting workspace structure:

ncs/
  .west/
  nrf/             ← sdk-nrf (NCS-specific APIs and samples)
  zephyr/          ← sdk-zephyr (Nordic's patched Zephyr fork)
  bootloader/
    mcuboot/       ← MCUboot bootloader (used for OTA firmware update)
  modules/
    crypto/
      mbedtls/     ← mbedTLS (BLE and TLS cryptography)
    hal/
      nordic/      ← Nordic HAL (hardware register definitions)

VS Code path: Use the nRF Connect extension's "Create a new application" wizard, which runs the equivalent initialisation steps through a GUI and sets the active SDK and toolchain for the workspace.


Step 3 — Project Structure

A minimal NCS application requires three files:

my-project/
  CMakeLists.txt
  prj.conf
  src/
    main.c

CMakeLists.txt — the CMake entry point:

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(my_project)

target_sources(app PRIVATE src/main.c)

find_package(Zephyr) locates the Zephyr build system via the ZEPHYR_BASE environment variable set by the west workspace. Every NCS application starts with this boilerplate.

prj.conf — the project's Kconfig settings:

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="My Device"
CONFIG_LOG=y

prj.conf is the project-level Kconfig file. Every NCS subsystem — BLE, USB, logging, power management, watchdog — is enabled and configured through CONFIG_* symbols here. The nRF5 SDK's macro-heavy header approach does not exist in NCS; the Kconfig system is the single point of feature selection.

src/main.c — the application entry point:

#include <zephyr/kernel.h>

int main(void)
{
    /* Application code here */
    return 0;
}

Step 4 — Build the Project

Command line:

west build -b nrf52840dk/nrf52840 /path/to/my-project

The -b flag specifies the board target. For the nRF52840 Development Kit, the target is nrf52840dk/nrf52840 (slash format, used in NCS v2.5 and later; earlier versions used nrf52840dk_nrf52840 with an underscore). Run west boards | grep nrf52 to list all available nRF52 board targets in your workspace.

The first build processes the entire Zephyr + NCS dependency graph and takes several minutes. Subsequent incremental builds are substantially faster.

Kconfig changes and pristine builds: Adding or removing a CONFIG_* symbol in prj.conf triggers CMake to regenerate the build automatically. If you encounter stale state — a symbol is present but its effect is not visible — force a pristine build:

west build -b nrf52840dk/nrf52840 /path/to/my-project --pristine

VS Code: Select the board target in the nRF Connect extension's Build panel and click "Build Application."


Step 5 — Flash and Debug

Flash:

west flash

Run this from the directory containing build/. By default, west flash uses J-Link. Nordic DK boards include a J-Link OB (On-Board) programmer, so no external probe is required. For a standalone J-Link, pass --runner jlink explicitly.

Debug:

west debug

This starts a GDB server via J-Link and attaches a GDB session. The nRF Connect VS Code extension wraps west debug in a graphical debug session with breakpoints, register views, RTT logging, and RTOS-aware thread inspection (Zephyr thread names appear in the debug thread list).

Verify the SWD connection before flashing custom hardware — confirm SWDIO and SWDCLK pinout and ensure pull-ups are present if required. See How Do You Debug Embedded Firmware? for SWD debugging fundamentals.


Kconfig Reference

Zephyr's Kconfig system controls every subsystem through a hierarchy of Kconfig files distributed across the Zephyr and NCS trees. prj.conf overrides the defaults for your project.

Browse available symbols interactively:

west build -t menuconfig

This opens an ncurses-based configuration browser showing all CONFIG_* symbols with their current values, dependency tree, and help text. The VS Code extension provides a GUI equivalent (guiconfig). Browsing menuconfig before writing prj.conf entries is the fastest way to discover available symbols and their dependencies.

Common BLE Kconfig symbols:

SymbolDefaultEffect
CONFIG_BTnEnable the Bluetooth subsystem
CONFIG_BT_PERIPHERALnEnable BLE peripheral role (connectable advertising, GATT server)
CONFIG_BT_CENTRALnEnable BLE central role (initiator, GATT client)
CONFIG_BT_MAX_CONN1Maximum simultaneous BLE connections
CONFIG_BT_DEVICE_NAME"Zephyr"BLE device name used in advertising
CONFIG_LOGnEnable Zephyr logging subsystem
CONFIG_LOG_BACKEND_UARTnRoute log output to UART

MCUboot child image config: When OTA firmware update is enabled, NCS builds a second image (the MCUboot bootloader) alongside the application. MCUboot has its own CONFIG_BOOT_* Kconfig namespace, set in child_image/mcuboot.conf to keep it separate from the application config. See How Does OTA Firmware Update Work? for the full dual-slot OTA partition and MCUboot workflow.

Zephyr is an RTOS — its scheduler, task model, and concurrency primitives differ substantially from bare-metal firmware. See Bare-Metal vs RTOS: Which Should You Use? and What Is an RTOS? for grounding in the concepts the NCS framework builds on.


Common Setup Mistakes

  • Python environment conflicts — NCS requires specific Python package versions. If you have a global Python installation, version conflicts between west, CMake's Python bindings, and other tools are common. Use a Python virtual environment (python -m venv .venv) and install all NCS Python dependencies inside it. nRF Connect for Desktop manages this automatically.
  • Not running west update after changing SDK version — switching NCS versions requires west update to fetch the new dependency revisions. Building after a version change without running west update produces confusing Kconfig symbol-not-found errors or header conflicts between mismatched repository versions.
  • Using the wrong board target separator — NCS v2.5 changed board targets from underscore format (nrf52840dk_nrf52840) to slash format (nrf52840dk/nrf52840). A "Board not found" CMake error usually means you are using the wrong format for the SDK version installed.
  • Editing build/zephyr/.config directly — this file is the merged Kconfig output generated by CMake. Any edits are overwritten on the next build. Always modify prj.conf to change configuration; use menuconfig to explore options.
  • Adding CONFIG_ symbols with unmet dependencies — many Kconfig symbols only activate when their parent symbol is also enabled. For example, CONFIG_BT_PERIPHERAL=y has no effect without CONFIG_BT=y. The menuconfig browser shows dependency chains explicitly and is the correct tool for diagnosing silent Kconfig no-ops.

Design Considerations

Once the NCS toolchain and workspace are functional:

  • Build and flash the nrf/samples/bluetooth/peripheral_hr/ sample before writing custom GATT code — it exercises advertising, connection, notification, and disconnect in a compact, well-documented codebase and confirms the full tool chain is working end to end.
  • Enable CONFIG_LOG=y and a log backend (CONFIG_LOG_BACKEND_UART=y or CONFIG_LOG_BACKEND_RTT=y) from the start. Zephyr's structured logging is substantially more useful than bare printk once BLE event callbacks and multi-thread interactions become complex.
  • Run west build -t ram_report after initial integration to understand memory partitioning. Zephyr + BLE stack infrastructure on the nRF52840 typically consumes 40–80 KB RAM depending on connection count, GATT table size, and BLE buffer configuration — profile this before committing to a smaller variant.

For nRF52 firmware development including nRF Connect SDK / Zephyr RTOS bring-up, BLE GATT profile implementation, power optimisation, and MCUboot OTA integration, Zeus Design delivers complete firmware stacks for wearable and IoT products.

Frequently Asked Questions

Do I need to use VS Code with the nRF Connect SDK, or can I use the command line only?
Both approaches work. The VS Code + nRF Connect extension route is recommended for most developers because it bundles toolchain installation, project management, build configuration, and J-Link debugging in one UI. The command-line workflow (west init, west update, west build, west flash) is equally capable and is the right choice for CI environments or when you prefer a different editor. Both approaches use the same underlying toolchain and produce identical build outputs.
What board target should I use for the nRF52840 Development Kit?
Use nrf52840dk/nrf52840 in NCS v2.5 and later (slash separator); earlier versions used the underscore form nrf52840dk_nrf52840. The board target determines the memory layout, default pin assignments, and peripheral configuration for the DK hardware. For custom hardware, create a board target in your project's boards/ directory or use the DK target with a device tree overlay (.overlay file) to adjust pin assignments. Run west boards | grep nrf52 to list all available nRF52 board targets in your workspace.
Why do I need to run west update after west init?
The nRF Connect SDK workspace is a collection of Git repositories: sdk-nrf, sdk-zephyr (Nordic's Zephyr fork), sdk-mcuboot, sdk-mbedtls, and others. west init only clones the manifest repository (sdk-nrf) and reads west.yml, which lists all other required repositories and their pinned revisions. west update then clones or updates each dependency to the exact commit the SDK version requires. Skipping west update leaves the workspace incomplete — build failures and missing header errors will result.

References

Related Questions

Related Forum Discussions