Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FreeRTOS Development Setup

Guide for developing and testing nano-ros on FreeRTOS + lwIP using QEMU MPS2-AN385 (ARM Cortex-M3).

Prerequisites

  • qemu-system-arm (QEMU with ARM system emulation)
  • arm-none-eabi-gcc (ARM bare-metal cross-compiler)
  • Rust nightly toolchain with thumbv7m-none-eabi target
# Install cross-compiler (Ubuntu/Debian)
sudo apt install qemu-system-arm gcc-arm-none-eabi

# Install Rust target
rustup target add thumbv7m-none-eabi
rustup component add --toolchain nightly rust-src

Or use just setup which installs Rust targets automatically.

FreeRTOS + lwIP Sources

Download the FreeRTOS kernel and lwIP:

just setup freertos

This shallow-clones:

  • FreeRTOS kernel (V11.2.0) → third-party/freertos/kernel/
  • lwIP (STABLE-2_2_1_RELEASE) → third-party/freertos/lwip/

Override paths if sources are elsewhere:

VariableDefaultDescription
FREERTOS_DIRthird-party/freertos/kernelFreeRTOS kernel source
FREERTOS_PORTstated by the board (GCC_ARM_CM3 on mps2)upstream FreeRTOS-Kernel’s port enum (phase-349 W3)
LWIP_DIRthird-party/freertos/lwiplwIP source
FREERTOS_CONFIG_DIRBoard crate’s config/FreeRTOSConfig.h + lwipopts.h

Building Examples

just freertos build-examples

This cross-compiles all FreeRTOS examples for thumbv7m-none-eabi. The board crate’s build.rs compiles FreeRTOS kernel, lwIP, and the LAN9118 lwIP netif driver via the cc crate.

Available Examples

Rust examples are in examples/mps2-an385-freertos/rust/:

ExampleDescription
talkerPublishes std_msgs/Int32 on /chatter
listenerSubscribes to std_msgs/Int32 on /chatter
service-serverServes AddTwoInts on /add_two_ints
service-clientCalls AddTwoInts on /add_two_ints
action-serverServes Fibonacci action on /fibonacci
action-clientSends Fibonacci goal on /fibonacci

Testing

just freertos test

This runs QEMU-based integration tests with TAP networking. Each QEMU instance connects to the host via a TAP device, communicating through a bridge running zenohd:

┌─────────────────────────────────────────────────┐
│  Host (Linux)                                    │
│  zenohd (192.0.3.1)  QEMU talker  QEMU listener │
│       │                   │              │        │
│  ─────┴───────────────────┴──────────────┴────── │
│       br-qemu         tap-qemu0      tap-qemu1   │
└─────────────────────────────────────────────────┘

Network Setup

TAP bridge setup requires root. The test infrastructure handles this automatically via scripts/qemu/setup-network.sh.

RoleIP AddressTAP Device
zenohd (host)192.0.3.1br-qemu
Talker/Publisher192.0.3.10tap-qemu0
Listener/Sub192.0.3.11tap-qemu1
Service Server192.0.3.12tap-qemu0
Service Client192.0.3.13tap-qemu1

Architecture

The FreeRTOS platform stack:

User Application (Executor + Node + Pub/Sub)
        │
nros-node (Executor)
        │
nros-rmw-zenoh → zpico-sys (zenoh-pico + C shim)
        │                       │
        │          zenoh-pico FreeRTOS platform
        │          (system.c + lwip/network.c)
        │
Board Crate (nros-board-mps2-an385-freertos)
├── FreeRTOS kernel (tasks, mutexes, semaphores)
├── lwIP TCP/IP stack (BSD sockets, threaded mode)
└── LAN9118 lwIP netif driver (Ethernet on QEMU)

Key Design Points

  • Multi-threaded: FreeRTOS provides real tasks/mutexes. zenoh-pico uses background read/lease tasks.
  • lwIP socket API: POSIX-compatible socket()/connect()/select() — same code path as zenoh-pico’s POSIX platform.
  • Build via cc crate: FreeRTOS kernel + lwIP compiled in the board crate’s build.rs (no external CMake needed).
  • no_std target: thumbv7m-none-eabi with semihosting output.

Task Priorities

PriorityTaskRole
4tcpip_threadlwIP TCP/IP processing
4poll taskLAN9118 RX FIFO → lwIP
4zenoh read/leasezenoh-pico background I/O
3app tasknros application (Executor + Node)
2timer taskFreeRTOS software timers
0idleWFI (mandatory for QEMU networking)

Debugging

See FreeRTOS LAN9118 Debugging Guide for detailed register-level debugging, common pitfalls, and QEMU networking internals.

Porting to Real Hardware

The QEMU board crate (nros-board-mps2-an385-freertos) validates the FreeRTOS integration pattern. To port to a real board (e.g., STM32F767 Nucleo):

  1. Create a new board crate (e.g., nros-stm32f767-freertos)
  2. Replace LAN9118 netif with the vendor Ethernet driver (STM32 HAL ETH)
  3. Update FreeRTOSConfig.h for the target MCU (clock, heap, priorities)
  4. Update lwipopts.h for available RAM
  5. Update the linker script for the target’s memory map
  6. Keep the same run() pattern and Config builder

The nros Executor, Node, and zenoh-pico integration are unchanged — only the board-level HAL and Ethernet driver differ.