RIOT-OS 2026.04, codenamed Fire Rizzlease, was released on May 6, 2026.
RIOT is a multi-threading operating system targeting microcontrollers found in the
Internet of Things — from 8-bit and 16-bit MCUs to lightweight 32-bit processors —
with a focus on energy-efficiency, soft real-time capabilities, and a small memory
footprint.
This release spans 84 days of development, 125 merged pull requests composed of 229
commits, and contributions from 27 people. A notable stat: 1,141,523 lines were
deleted against only 25,007 inserted, largely thanks to a major vendor code cleanup.
Codeberg mirror
RIOT is now synced to Codeberg (#21997). This gives the project a home on a
non-profit, community-driven forge alongside its GitHub presence, a welcome step
for an independent open-source project.
Massive EFM32 vendor code removal
Over one million lines of vendor code have been removed from the EFM32 family,
replaced by a pkg/gecko_sdk dependency (#22040). This is the single biggest
contributor to the impressive deletion count and results in a much leaner and more
maintainable codebase for Silicon Labs EFM32-based boards.
Raspberry Pi Pico 2 / RP2350 improvements
The RP2350 support received a thorough overhaul (#21753):
- Unified abstractions between the RISC-V and ARM cores of the RP2350.
- Added the XH3IRQ interrupt controller.
- Updated UART driver.
- Added RISC-V support.
The scope of this work was large enough to inspire a bachelor's thesis at
HAW Hamburg.
New board and CPU support
Three new targets join the supported hardware list:
- pro-micro-nrf52840 (#22089) — a popular nRF52840-based Pro Micro form-factor board.
- slstk3301a (#22069) — Silicon Labs EFM32 Tiny Gecko starter kit.
- STM32H7 (#21978) — high-performance STM32 family, with additional peripheral
support for the nucleo-h753zi (#22076).
New device drivers
- AMG88xx (#22104) — infrared array sensor (thermal camera) from Panasonic.
- ADS1X1X (#21694) — family of Texas Instruments I²C ADCs.
Guide site and documentation
The RIOT Guide Site continues to grow as the default entry point for new users,
progressively replacing Doxygen for prose documentation. This release adds:
- More tutorials.
- An experimental Supported Boards section.
- Unit tests in tutorials (#22042).
- Updated Astro v6 framework (#22145).
The Doxygen API reference remains available at api.riot-os.org.
Networking improvements
Several additions to the GNRC networking stack:
- New gnrc_pktshark module to pretty-print network traffic (#21284).
- gnrc_ipv6_nib_dyn_lladdr_get() API (#22013).
- ABR (Authoritative Border Router) now run-time configurable (#21081).
- Generic UDP shell command (#22049).
Notable bug fixes
43 bugs were fixed in this release, including:
- ESP8266 crashes on reboot and startup (#22014, #22010).
- Potential buffer overflow in the atwinc15x0 driver (#22041).
- NanoCoAP message corruption in coap_build_reply() (#22094).
- Wrong byte order for gyro and accelerometer reads in the MPU-9x50 driver (#22135).
- LVGL configuration and SDL issues on native (#22005, #22139).
Introduction
The goal of the Zephyr project, hosted by the Linux foundation, since 2016, is to provide a safe and secured real time operating system (RTOS) for connected devices that are too small for Linux, or for core companion, through the Apache 2.0 open source license.
It is designed for resource-constrained devices such as microcontrollers and Internet of Things (IoT) devices, to be modular and scalable. This makes it ideal for a wide range of devices, from simple sensors to complex systems. The operating system is written in C and is fully compatible with the C11 and C++17 standards.
One of the key benefits of the Zephyr device model is its small footprint, it can be configured to run on devices with as little as 10 KB of memory.
It supports multiple 32 bits and 64 bits architectures: Cortex-A, Cortex-M, Cortex-R, RISC-V, x86-64, etc.
But it also support several boards and extensions: Feather, nRF52840, ST Discovery, ST Nucleo, ESP-32, etc.
It is able to manage several kinds of connectivity: Bluetooth, ethernet, wifi, LoRa.
And it support some network protocols: IPv4, IPv6,UDP, TCP, CoAP, LWM2M, MQTT, DNS, etc.
As Linux, Zephyr use Kconfig, and its device model is mainly based on device tree.
Device tree
Device trees are tree data structures that describe the hardware components and their relationships in a system.
They are stored in a text file, named device tree sources (*.dts), and they written by developers to describe hardware architectures of SoCs and boards.
And they are used by the operating system to determine how to initialize and interact with the hardware.
Each node describe a device of the system, has its own properties that describe their characteristics, and they have only one parent (except for the root node).
Each device driver is associated with a specific device tree node, which represents a hardware component in the system. The device driver provides the necessary code and data to control the behavior of the hardware component.
test_i2c_bme280: bme280@6 {
compatible = "bosch,bme280";
reg = <0x6>;
};
In the Linux kernel, device tree sources are compiled to device tree binaries (dtb) that are parsed, at boot, by bootloader stages (U-Boot, TF-A...) and the kernel to allow support several hardware configuration with same binaries.
But in Zephyr, device tree sources are transformed to a "devicetree_generated.h" C header file at build, that contains macro definitions and data structures allowing device drivers to access information about the hardware components in the system, such as the memory mapping of a device, its pin assignments, and its IRQ numbers:
#define DT_COMPAT_HAS_OKAY_bosch_bme280 1
#define DT_N_INST_bosch_bme280_NUM_OKAY 1
#define DT_FOREACH_OKAY_bosch_bme280(fn) fn(DT_N_S_soc_S_i2c_40005400_S_bme280_77)
#define DT_FOREACH_OKAY_VARGS_bosch_bme280(fn, ...) fn(DT_N_S_soc_S_i2c_40005400_S_bme280_77, __VA_ARGS__)
#define DT_FOREACH_OKAY_INST_bosch_bme280(fn) fn(0)
#define DT_FOREACH_OKAY_INST_VARGS_bosch_bme280(fn, ...) fn(0, __VA_ARGS__)
#define DT_COMPAT_bosch_bme280_BUS_i2c 1
Where:
- DT_COMPAT_HAS_OKAY_bosch_bme280: indicates that there is at least one instance of BME280
- DT_N_INST_bosch_bme280_NUM_OKAY: defines the number of BME280 instances that are marked okay
- DT_FOREACH_OKAY_bosch_bme280: allows you to apply a function fn to each instance of the BME280
- DT_FOREACH_OKAY_VARGS_bosch_bme280: also allows you to apply a function fn to each instance of the BME280, but with additional arguments
- DT_FOREACH_OKAY_INST_bosch_bme280: allows you to apply a function fn to each instance of the BME280, passing the instance number as an argument
- DT_FOREACH_OKAY_INST_VARGS_bosch_bme280: is similar to the previous macro, but this one allows for additional arguments
- DT_COMPAT_bosch_bme280_BUS_i2c: indicates that the BME280 device is connected to an I2C bus.
- DT_N_S_soc_S_i2c_40005400_S_bme280_77: refers to a specific node in the device tree, here it refers to the BME280 sensor connected to the I2C controller with the base address 0x40005400 within the SoC. The sensor's address on this I2C bus is 0x77.
In addition, device tree sources can be extended or overridden, for example to connect additional devices to a board, or to disable board devices which will not be used:
/ {
aliases {
bme280 = &bme280;
};
};
&spi1 {
status = "disabled";
};
&i2c1 {
status = "okay";
bme280: bme280@77 {
compatible = "bosch,bme280";
reg = <0x77>;
};
};
Binding
Content of device tree sources is described in binding files, that are written in human readable and easy to parse YAML.
Binding files can be also used to validate device tree sources by comparing the information in the YAML file with the information in the device tree sources.
description: BME280 integrated environmental sensor
compatible: "bosch,bme280"
include: [sensor-device.yaml, i2c-device.yaml]
Device driver
In Zephyr, a device driver can access the properties of an associated node in the device tree using the macro that are defined in C header files.
For example, the following code can be used to initialize a BME280 sensor using properties defined in the device tree:
#include <device.h>
#include <drivers/i2c.h>
#include <devicetree.h>
#include <zephyr.h>
// Define the node identifier for the BME280 sensor
#define BME280_NODE DT_N_S_soc_S_i2c_40005400_S_bme280_77
// Function to initialize the BME280 sensor
static int bme280_init(const struct device *dev)
{
// Check if the node is available
if (!device_is_ready(dev)) {
printk("Device %s is not ready\n", dev->name);
return -ENODEV;
}
// Retrieve the I2C device associated with the BME280 node
const struct device *i2c_dev = DEVICE_DT_GET(DT_BUS(BME280_NODE));
if (!device_is_ready(i2c_dev)) {
printk("I2C device not ready\n");
return -ENODEV;
}
// Write some initialization code here, such as configuring registers
printk("BME280 sensor initialized\n");
return 0;
}
// Initialize the BME280 sensor at boot time
SYS_INIT(bme280_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
Conclusion
Those who have already implemented BSP or driver on Linux shouldn't encounter too much difficulty, but on the other hand, the step is a little higher for people coming from the world of micro-controllers.