nRF Connect SDK Advanced Practices
- 5 minutes read - 1020 wordsIn our previous article, we provided a brief overview of the nRF Connect SDK and demonstrated how to build a simple application. This article explores advanced practices for working with the nRF Connect SDK, focusing on Zephyr OS internals, including timers, schedulers, bootloading, DFU, and FOTA concepts. It builds on our previous introduction to the nRF Connect SDK and provides insights into developing multi-threaded firmware, troubleshooting, and deploying firmware over the air (OTA).
This article is inspired from the detailed course, and covers the advanced concept in brief here.
Practice Note : IoT devices are resource-constrained, and every additional component impacts memory, CPU, and battery usage. The nRF Connect SDK includes numerous configuration options to optimize resource utilization.
Device Boot Process
When an nRF device powers on, it starts in a hibernation or reset state. The boot process consists of multiple phases:
- Preparation Phase: The device initializes hardware components, preparing for kernel execution.
- Kernel Initialization: System drivers (e.g., clock, UART, timers) are initialized based on the system and application configuration.
- Post-Kernel Initialization:
- System threads and the scheduler are initialized.
- Application threads are launched.
- The
main()
function is invoked within the main thread, completing the boot sequence.
By default, the device executes the application stored at memory address 0x00000000
in Non-Volatile Memory (NVL), which retains its content even after a power cycle. If an application is directly flashed at this address, any update requires manually reflashing the device—a highly impractical approach.
To enable seamless updates, a bootloader is instead flashed at 0x00000000
, which loads and manages the application firmware dynamically.
A bootloader from trusted source, often referred to as an Immutable Bootloader, that is locked for modification once flashed. A trusted bootloader ensures application integrity by verifying digital signatures before loading an application.
Multi-Tasking in Zephyr RTOS
IoT applications often require multi-tasking. Zephyr RTOS provides Threads and Interrupts for managing concurrent tasks efficiently.
- Threads — Created by the application or system. The scheduler maintains a queue of ready-to-execute threads, allocating CPU time based on priority. Preemptible threads are commonly used in user applications, whereas cooperative threads (negative priority) cannot be preempted. Key functions like k_yield(),moves the thread to the ready queue, k_sleep()- Puts the thread in sleep mode, allowing others to run.
- Interrupts — Triggered by timers, external signals, or device I/O. It preempts the current running thread. Interrupts can also be interrupted by higher-priority interrupts.
Practice Note: Interrupt handlers should be short and avoid blocking calls. Avoid using K_FOREVER timeouts inside an interrupt. User interrupts for Time-critical operations, and for accessing restricted set of kernel services and registers.
Data Synchronization in Multi-Threading
To prevent data corruption, synchronization mechanisms include:
- Mutexes, Semaphores, and Event Flags to manage critical sections.
- Message Queue & FIFO : Message Queues are used when the number and size of items are known, while FIFO is used when item sizes vary.
- Consumer threads wait when the queue is empty, while producer threads wait when the queue is full.
Practice Notes:
Use memory-efficient structures like union within a struct to optimize memory usage.Calling k_fifo_get() removes data from the FIFO, but developers must free allocated memory using k_free().
Do not add the same data item twice in a FIFO, as it may corrupt the linked list used internally.
Execution Context & Stack Management
Each execution environment has its own context and stack memory allocation.
- When the scheduler switches between threads or interrupts, context switching occurs.
- Large-memory applications may require external memory configurations.
Debugging and Troubleshooting
The nRF Connect Extensions in VSCode provide powerful debugging tools, it provides standard debugging methods like breakpoint, watch, conditional breakpoint and call-stack, play/pause. It provide interesting views on
- Thread Viewer: Displays details of each thread and its stack memory usage.
- Peripherals Viewer: Shows a memory map of peripherals and their register values.
- Debug Modes: The debugger can run in two modes. Halt mode, the debugger halts the CPU when a debug request occurs, while in Monitor Mode, the debugger lets the CPU debug parts of an application while crucial functions continue.
- Remote Debugging: Supported via GDB.
- Core Dumps: Useful for debugging field issues without remote access.
Practice Note: Implement both local debugging and core dump capabilities for production devices. Core dump support is not enabled by default in Zephyr and requires additional configuration.
Device Firmware Update (DFU)
Firmware updates are managed by the bootloader. During a Device Firmware Update (DFU), the device boots into DFU mode instead of launching the application. It then receives and installs a new firmware image, replacing the existing application in NVL.
DFU Methods
DFU can be performed in two main ways:
- Bootloader-Level DFU: The bootloader directly receives and installs firmware updates over a basic interface like UART.
- Application-Level DFU:
- Used for more complex communication protocols (e.g., BLE, Wi-Fi, HTTP).
- The firmware is downloaded into a secondary memory partition.
- Once verified, the bootloader switches to the new firmware.
- A rollback mechanism ensures the device can revert to the previous version if an update fails.
nRF Connect SDK Support
nRF Connect SDK includes MCUboot as the bootloader and provides standard libraries for DFU:
- Partition Manager: Manages NVL partitions, including:
- mcu_bootloader (Bootloader)
- mcu_primary (Primary Application Slot)
- mcu_secondary (DFU Update Slot)
- MCUmgr: Manages DFU over UART or BLE.
- DFU Target Library: Determines the type of update and processes it accordingly
- FOTA download Library: Fetches firmware updates via a URL and hands them over to DFU Target.
For DFU, we need two builds to be deployed. Earlier there used to be multi-image system in nRF SDK, that merges multiple images to one. Sysbuild became available in nRF Connect SDK version 2.7.0 and is enabled by default for all nRF Connect SDK projects from version 2.8.0 onwards.
What Next?
This article covered key advanced concepts of the nRF Connect SDK, including bootloading, scheduling, multi-threading, and debugging. Additional topics to explore include:
- Defining custom boards
- Pulse Width Modulation (PWM)
- Serial Peripheral Interface (SPI)
- The Zephyr Device Driver Model
Mastering these topics will further enhance your firmware development skills for nRF-based IoT applications.
Check out 🔗 nRF Connect SDK Intermediate — Nordic Developer Academy course to solidify your understanding.
Find the IoT Practices Publication for more details.
#IOT #network #cloud #getting started #learning #technology #fundamentals #thread #openthread #nRF #SDK #OTA #DFU #OS