XIAO Zephyr RTOS Development
Overview
Complete Zephyr RTOS development guide for SeeedStudio XIAO series. This skill works with the /xiao skill - use /xiao for pin definitions, /xiao-zephyr for Zephyr RTOS APIs, build system, and configuration.
Prerequisites
- Pin Definitions: Read
/xiaoskill first for board-specific pin mappings - Zephyr SDK: Native Zephyr SDK with west tool (PRIMARY method)
- PlatformIO (optional): Alternative for nRF54L15 only
- Build Tools: CMake, Ninja, Devicetree compiler, Python 3.8+
Environment Setup
For first-time Zephyr environment installation, see setup/:
- Zephyr SDK Installation (PRIMARY):
setup/installation.md- Native SDK with west workflow - PlatformIO (optional, nRF54L15 only):
setup/platformio.md - Tooling:
setup/tooling.md- CMake, Devicetree compiler requirements
Zephyr Project Structure (CRITICAL)
Zephyr requires a specific project structure:
my-zephyr-project/
├── CMakeLists.txt # Build configuration (required)
├── prj.conf # Kconfig settings (required)
├── overlay.dtsh # Devicetree overlay (optional, for custom pins)
└── src/
└── main.c # Application code
CMakeLists.txt (Minimum)
cmake_minimum_required(VERSION 3.20)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(my_project)
target_sources(app PRIVATE src/main.c)
prj.conf (Minimum)
# Minimum required configuration
CONFIG_MAIN_STACK_SIZE=1024
CONFIG_GPIO=y
Code Generation Workflow (CRITICAL)
When a user requests Zephyr code generation, you MUST:
Step 1: Select Board (Zephyr Board Name)
| Board | Zephyr Board Name |
|---|---|
| nRF52840 | seeeduino_xiao_ble |
| ESP32C3 | seeeduino_xiao_esp32c3 |
| ESP32C6 | xiao_esp32c6 |
| ESP32S3 | xiao_esp32s3 |
| MG24 | xiao_mg24 |
| nRF54L15 | seeed_xiao_nrf54l15 |
| RA4M1 | xiao_ra4m1 |
| RP2040 | xiao_rp2040 |
| SAMD21 | seeeduino_xiao |
Step 2: Create Project Structure
Use the Write tool to create:
CMakeLists.txt- Build configurationprj.conf- Kconfig settingssrc/main.c- Application codeoverlay.dtsh(if custom pin mapping needed)
Step 3: Configure with Kconfig
Add required subsystems to prj.conf:
# Enable GPIO
CONFIG_GPIO=y
# Enable I2C (if needed)
CONFIG_I2C=y
# Enable SPI (if needed)
CONFIG_SPI=y
# Enable UART (if needed)
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y
# Enable Bluetooth (if needed)
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
Step 4: Write Code Using Zephyr APIs
Use Zephyr kernel and driver APIs (see api/ reference files):
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS 1000
/* Get the device pointer for the GPIO */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led), gpios);
int main(void)
{
if (!gpio_is_ready_dt(&led)) {
return 0;
}
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
while (1) {
gpio_pin_toggle_dt(&led);
k_msleep(SLEEP_TIME_MS);
}
return 0;
}
Step 5: Build with West
# Set Zephyr environment
source zephyr-env.sh # Linux/macOS
# or
zephyr-env.bat # Windows
# Build
west build -b <board_name>
# Example for XIAO nRF52840:
west build -b seeeduino_xiao_ble
Step 6: Flash with West
west flash
Quick Start by Board
| Board | Zephyr Board Name | Getting Started |
|---|---|---|
| nRF52840 | seeeduino_xiao_ble | getting-started/xiao-ble.md |
| ESP32C3 | seeeduino_xiao_esp32c3 | getting-started/xiao-esp32c3.md |
| ESP32C6 | xiao_esp32c6 | getting-started/xiao-esp32c6.md |
| ESP32S3 | xiao_esp32s3 | getting-started/xiao-esp32s3.md |
| MG24 | xiao_mg24 | getting-started/xiao-mg24.md |
| nRF54L15 | seeed_xiao_nrf54l15 | getting-started/xiao-nrf54l15.md |
| RA4M1 | xiao_ra4m1 | getting-started/xiao-ra4m1.md |
| RP2040 | xiao_rp2040 | getting-started/xiao-rp2040.md |
| SAMD21 | seeeduino_xiao | getting-started/seeeduino-xiao.md |
Zephyr APIs and Subsystems
Basic Peripherals
| API/Subsystem | Reference |
|---|---|
| GPIO (Digital I/O) | api/gpio-pwm-adc.md |
| PWM | api/gpio-pwm-adc.md |
| ADC | api/gpio-pwm-adc.md |
| I2C | api/i2c-spi-uart.md |
| SPI | api/i2c-spi-uart.md |
| UART/Serial | api/i2c-spi-uart.md |
Connectivity
| API/Subsystem | Reference |
|---|---|
| Bluetooth LE | api/bluetooth.md |
| WiFi (ESP32) | api/wifi.md |
| Networking | api/networking.md |
Kernel Services
| API/Subsystem | Reference |
|---|---|
| Threading | api/threads.md |
| Timers | api/timers.md |
| Power Management | api/power-management.md |
Configuration Systems
| Topic | Reference |
|---|---|
| Kconfig | configuration/kconfig.md |
| Devicetree | configuration/devicetree.md |
| CMakeLists.txt | configuration/cmake.md |
| prj.conf settings | configuration/prj-conf.md |
Code Patterns
Basic Structure (Blinky)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(blinky)
target_sources(app PRIVATE src/main.c)
prj.conf:
CONFIG_GPIO=y
src/main.c:
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#define SLEEP_TIME_MS 1000
/* LED on D10 (XIAO standard) - adjust per board */
#define LED_NODE DT_ALIAS(led)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED_NODE, gpios);
int main(void)
{
if (!device_is_ready(led.port)) {
return 0;
}
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
while (1) {
gpio_pin_toggle_dt(&led);
k_msleep(SLEEP_TIME_MS);
}
return 0;
}
Non-blocking Delay (Kernel Timer)
#include <zephyr/kernel.h>
#define TIMER_INTERVAL_MS 1000
K_TIMER_DEFINE(my_timer, timer_expiry_callback, NULL);
void timer_expiry_callback(struct k_timer *timer)
{
// Timer expired
}
int main(void)
{
k_timer_start(&my_timer, K_MSEC(TIMER_INTERVAL_MS), K_MSEC(TIMER_INTERVAL_MS));
while (1) {
// Other work here
k_msleep(100);
}
return 0;
}
Threading Example
#include <zephyr/kernel.h>
#define THREAD_STACK_SIZE 1024
#define THREAD_PRIORITY 5
K_THREAD_DEFINE(thread_id, THREAD_STACK_SIZE,
thread_func, NULL, NULL, NULL,
THREAD_PRIORITY, 0, 0);
void thread_func(void *p1, void *p2, void *p3)
{
while (1) {
// Thread work here
k_msleep(1000);
}
}
int main(void)
{
// Main thread
while (1) {
k_msleep(1000);
}
return 0;
}
Code Verification
After generating Zephyr code, verify it builds correctly.
Build with West
# Set Zephyr environment
source zephyr-env.sh # Linux/macOS
# or
zephyr-env.bat # Windows
# Build for specific board
west build -b <board_name> -p always
# Example for XIAO nRF52840:
west build -b seeeduino_xiao_ble -p always
Common Build Errors and Solutions
| Error | Solution |
|---|---|
Could not find Zephyr | Source zephyr-env.sh or set ZEPHYR_BASE |
Unknown board | Check board name matches Zephyr board identifier |
undefined reference to gpio_pin_configure_dt | Add CONFIG_GPIO=y to prj.conf |
Devicetree error | Check overlay.dtsh syntax and node names |
Kconfig error | Check prj.conf syntax and option names |
Verification Checklist
After generating code, verify:
- CMakeLists.txt includes
find_package(Zephyr REQUIRED) - prj.conf enables required subsystems (GPIO, I2C, SPI, etc.)
- Pin definitions match the XIAO board (use
/xiaoskill) - Board name matches Zephyr board identifier
- Code compiles without errors
- Memory usage is within board limits
Troubleshooting
Build Failures
- Environment not set: Source
zephyr-env.shbefore building - Wrong board name: Check Zephyr board name in
boards/seeed/ - Missing Kconfig options: Enable required subsystems in prj.conf
Flash Failures
- nRF52: Double-click RESET button to enter bootloader
- ESP32: Hold BOOT button during flash
- RP2040: Hold BOOTSEL while connecting USB
Device Tree Issues
- Check node names match devicetree sources
- Verify alias names in overlay.dtsh
- Use
west build -t menuconfigto inspect configuration
Sense Boards Support
XIAO Sense boards with onboard sensors are supported in Zephyr:
| Board | Onboard Peripherals | Reference |
|---|---|---|
| nRF52840 Sense | IMU (6-axis), PDM mic, NFC | getting-started/xiao-ble.md |
| ESP32S3 Sense | Camera, PDM mic | getting-started/xiao-esp32s3.md |
| MG24 Sense | IMU (6-axis), PDM mic | getting-started/xiao-mg24.md |
Expansion Boards
XIAO expansion boards are supported in Zephyr. For hardware specifications, see /xiao/references/expansion_boards/.
| Expansion Board | Zephyr Support | Reference |
|---|---|---|
| Expansion Base | Yes (OLED, RTC, SD, buzzer) | examples/expansion-base.md |
| Round Display | Yes (touchscreen) | examples/round-display.md |
| Grove Shield | Yes | Examples in examples/ |
Resources
setup/
Environment installation and configuration:
setup/installation.md- Zephyr SDK and west tool installation (Windows/macOS/Linux)setup/platformio.md- PlatformIO for nRF54L15 (optional alternative)setup/tooling.md- CMake, Devicetree compiler, and other tools
getting-started/
Board-specific setup instructions for all 9 supported XIAO boards:
getting-started/xiao-ble.md- nRF52840 setup and first projectgetting-started/xiao-esp32c3.md- ESP32C3 setupgetting-started/xiao-esp32c6.md- ESP32C6 setupgetting-started/xiao-esp32s3.md- ESP32S3 setupgetting-started/xiao-mg24.md- MG24 setupgetting-started/xiao-nrf54l15.md- nRF54L15 setupgetting-started/xiao-ra4m1.md- RA4M1 setupgetting-started/xiao-rp2040.md- RP2040 setupgetting-started/seeeduino-xiao.md- SAMD21 setup
api/
Zephyr API documentation:
api/gpio-pwm-adc.md- GPIO, PWM, ADC APIsapi/i2c-spi-uart.md- I2C, SPI, UART communicationapi/bluetooth.md- Bluetooth LE stack (80+ examples)api/wifi.md- WiFi (ESP32 boards)api/networking.md- IP networking, MQTTapi/threads.md- Threading and schedulingapi/timers.md- Kernel timersapi/power-management.md- Sleep modes
configuration/
Zephyr configuration systems:
configuration/kconfig.md- Kconfig systemconfiguration/devicetree.md- Devicetree overlaysconfiguration/cmake.md- CMakeLists.txt patternsconfiguration/prj-conf.md- prj.conf settings
examples/
Complete project examples combining Ref/zephyr and Ref/platform-seeedboards:
examples/basic.md- Blinky, button, sensor examplesexamples/bluetooth.md- BLE peripheral, central, meshexamples/sensors.md- I2C/SPI sensor integrationexamples/lowpower.md- Low power modes
Related Skills
/xiao- Core board reference with pin definitions/xiao-arduino- Arduino development for XIAO/xiao-micropython- MicroPython development for XIAO
