• Stars
    star
    245
  • Rank 165,304 (Top 4 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created over 5 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

API bindings, libstd, and Cargo integration for running Rust applications on a Zephyr kernel

Rust on Zephyr RTOS

Overview

Zephyr module for building a Cargo project and linking it into a Zephyr image. Add this directory to ZEPHYR_EXTRA_MODULES to build a Cargo library project (located in the Zephyr app's source directory by default) and link it into the Zephyr app.

Version Compatibility

Zephyr: v2.3, v2.4, v2.5

Rust: exactly 1.68.0

Features

  • Generated bindings for all syscalls
  • Safe wrappers for some Zephyr APIs (mutex, semaphore, timers, k_poll, UART)
  • Basic libstd port (no_std not necessary)
  • Heap (std::alloc) see CONFIG_RUST_ALLOC_POOL
  • Thread-local storage
  • Kernel or user-mode Rust
    • Rust globals and heap in a Rust-specific memory segment that can be granted to specific threads
    • Syscalls compile to direct C function calls when !CONFIG_USERSPACE
    • Note: running kernel and user-mode Rust at the same time could pose a security risk, since there is one shared global allocator
  • Minimal std::futures executor
    • Supports dynamic tasks and timers
    • Currently single-threaded
    • async/await UART example
  • Implemented as a Zephyr module for inclusion in existing Zephyr projects
  • No modifications to Zephyr source

Building and Running

Clone the repo

Make sure to clone the submodules recursively. This points to modified Rust libstd.

git clone --recurse-submodules https://github.com/tylerwhall/zephyr-rust.git

Zephyr setup

Refer to the Zephyr getting started guide. This includes installing west, getting Zephyr source, and the Zephyr toolchain. Make sure you can build a C sample within Zephyr.

See above for tested compatible Zephyr releases. Please try a release if master does not work. Due to differences in the syscall header generation, v1.14 LTS is no longer supported. See issue 16.

Rust toolchain

The compiler version must exactly match the version of standard library included as a submodule of this project. In practice, using a different compiler version often fails to compile because of Rust internally making heavy use of unstable compiler features.

The current base is stable-1.68.0. Rustup is the default workflow, and the rust-toolchain file in this repo should cause rustup to automatically install and use the right version. If not, manually install:

rustup toolchain install 1.68.0

If supplying your own rustc and cargo, make sure they are the version above. The build will fail if it detects a version mismatch.

Also install clang from your distro. This is required by bindgen to generate syscall bindings. Else you will get this error

thread 'main' panicked at 'Unable to find libclang: "couldn\'t find any valid shared libraries matching: [\'libclang.so\', \'libclang-*.so\', \'libclang.so.*\']

Build

west build -p auto -b <board name> samples/rust-app/

Native:

west build -p auto -b native_posix samples/rust-app/

qemu_x86:

west build -p auto -b qemu_x86 samples/rust-app/

ARM Cortex-M:

west build -p auto -b qemu_cortex_m3 samples/rust-app/

These errors are normal. Needs investigation, but the binary is still created successfully.

x86_64-zephyr-elf-objdump: DWARF error: mangled line number section (bad file number)

Run (QEMU targets):

cd build
ninja run

Sample Output

*** Booting Zephyr OS build zephyr-v2.2.0  ***
Hello Rust println
Hello from Rust kernel with direct kernel call
Hello from Rust kernel with runtime-detect syscall
Hello from second thread
second thread: f = 1
second thread: now f = 55
Time InstantMs(20)
Time Instant(InstantMs(20))
Locking
Unlocking
No device
Boxed value 1
main thread: f = 1
main thread: now f = 2
Hello from Rust userspace with forced user-mode syscall
Locking
Unlocking
INFO app: TEST: info!()
WARN app: TEST: warn!()
ERROR app: TEST: error!()
main thread: f = 2
main thread: now f = 3
Hello from Rust userspace with forced user-mode syscall
Hello from Rust userspace with runtime-detect syscall
Next call will crash if userspace is working.
FAILED: zephyr/CMakeFiles/run

Failure is from an intentional crash at the end of the sample.

Testing

The Zephyr test runner can be used:

$ZEPHYR_BASE/scripts/sanitycheck --testcase-root tests -p native_posix -N

Or you can build and run the test manually:

west build -p auto -b native_posix tests/rust
cd build
ninja run

Supported Architectures

  • native_posix
  • x86
  • armv7m
  • armv7r
  • thumbv7em

Really anything that works with Zephyr and Rust should work. Only need to define a target.json and add a case for it in CMakelists.

TODO

  • Figure out how to fail tests through assertions in code
  • Support #[test]
  • CI
  • Ability to build multiple independent apps
  • Investigate DWARF errors in final link
  • More safe bindings (e.g. GPIO)

Features Not Planned to Support

  • std::thread. Requires thread resources to be dynamically allocated. This is possible, but not common for Zephyr.
  • Defining static threads in Rust. Zephyr uses many layers of architecture-specific C macros that would not be wise to try to duplicate exactly in Rust. Possibly could generate C code like in the "cpp" crate, but for now just define threads in C and point them at a Rust FFI entry point.
  • std::sync::{Mutex, RwLock}. Mutex should work when built without userspace support. Userspace would require (at least) CONFIG_DYNAMIC_OBJECTS. While this is possible, I don't want to require it to use libstd. May revisit. The small number of uses in libstd are patched out.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

More Repositories

1

desktop-duplication-sample

Quick experiment in displaying the desktop as a texture in Unity. Very hacky.
C#
31
star
2

hpbdl

Extract HP printer ".bdl" firmware update files
Rust
10
star
3

rmp-futures

Async Rust MessagePack and MessagePack-RPC
Rust
10
star
4

a2dp-receiver

Makes Linux act as a Bluetooth audio receiver. AVRCP control from VWCDPIC.
Python
10
star
5

CECS-525-QEMU

Modification of QEMU to emulate the minimal 68000 computer used in CECS 525 at the University of Louisville
C
5
star
6

Minecraft-server-wrapper

Fork of cMss 0.3 updated for Alpha
Python
5
star
7

tis-100-rs

TIS-100 CPU interpreter in Rust
Rust
4
star
8

esp8266-fan-control

Lua scripts for NodeMCU to publish ceiling fan light and speed controls over MQTT.
Lua
4
star
9

insomniad

User space policy for Linux's autosleep mechanism
C
3
star
10

hyperdav-server

Basic WebDAV server as a hyper server handler.
Rust
3
star
11

dos-drive-imager

Raw disk imager for DOS
C
3
star
12

vwcdpic

VW CD Changer Emulator for AUX Input
Assembly
3
star
13

libminidump

Minidump and Minicore Generator Library
C
2
star
14

docker-jenkins-swarm

Dockerized swarm client for Jenkins configured with etcd
Shell
2
star
15

docker-gerrit-psql

Gerrit docker configuration using postgresql
Shell
1
star
16

shenzhen-c64

Work in progress Shenzhen Solitaire for Commodore 64
C
1
star
17

insomniad-rs

User space policy for Linux's autosleep mechanism
Rust
1
star
18

fanrf

Hampton Bay / Harbor Breeze RF fan control via RFM22 module
Rust
1
star
19

pwgraster

Decoding of PWG (Printer Working Group) raster images
Rust
1
star
20

Flimsy

Flood monitoring system for a university project. This project is low priority and code quality may be sub-optimal.
Python
1
star