liminfo

Zephyr RTOS Reference

Free reference guide: Zephyr RTOS Reference

26 results

About Zephyr RTOS Reference

The Zephyr RTOS Reference is a comprehensive guide to the Zephyr Project, an open-source real-time operating system designed for resource-constrained IoT and embedded devices. This reference covers the essential APIs and patterns for Zephyr development, from kernel primitives like K_THREAD_DEFINE and k_thread_create for static and dynamic thread management, to k_sleep, k_yield, and thread suspend/resume for scheduling control. Each entry includes production-ready code examples that compile against the Zephyr SDK.

This reference organizes Zephyr's extensive API surface into six practical categories: Threads (static/dynamic creation, sleep, yield, suspend/resume), Device Tree (DT_NODELABEL, DT_PROP, DT_CHOSEN, DT_ALIAS macros for hardware abstraction), Drivers (gpio_pin_configure_dt, sensor_sample_fetch, uart_poll_out/in, i2c_write/read for peripheral access), Networking (Ethernet L2, BSD sockets via zsock_*, MQTT client, CoAP messaging), Build (west build/flash/debug, CMakeLists.txt configuration), and Configuration (prj.conf Kconfig options, board device tree overlays, menuconfig GUI).

Whether you are developing for Nordic nRF52840, STM32, ESP32, or any of the 600+ supported boards, this reference provides the device-tree-driven, hardware-abstracted API patterns that make Zephyr code portable across architectures. The device tree system maps hardware to software bindings at compile time, Kconfig enables modular feature selection, and the west meta-tool handles building, flashing, and debugging. These patterns represent the modern approach to embedded development where hardware details are abstracted into declarative configuration rather than scattered across C code.

Key Features

  • K_THREAD_DEFINE and k_thread_create examples for static and dynamic thread creation with priority and stack configuration
  • Device tree macros (DT_NODELABEL, DT_PROP, DT_CHOSEN, DT_ALIAS) for compile-time hardware abstraction
  • GPIO driver API with device-tree-based pin configuration, set, and toggle using gpio_dt_spec structures
  • Sensor, UART, and I2C driver examples with device tree bindings for BME280, serial communication, and bus operations
  • BSD socket API (zsock_socket/connect) and protocol clients for MQTT publish/subscribe and CoAP RESTful messaging
  • West meta-tool commands for building (west build -b board), flashing (west flash), and debugging (west debug) firmware
  • CMakeLists.txt project setup with find_package(Zephyr) and target_sources for application builds
  • Kconfig system with prj.conf options, device tree overlays (.dts), and interactive menuconfig for feature configuration

Frequently Asked Questions

What is the difference between K_THREAD_DEFINE and k_thread_create?

K_THREAD_DEFINE creates a thread statically at compile time, allocating the stack and thread control block in the binary. It takes the thread name, stack size, entry point, arguments, priority, options, and startup delay. k_thread_create creates threads dynamically at runtime from pre-allocated stack memory. Static threads are preferred for fixed tasks that always exist, while dynamic threads are used when the number of threads varies or threads are created and destroyed during operation.

How does Zephyr's device tree system work for hardware abstraction?

The device tree is a hierarchical data structure describing hardware topology, compiled from .dts files at build time. Macros like DT_NODELABEL(led0) reference nodes by label, DT_PROP reads properties like baud rate, DT_CHOSEN accesses the Zephyr-selected console device, and DT_ALIAS provides shorthand names. DEVICE_DT_GET obtains the runtime device handle. This system decouples application code from specific hardware, allowing the same C code to run on different boards by changing only the device tree overlay.

How do I configure GPIO pins using the device tree API?

First define the GPIO spec from the device tree: const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios). Then configure the pin direction: gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE). Control the pin with gpio_pin_set_dt(&led, 1) to set high or gpio_pin_toggle_dt(&led) to toggle. This approach automatically resolves the GPIO controller, pin number, and active-low/high polarity from the device tree, making the code hardware-independent.

What networking protocols does Zephyr support for IoT applications?

Zephyr supports a comprehensive networking stack including Ethernet L2, IPv4/IPv6 with DHCP, BSD-compatible sockets (zsock_socket, zsock_connect, zsock_send/recv), MQTT client for publish/subscribe messaging to brokers, CoAP for constrained RESTful communication, LwM2M for device management, HTTP client/server, WebSocket, and DNS resolver. For wireless, it supports Bluetooth Low Energy, IEEE 802.15.4, Thread mesh networking, and Wi-Fi. The stack is modular and enabled through Kconfig options.

How does the west build system work in Zephyr development?

West is Zephyr's meta-tool that manages the workspace, build, flash, and debug workflows. "west build -b nrf52840dk_nrf52840 samples/basic/blinky" configures CMake with the target board and builds the firmware. "west flash" programs the built image onto the device using the detected debug probe (J-Link, OpenOCD, etc.). "west debug" launches a GDB session connected to the target. West also manages Zephyr's manifest-based dependency system for pulling in modules, HALs, and external libraries.

What is Kconfig and how does prj.conf work in Zephyr?

Kconfig is Zephyr's feature configuration system inherited from the Linux kernel. The prj.conf file in your application root sets CONFIG_* options to enable or disable kernel features, drivers, and subsystems. For example, CONFIG_GPIO=y enables GPIO drivers, CONFIG_BT=y enables Bluetooth, and CONFIG_LOG_DEFAULT_LEVEL=3 sets logging verbosity. Options have dependencies (CONFIG_BT_PERIPHERAL requires CONFIG_BT), and "west build -t menuconfig" opens an interactive GUI for exploring all available options with descriptions.

How do I read sensor data in Zephyr using the sensor API?

Obtain the device handle with DEVICE_DT_GET_ONE(compatible_string), for example DEVICE_DT_GET_ONE(bosch_bme280). Call sensor_sample_fetch(dev) to trigger a hardware read, then sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &val) to retrieve specific channels. The sensor_value struct contains val1 (integer part) and val2 (fractional part in millionths). This unified API works identically across different sensor chips, with the device tree binding selecting the correct driver at compile time.

How do I create a device tree overlay for custom hardware?

Create an app.overlay file in your project root or a boards/board_name.overlay for board-specific changes. Use node references with & to modify existing nodes: &i2c0 { status = "okay"; bme280@76 { compatible = "bosch,bme280"; reg = <0x76>; }; }; adds a BME280 sensor on I2C bus 0 at address 0x76. Overlays are merged with the base board .dts at build time. Properties like pin assignments, bus speeds, and interrupt configurations are all declaratively specified in the overlay.