Nordic nRF Firmware Dev Guide
A comprehensive guide to developing firmware for Nordic nRF52, nRF53, nRF54, nRF7002, and nRF9160 SoCs — from project planning and toolchain setup through driver integration, wireless protocols, testing, and secure OTA deployment.
Phase 1
Planning
Define project scope, requirements, and select the appropriate Nordic SoC for your application.
Phase 2
Environment
Configure Nordic's toolchain and nRF Connect SDK for efficient development.
Phase 3
Drivers
Leverage Nordic's HAL and Zephyr drivers for hardware initialization and peripheral access.
Phase 4
Wireless
Integrate Nordic's wireless protocols and implement application logic.
Phase 5
Testing
Test firmware using Nordic's tools and validate wireless performance.
Phase 6
Deployment
Deploy firmware and implement secure OTA updates using Nordic's DFU.
1. Planning & Requirements
Define project scope, requirements, and select the appropriate Nordic SoC for your application.
The planning phase is critical for embedded projects. Choosing the right Nordic SoC upfront prevents costly redesigns later. Consider your wireless protocol needs, power budget, processing requirements, and security features when making your selection.
- 1
Select Nordic SoC Based on Requirements
Choose the right Nordic chip for your application based on connectivity, processing power, and power consumption needs.
Tips
- nRF52832/52840: Best for BLE applications, mesh networking, and low-power sensors
- nRF5340: Dual-core for complex applications requiring both connectivity and processing
- nRF54 Series: Latest generation with improved power efficiency and performance
- nRF7002: WiFi 6 companion IC for cloud-connected applications
- nRF9160: Cellular IoT (LTE-M/NB-IoT) with GPS for asset tracking and remote monitoring
Resources
- 2
Define Wireless Connectivity Needs
Determine which wireless protocols your application requires and ensure your chosen SoC supports them.
Tips
- BLE: Short-range, low-power, ideal for wearables and sensors
- Thread/Zigbee: Mesh networking for smart home and industrial IoT
- WiFi: High bandwidth for streaming and cloud connectivity
- LTE-M/NB-IoT: Wide-area coverage for remote assets
- Consider multi-protocol support (BLE + Thread) for future flexibility
- 3
Create System Architecture
Design your system architecture considering Nordic's SoftDevice, protocol stacks, and application requirements.
Reference
System Architecture Layers: - Application Layer: Business Logic, State Machines, Protocol Handlers - Middleware Layer: nRF Connect SDK Libraries, Zephyr Subsystems - OS Layer: Zephyr RTOS (threads, timers, workqueues) - HAL Layer: Nordic HAL / Zephyr Device Drivers - Hardware Layer: Nordic SoC + External PeripheralsTips
- Separate hardware-specific code into HAL modules
- Use Zephyr's native drivers when available
- Plan memory layout for SoftDevice + application + OTA
- 4
Establish Power Budget
Calculate expected power consumption and battery life early in the design process.
Reference
Power Budget Calculation Example: Active Mode (BLE advertising @ 1s interval): Radio TX: 4.6mA x 1ms = 4.6uAs per interval CPU: 3mA x 0.5ms = 1.5uAs per interval Average: ~6uA continuous Sleep Mode (System ON, RTC running): 1.5uA base Target: CR2032 (225mAh) for 2 years Available: 225mAh / (2 years x 8760 hours) = 12.8uA Budget: 10uA average leaves headroomTips
- Use Nordic Power Profiler Kit II for accurate measurements
- Account for peak currents when sizing batteries
- Include all peripherals in power calculations
- Plan for temperature variations affecting battery capacity
Resources
- 5
Plan Peripheral Usage
Map out which peripherals you need and their pin assignments.
Tips
- Check pin multiplexing constraints in the datasheet
- Reserve pins for programming/debugging (SWD)
- Consider peripheral power domains for low-power modes
- Plan for hardware flow control on UART if needed
- 6
Define Security Requirements
Determine security features needed: secure boot, encryption, TrustZone, key storage.
Tips
- nRF52: Software-based security, CryptoCell for crypto acceleration
- nRF53/54: Arm TrustZone for hardware isolation
- nRF9160: Trusted Firmware-M (TF-M) for secure processing
- Plan key provisioning and storage strategy early
2. Development Environment Setup
Configure Nordic's toolchain and nRF Connect SDK for efficient development.
Setting up the development environment correctly saves hours of debugging later. Nordic provides excellent tooling through nRF Connect for Desktop and VS Code extensions. The nRF Connect SDK builds on Zephyr RTOS and provides Nordic-specific drivers and libraries.
- 1
Install nRF Connect for Desktop
Download and install nRF Connect for Desktop, which provides access to all Nordic development tools.
Reference
Key apps to install via nRF Connect for Desktop: - Toolchain Manager: Install and manage SDK versions - Programmer: Flash firmware to devices - Bluetooth Low Energy: Debug BLE connections - Power Profiler: Analyze power consumption - Serial Terminal: UART communicationTips
- Keep nRF Connect for Desktop updated for latest tool versions
- Install all recommended apps for comprehensive development support
- Toolchain Manager handles SDK and toolchain version management
Resources
- 2
Set Up nRF Connect SDK with Zephyr
Use Toolchain Manager to install the nRF Connect SDK which includes Zephyr RTOS and all necessary tools.
Reference
SDK structure after installation: ~/ncs/ ├── nrf/ # Nordic-specific code and samples ├── zephyr/ # Zephyr RTOS core ├── modules/ # Third-party modules (mbedTLS, etc.) ├── bootloader/ # MCUboot bootloader └── tools/ # Build tools Verify installation: $ west --version $ cmake --versionTips
- Use LTS (Long Term Support) SDK versions for production projects
- nRF Connect SDK v2.x uses west for build management
- Keep a backup of working SDK versions before upgrading
Resources
- 3
Configure VS Code with nRF Connect Extension
Install VS Code and the nRF Connect Extension Pack for the best development experience.
Tips
- Install the full nRF Connect Extension Pack (includes C/C++, CMake, DTS)
- Use the nRF Connect sidebar for build, flash, and debug operations
- Configure IntelliSense for accurate code completion
Resources
- 4
Install nRF Command Line Tools
Install command-line tools for scripting, automation, and CI/CD integration.
Reference
Key commands: $ nrfutil version # Check installation $ nrfutil device list # List connected devices $ nrfutil device program --firmware app.hex # Flash firmware $ nrfutil device reset # Reset device $ nrfutil device recover # Recover locked device West build commands (Zephyr): $ west build -b nrf52840dk_nrf52840 # Build for target $ west flash # Flash to device $ west debug # Start debug sessionTips
- Add nrfutil to your PATH for easy access
- Use --snr flag to target specific device when multiple connected
- Combine with west for streamlined workflow
Resources
- 5
Set Up Development Kit
Connect and configure your Nordic Development Kit for programming and debugging.
Tips
- Update DK firmware using nRF Connect Programmer
- Check jumper settings for power source selection
- Install USB drivers if not automatically detected
- Use board's onboard J-Link for debugging (no external debugger needed)
- 6
Initialize Git Repository
Set up version control with proper structure for Nordic/Zephyr projects.
Reference
Recommended .gitignore for nRF Connect SDK projects: build/ *.pyc __pycache__/ .west/ *.log *.elf *.hex *.bin .vscode/settings.json *.DS_StoreTips
- Track prj.conf, overlay files, and Kconfig in version control
- Don't commit build directories or SDK files
- Use Git tags to mark firmware releases
- Include hardware revision in commit history
3. Hardware Abstraction & Drivers
Leverage Nordic's HAL and Zephyr drivers for hardware initialization and peripheral access.
The nRF Connect SDK provides comprehensive hardware abstraction through Zephyr's device driver model and Nordic-specific HAL layers. Using Device Tree for configuration keeps your C code clean and makes porting between boards straightforward.
- 1
Configure Device Tree
Use Device Tree Source (DTS) files and overlays to configure hardware without modifying C code.
Reference
Example overlay file (nrf52840dk.overlay): Enable I2C with BME280 sensor at address 0x76 Configure GPIO for status LED on pin P0.13 Use aliases for hardware-independent code accessTips
- Use overlays instead of modifying board DTS files
- Check compatible strings in Zephyr bindings documentation
- Use aliases for hardware-independent code
- Validate overlays with 'west build' before flashing
Resources
- 2
Initialize Clock System
Configure high-frequency and low-frequency clocks for optimal performance and power consumption.
Reference
Clock configuration in prj.conf: CONFIG_CLOCK_CONTROL=y CONFIG_CLOCK_CONTROL_NRF=y Notes: - HFCLK (64MHz) is needed for radio and high-speed peripherals - LFCLK (32.768kHz) runs always for RTC and timers - Clocks are managed automatically by Zephyr in most casesTips
- HFCLK (64MHz) is needed for radio and high-speed peripherals
- LFCLK (32.768kHz) runs always for RTC and timers
- Use external 32kHz crystal for best BLE timing accuracy
- Clocks are managed automatically by Zephyr in most cases
- 3
Set Up GPIO
Configure GPIO pins for inputs, outputs, and interrupts using Zephyr's GPIO API.
Reference
GPIO setup pattern: 1. Get GPIO device from Device Tree using GPIO_DT_SPEC_GET 2. Check gpio_is_ready_dt() before using GPIO 3. Configure with gpio_pin_configure_dt() 4. For buttons: add interrupt with gpio_pin_interrupt_configure_dt() 5. Use gpio_init_callback() and gpio_add_callback() for ISRTips
- Always check gpio_is_ready_dt() before using GPIO
- Use GPIO_DT_SPEC_GET for compile-time device tree access
- Configure interrupt polarity based on hardware (pull-up/pull-down)
- Debounce button inputs in software or hardware
- 4
Configure Serial Interfaces (UART, SPI, I2C)
Set up communication peripherals using Zephyr device drivers.
Reference
Enable peripherals in prj.conf: CONFIG_UART_ASYNC_API=y CONFIG_I2C=y CONFIG_SPI=y Pattern for I2C: 1. Get device with DEVICE_DT_GET(DT_NODELABEL(i2c0)) 2. Check device_is_ready() before use 3. Use i2c_write_read() for register accessTips
- Use async APIs for non-blocking operations
- Check max clock frequencies in peripheral datasheets
- Configure DMA for high-throughput transfers
- Handle bus errors and implement retry logic
- 5
Implement Interrupt Handlers
Handle hardware interrupts efficiently using Zephyr's ISR management.
Reference
ISR best practice pattern: 1. Keep ISR short - just submit work with k_work_submit() 2. Use k_work_init() to initialize work item in main() 3. Do heavy processing in work handler, not ISR 4. Use volatile for data shared between ISR and mainTips
- Keep ISRs as short as possible
- Use work queues to defer processing
- Avoid blocking calls (malloc, printf) in ISRs
- Use atomic operations for shared data
- 6
Set Up Power Management
Configure power management for optimal battery life using Nordic's PM API.
Reference
Power management in prj.conf: CONFIG_PM=y CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y Use pm_device_action_run() to suspend/resume peripherals Use pm_policy_state_lock_get/put() during critical operationsTips
- Zephyr automatically enters low-power modes when idle
- Use PM_DEVICE to control individual peripheral power
- Lock power states during time-critical operations
- Profile power with and without PM enabled
Resources
4. Wireless Protocol Integration
Integrate Nordic's wireless protocols and implement application logic.
Nordic provides production-ready protocol stacks in the nRF Connect SDK. The Bluetooth stack is based on Zephyr's implementation with Nordic optimizations. Thread, Zigbee, and Matter support enable smart home applications, while cellular IoT is supported on the nRF9160.
- 1
Configure Bluetooth Low Energy
Set up BLE with Zephyr's Bluetooth stack for advertising, connections, and GATT services.
Reference
BLE configuration in prj.conf: CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="MyDevice" CONFIG_BT_DEVICE_APPEARANCE=833 CONFIG_BT_MAX_CONN=1 CONFIG_BT_MAX_PAIRED=2 Initialization flow: 1. bt_enable(NULL) to initialize stack 2. Define advertising data with BT_DATA macros 3. Register connection callbacks with BT_CONN_CB_DEFINE 4. Start advertising with bt_le_adv_start()Tips
- Use BT_CONN_CB_DEFINE for static callback registration
- Configure connection parameters for your power/latency needs
- Enable CONFIG_BT_SETTINGS to persist bonding information
- Use nRF Connect mobile app for testing and debugging
Resources
- 2
Implement GATT Services
Create custom BLE services and characteristics for your application.
Reference
GATT service pattern: 1. Define custom 128-bit UUIDs with BT_UUID_DECLARE_128 2. Create read/write handlers for characteristics 3. Use BT_GATT_SERVICE_DEFINE to declare service 4. Include BT_GATT_CCC for notification support 5. Use bt_gatt_notify() to send notificationsTips
- Use 128-bit UUIDs for custom services
- Include CCC (Client Characteristic Configuration) for notifications
- Test with nRF Connect mobile app's GATT viewer
- Consider using Nordic's GATT Service samples as templates
- 3
Add Thread/Zigbee Support
Enable mesh networking protocols for smart home and industrial IoT applications.
Reference
Thread configuration in prj.conf: CONFIG_NETWORKING=y CONFIG_NET_L2_OPENTHREAD=y CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y CONFIG_OPENTHREAD_CHANNEL=11 CONFIG_OPENTHREAD_PANID=4660 Use OpenThread API via openthread_get_default_context()Tips
- Thread requires IEEE 802.15.4 radio (nRF52840, nRF5340)
- Use OpenThread CLI sample for initial testing
- Configure network credentials via CLI or programmatically
- Consider Matter for cross-ecosystem compatibility
Resources
- 4
Configure WiFi for nRF7002
Set up WiFi connectivity using the nRF7002 companion IC.
Reference
WiFi configuration in prj.conf: CONFIG_WIFI=y CONFIG_WIFI_NRF700X=y CONFIG_WPA_SUPP=y CONFIG_NET_L2_WIFI_MGMT=y CONFIG_NET_DHCPV4=y Use net_mgmt(NET_REQUEST_WIFI_CONNECT, ...) to connectTips
- nRF7002 requires nRF5340 or nRF52840 as host
- Enable WPA3 for enhanced security
- Use low-power modes (TWT) for battery-powered devices
- Test with different access points for compatibility
Resources
- 5
Implement LTE-M/NB-IoT for nRF9160
Set up cellular connectivity for wide-area IoT applications.
Reference
LTE configuration in prj.conf: CONFIG_LTE_LINK_CONTROL=y CONFIG_NRF_MODEM_LIB=y CONFIG_MODEM_INFO=y Initialization: 1. nrf_modem_lib_init() to start modem 2. lte_lc_register_handler() for events 3. lte_lc_connect_async() to connect to networkTips
- Use LTE-M for mobility, NB-IoT for stationary sensors
- Configure PSM (Power Saving Mode) and eDRX for power optimization
- Test with nRF Cloud for easy connectivity verification
- Handle network registration and connection loss gracefully
Resources
- 6
Develop Application State Machines
Implement application logic using state machines for reliable operation.
Reference
State machine pattern: 1. Define states as enum (INIT, IDLE, ADVERTISING, CONNECTED, etc.) 2. Create state handler functions for each state 3. Use function pointer array for state dispatch 4. Implement transition_to() function for state changes 5. Consider Zephyr's SMF for complex state machinesTips
- Use state machines for complex control flow
- Document state transitions with diagrams
- Handle all edge cases and error states
- Use Zephyr's SMF (State Machine Framework) for complex state machines
5. Testing & Validation
Test firmware using Nordic's tools and validate wireless performance.
Thorough testing is essential for reliable embedded systems. Nordic provides excellent tools for BLE testing, power profiling, and RF analysis. Combine automated testing with manual validation on real hardware to catch issues before deployment.
- 1
Use nRF Connect Mobile App
Test BLE functionality with Nordic's mobile app for Android and iOS.
Tips
- Scan for your device's advertising packets
- Connect and explore GATT services and characteristics
- Read, write, and enable notifications on characteristics
- View connection parameters and signal strength
- Log data for later analysis
Resources
- 2
Perform Power Profiling
Measure actual power consumption using Power Profiler Kit II (PPK2).
Reference
Production configuration for accurate profiling: CONFIG_LOG=n # Disable logging CONFIG_ASSERT=n # Disable asserts CONFIG_DEBUG=n # Disable debug Test all modes: advertising, connected, data transfer, sleep Calculate: Battery Life = Capacity (mAh) / Average Current (mA)Tips
- Measure each operating mode separately
- Account for peak currents (radio TX)
- Test at expected temperature range
- Compare measurements against datasheet values
- Use PPK2 trigger mode for event-based capture
Resources
- 3
Test RF Performance
Validate wireless range and reliability using nRF Sniffer and other tools.
Reference
RF testing checklist: 1. Range testing at various distances 2. Test through walls and obstacles 3. Measure RSSI and packet loss 4. Test with WiFi and other 2.4GHz interference 5. Verify antenna matching and radiation patternTips
- Use nRF Sniffer to capture and analyze packets
- Test with multiple phone models for BLE
- Document RF test results for certification
- Consider antenna placement in enclosure design
Resources
- 4
Validate Protocol Compliance
Ensure your implementation meets protocol standards and passes certification tests.
Tips
- Run Bluetooth SIG qualification tests
- Test with official certification equipment if available
- Document compliance for regulatory submissions
- Use Nordic's pre-certified modules to simplify certification
- 5
Conduct Integration Testing
Test complete system integration with all components and interfaces.
Reference
Integration test checklist: Hardware: All sensors, actuators, power supply, reset sequence Software: All tasks, inter-task communication, error handling System: End-to-end data flow, mobile app, cloud connectivity, OTATips
- Create automated test scripts where possible
- Test failure scenarios (power loss, disconnect)
- Verify behavior across temperature range
- Document test procedures for repeatability
- 6
Perform Long-Term Stability Testing
Run extended tests to catch memory leaks, timing issues, and rare bugs.
Tips
- Run for days or weeks in realistic conditions
- Monitor memory usage over time
- Log errors and unexpected behaviors
- Test rapid connect/disconnect cycles
- Stress test with maximum data rates
6. Deployment & OTA Updates
Deploy firmware and implement secure OTA updates using Nordic's DFU.
Proper deployment includes secure bootloading, over-the-air update capability, and protection against unauthorized access. Nordic's MCUboot integration provides a robust foundation for secure firmware updates.
- 1
Implement Device Firmware Update (DFU)
Set up Nordic's DFU for firmware updates over BLE, UART, or USB.
Reference
DFU over BLE configuration in prj.conf: CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="path/to/key.pem" CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y CONFIG_MCUMGR=y CONFIG_MCUMGR_GRP_IMG=y CONFIG_MCUMGR_GRP_OS=yTips
- Use MCUmgr protocol for standardized update flow
- Test updates with nRF Connect mobile app
- Plan partition sizes for largest expected image
- Implement update progress indication in UI
Resources
- 2
Configure Secure Bootloader (MCUboot)
Set up MCUboot for verified boot and secure update installation.
Reference
MCUboot configuration in prj.conf: CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="priv-key.pem" CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y CONFIG_MCUBOOT_IMAGE_VERSION="1.0.0" Build signed image: $ west build -b nrf52840dk_nrf52840 Output: build/zephyr/app_signed.hexTips
- Store signing keys securely (HSM for production)
- Use different keys for development and production
- Enable encryption for sensitive firmware
- Test rollback protection mechanism
Resources
- 3
Set Up OTA Infrastructure
Deploy backend infrastructure for managing and distributing firmware updates.
Tips
- Use nRF Cloud for quick prototyping
- Implement version checking before download
- Support delta updates to reduce bandwidth
- Track update success/failure rates
- Plan for fleet segmentation (staged rollouts)
Resources
- 4
Enable Security Features
Configure TrustZone, secure key storage, and access protection.
Reference
TrustZone configuration for nRF5340/nRF9160: CONFIG_ARM_TRUSTZONE_M=y CONFIG_SPM=y # Secure Partition Manager Access protection: - APPROTECT: Blocks debugger access - SECUREAPPROTECT: Blocks secure domain access - Use KMU (Key Management Unit) for secure key storageTips
- Enable APPROTECT in production to prevent debugging
- Use TF-M for advanced secure processing (nRF91)
- Implement secure provisioning for keys
- Test that protection cannot be bypassed
- 5
Create Production Firmware
Build optimized, protected firmware for production deployment.
Reference
Production prj.conf settings: CONFIG_LOG=n CONFIG_ASSERT=n CONFIG_DEBUG=n CONFIG_PRINTK=n CONFIG_SIZE_OPTIMIZATIONS=y CONFIG_STACK_CANARIES=y CONFIG_HW_STACK_PROTECTION=y Build: west build -b board -- -DCONF_FILE=prj_release.confTips
- Create separate debug and release configurations
- Remove all debug output for production
- Enable hardware stack protection
- Verify final image size fits in flash
- Store build artifacts with version tags
- 6
Establish Monitoring and Diagnostics
Implement logging and monitoring for deployed devices.
Tips
- Use nRF Cloud for device monitoring
- Implement error logging with persistence
- Add heartbeat/health check functionality
- Plan for remote diagnostics capability
- Track key metrics (battery, connectivity, errors)
Resources
Nordic Development Tools
IDEs
VS Code with nRF Connect Extension, SEGGER Embedded Studio, Keil MDK
SDK
nRF Connect SDK, nRF5 SDK, Zephyr RTOS
Debuggers
J-Link, nRF52/53/54/9160 DK onboard debugger
Programming Tools
nRF Command Line Tools, nrfutil, west (Zephyr)
Testing Tools
nRF Connect for Mobile, Power Profiler Kit II, nRF Sniffer
Wireless Tools
nRF Cloud, Bluetooth Mesh SDK, Thread/Zigbee SDK
Nordic Resources
Skip the boilerplate — generate your nRF project
FirmwareMaestro scaffolds a complete nRF Connect SDK + Zephyr project tailored to your hardware, with sensible Kconfig, Device Tree overlays, and MCUboot wiring out of the box.