Getting Started with Zephyr OS Threads on the nRF7002DK

Table of Contents


Introduction to Zephyr OS Logging

The Zephyr OS logging module is a powerful tool for embedded developers, offering a lightweight yet flexible way to log debug, diagnostic, and operational messages. Designed for resource-constrained devices, it balances functionality with minimal memory and CPU overhead. Whether you’re debugging a sensor driver or monitoring a network stack, the logging module provides fine-grained control over message output, making it indispensable for IoT applications.

In this blog post, we’ll explore the Zephyr logging module and demonstrate its use on the nRF7002DK, a development kit from Nordic Semiconductor featuring Wi-Fi 6 and Bluetooth LE capabilities. By the end, you’ll know how to configure and use logging to streamline development and debugging.


Key Features of the Logging Module

The Zephyr logging module is packed with features tailored for embedded systems:

  • Log Levels: Supports multiple severity levels (ERROR, WARNING, INFO, DEBUG) for filtering messages.
  • Backends: Outputs logs to UART, console, network, or custom destinations.
  • Asynchronous Logging: Queues messages to avoid blocking critical tasks.
  • Module-Specific Logging: Register unique log instances for different subsystems.
  • Runtime Control: Adjust log levels dynamically via APIs or shell commands.
  • Thread Safety: Safe for use in multi-threaded or interrupt contexts.

These features make the logging module versatile for both development and production environments.


Setting Up Logging on the nRF7002DK

The nRF7002DK is an ideal platform for testing Zephyr’s logging module, thanks to its support for UART and its rich set of peripherals. Here’s how to set it up:

  1. Enable Logging in Kconfig: Modify your project’s prj.conf to enable the logging module and UART backend:
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3  # INFO level
CONFIG_LOG_BACKEND_UART=y
  1. Register a Log Instance: In your application code, register a log instance for your module:
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(my_app, LOG_LEVEL_INF);
  1. Verify UART Output: Connect the nRF7002DK to your computer via USB, and use a terminal emulator (e.g., PuTTY or minicom) to monitor the UART output at 115200 baud.

Practical Example: Logging Sensor Data

Let’s create a simple Zephyr application for the nRF7002DK that logs simulated sensor data. This example assumes a temperature sensor (emulated for simplicity).

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

// Register log instance
LOG_MODULE_REGISTER(sensor_app, LOG_LEVEL_INF);

void main(void)
{
    LOG_INF("nRF7002DK sensor application started");

    int sensor_value = 20; // Simulated temperature in Celsius
    while (1) {
        LOG_INF("Temperature: %d°C", sensor_value);
        LOG_DBG("Debug: Processing sensor data");

        // Simulate temperature change
        sensor_value += (k_uptime_get_32() % 2) ? 1 : -1;
        if (sensor_value > 30) sensor_value = 20; // Reset if too high

        k_msleep(2000); // Log every 2 seconds
    }
}

Steps:

  1. Save the code as main.c in your Zephyr project.
  2. Build and flash the application to the nRF7002DK using:
west build -b nrf7002dk/nrf5340/cpuapp
west flash
  1. Open a terminal emulator to view the logs.

Sample Output (with LOG_LEVEL_INF):

[00:00:00.123] <inf> sensor_app: nRF7002DK sensor application started
[00:00:02.123] <inf> sensor_app: Temperature: 20°C
[00:00:04.123] <inf> sensor_app: Temperature: 21°C
...

To enable DEBUG logs, update prj.conf with CONFIG_LOG_DEFAULT_LEVEL=4 and rebuild. This will show LOG_DBG messages as well.


Optimizing Logging for Production

While debugging benefits from verbose logging, production systems require optimization to minimize resource usage:

  • Reduce Log Level: Set CONFIG_LOG_DEFAULT_LEVEL=1 to log only errors.
  • Disable Unused Backends: Remove CONFIG_LOG_BACKEND_UART if logs are sent over a network backend.
  • Use Asynchronous Mode: Enable CONFIG_LOG_MODE_DEFERRED to queue logs and avoid blocking.
  • Buffer Logs: Configure CONFIG_LOG_BUFFER_SIZE to handle bursts of log messages.

For the nRF7002DK, you might also consider a network backend (e.g., UDP) to send logs to a remote server, leveraging the board’s Wi-Fi capabilities.


Conclusion

The Zephyr OS logging module is a versatile tool for embedded development, offering flexibility and efficiency for debugging and monitoring. By integrating it with the nRF7002DK, developers can easily log sensor data, network events, or system status, streamlining the development of IoT applications. With its configurable backends, log levels, and runtime controls, the module adapts to both development and production needs.

Try experimenting with different backends or log levels on the nRF7002DK to see how the logging module fits into your workflow. For more details, check the Zephyr documentation or explore the nRF7002DK’s capabilities for your next IoT project!