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)
- 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.
- 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.
- 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:
| Symbol | Default | Effect |
|---|---|---|
CONFIG_BT | n | Enable the Bluetooth subsystem |
CONFIG_BT_PERIPHERAL | n | Enable BLE peripheral role (connectable advertising, GATT server) |
CONFIG_BT_CENTRAL | n | Enable BLE central role (initiator, GATT client) |
CONFIG_BT_MAX_CONN | 1 | Maximum simultaneous BLE connections |
CONFIG_BT_DEVICE_NAME | "Zephyr" | BLE device name used in advertising |
CONFIG_LOG | n | Enable Zephyr logging subsystem |
CONFIG_LOG_BACKEND_UART | n | Route 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 updateafter changing SDK version — switching NCS versions requireswest updateto fetch the new dependency revisions. Building after a version change without runningwest updateproduces 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/.configdirectly — this file is the merged Kconfig output generated by CMake. Any edits are overwritten on the next build. Always modifyprj.confto change configuration; usemenuconfigto 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=yhas no effect withoutCONFIG_BT=y. Themenuconfigbrowser 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=yand a log backend (CONFIG_LOG_BACKEND_UART=yorCONFIG_LOG_BACKEND_RTT=y) from the start. Zephyr's structured logging is substantially more useful than bareprintkonce BLE event callbacks and multi-thread interactions become complex. - Run
west build -t ram_reportafter 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
nRF52 Variants Compared: Which Should You Choose for Your BLE Product?
Compare nRF52 variants: nRF52840 (USB, 802.15.4), nRF52833 (Thread, no USB), nRF52832 (most widely deployed), and entry-level nRF52811/nRF52810. How to choose.
How Do You Implement a BLE Peripheral with Custom GATT Services on nRF52 Using Zephyr?
Implement a BLE peripheral with custom GATT services on nRF52 using Zephyr NCS: service definition, UUIDs, read/write handlers, and notifications.
How Do You Minimise Current Draw on an nRF52 in BLE Applications?
Minimise nRF52 BLE current draw: DCDC converter, advertising interval, connection interval, System OFF mode, Zephyr PM, and PPK2 measurement techniques.
How Do You Use the nRF52840 USB Port and Update Firmware Over DFU?
Use the nRF52840 native USB port in Zephyr NCS: CDC ACM serial, USB DFU class setup, MCUboot dual-slot partitioning, image signing, and DFU trigger workflow.
What Is an RTOS (Real-Time Operating System)?
An RTOS is a lightweight operating system that gives embedded firmware deterministic task scheduling. Learn how RTOSes work and when you actually need one.
Bare-Metal vs RTOS: Which Should You Use for Your Firmware?
Bare-metal firmware and RTOS suit different embedded projects. Learn the trade-offs — timing, RAM overhead, complexity — and how to choose.
Related Forum Discussions
nRF5340 network core not starting — BLE stack hangs on bt_enable after migrating from nRF52840
Trying to bring up an nRF5340 DK for the first time. I've done a few nRF52840 projects before so I figured the NCS migration would be fairly
nRF52840 BLE advertising not starting — device not showing up in scanner after bt_enable completes
Trying my first Zephyr/NCS project on an nRF52840 DK after mostly doing ESP32 stuff. Following the [BLE GATT peripheral guide](/questions/nr