Skip to content

Repository files navigation

hisi-riscv-rs

A Rust embedded ecosystem for the HiSilicon RISC-V family — the WS63 (Wi-Fi 6 + BLE + SLE/SparkLink) and the BS2X SKUs (BS20 / BS21E / BS22; BLE + SLE/NearLink), all single-core RV32IMFC (hard-float ilp32f, no atomics) SoCs.

This monorepo bundles per-chip svd2rust peripheral-access crates, a hand-written multi-chip safe HAL, a runtime, a porting layer for the closed-source Wi-Fi/BLE blobs, and runnable examples — buildable today with the official upstream Rust nightly target path, and runnable without hardware on the sister project hisi-riscv-qemu (machines -M ws63 / bs21 / bs21e / bs22 / bs20).

North star: connectivity. The WS63 path now completes real WPA2 scan, connect, sustained local traffic, BLE GATT, and SLE SSAP on paired real boards. The A0-A5 and U0-U8R delivery windows are frozen; no new implementation track starts until the product-direction gate allocates the single WIP slot. Current priorities are in ROADMAP.md, and dated evidence lives under docs/plan/evidence/.

Crates

Each library crate is a standalone repository (a git submodule here) and is published independently to crates.io; ws63-rf-rs and ws63-flashboot live in-tree and are not published.

Crate Role crates.io
ws63-pac svd2rust-generated WS63 peripheral access (raw RegisterBlocks, Peripherals::take()) ws63-pac
bs2x-pac svd2rust-generated BS21/BS2X peripheral access (the multi-chip sibling of ws63-pac) —
hisi-hal Hand-written safe drivers on embedded-hal 1.0 (GPIO, UART, SPI, I2C, DMA, timers, clocks, …) — plus optional async (embedded-hal-async/embedded-io-async) and embassy (an embassy-time driver). Standalone builds have no default chip: enable chip-ws63; experimental chip-bs21 also requires unstable. hisi-hal
hisi-riscv-rt Runtime: startup assembly, linker scripts, interrupt vectors (over riscv-rt) hisi-riscv-rt
hisi-alloc Caller-owned, bounded allocation contracts for vendor runtimes hisi-alloc
hisi-crypto Chip-neutral fallible crypto capabilities, secret/key types, and software oracles hisi-crypto
hisi-keystore Generation-tagged key handles and bounded bond/key lifecycle contracts hisi-keystore
hisi-storage Chip-neutral embedded-storage contracts hisi-storage
hisi-nvs Read-first HiSilicon ACPU KV/NVS format support hisi-nvs
hisi-rom-sys Chip-neutral ROM capability facade hisi-rom-sys
hisi-rf-core Chip-neutral radio domain types and bounded control/event contracts hisi-rf-core
hisi-rf Chip-neutral radio controller/runner, typed Wi-Fi config, bounded events and L2 device contracts hisi-rf
hisi-rf-rtos-driver Runtime-neutral task/IPC contract used by radio adapters hisi-rf-rtos-driver
hisi-rtos Single-hart scheduler, IPC and Embassy integration backend hisi-rtos
hisi-crypto-ws63 WS63 SPACC/PKE/RKP/TRNG hardware backend hisi-crypto-ws63
hisi-rf-ws63 WS63 composition, archive adapter, resource profiles, and radio backend hisi-rf-ws63
ws63-radio-sys WS63 blob ABI/archive profile and versioned hisi-rf-link post-link tooling; nests the language-neutral vendor payload GitHub/submodule
ws63-rf-rs Transitional WS63 blob ABI/OSAL/netif adapter and hisi-rf backend. In-tree, publish = false —
ws63-flashboot Experimental bootloader (not secure boot). In-tree, publish = false —
ws63-examples Runnable WS63 examples (blinky, uart_hello, timer_irq, gpio_irq, dma_loopback, …) —
bs21-examples BS21 isolated workspace; current member list is in docs/src/reference/02-examples.md —
bs20-examples BS20 isolated workspace (128K RAM variant); current member list is in docs/src/reference/02-examples.md —

Repository layout

The repo uses git submodules extensively. Generation inputs and vendor payloads are nested under the crate that owns them, so sibling crates do not reach into them laterally:

hisi-riscv-rs/
├── crates/                    # core publishable library crates
│   ├── chips/
│   │   ├── ws63/              # WS63 PAC, ROM/crypto backends, radio-sys
│   │   │   ├── ws63-pac/ws63-svd/       # PAC generation source
│   │   │   └── ws63-radio-sys/ws63-RF/ # vendor payload
│   │   ├── bs2x/              # BS2X PAC (nests bs2x-svd)
│   │   └── hi3322/            # planned-family PAC work (nests SVD)
│   ├── hisi-hal/              # submodule (multi-chip: chip-ws63 / chip-bs21)
│   ├── hisi-alloc/             # bounded caller-owned allocation contracts
│   ├── hisi-crypto/            # chip-neutral crypto contracts and software oracle
│   ├── hisi-keystore/          # key-handle and bond lifecycle contracts
│   ├── hisi-storage/           # storage traits and chip-neutral access contracts
│   ├── hisi-nvs/               # ACPU KV/NVS reader
│   ├── hisi-rom-sys/           # chip-neutral ROM facade
│   ├── hisi-rf-core/           # chip-neutral radio domain contracts
│   ├── hisi-rf/               # chip-neutral radio API/runner
│   ├── hisi-rf-rtos-driver/   # runtime-neutral radio OS contract
│   ├── hisi-rtos/             # native scheduler/IPC/Embassy runtime
│   ├── hisi-riscv-rt/         # submodule
├── examples/                  # application examples
│   ├── ws63/                  # submodule (blinky, uart_hello, …)
│   ├── bs21/                  # in-tree, isolated workspace (10+ examples: SPI, GADC, I2C, KEYSCAN, QDEC, RTC, WDT, DMA, USB, PDM)
│   └── bs20/                  # in-tree, isolated workspace (BS20 variant: same examples, 128K RAM)
├── chips/                     # chip-specific support
│   ├── ws63/
│   │   ├── guide/             # submodule — WS63 user guide
│   │   ├── rf/                # transitional in-tree crate (ws63-rf-rs)
│   │   └── flashboot/         # in-tree crate (ws63-flashboot)
│   └── bs2x/
│       └── guide/             # submodule — BS21/BS2X user guide
├── docs/                      # architecture docs (Chinese) + review ledger
├── hil/                       # hardware-in-the-loop scripts
├── CLAUDE.md                  # build/architecture guide
└── ROADMAP.md                 # staged plan toward connectivity

Always clone/update with recursion:

git submodule update --init --recursive

Getting started

1. Install the pinned official Rust nightly

The default target riscv32imfc-unknown-none-elf (hardware single-float ilp32f, no atomics) is an upstream rustc builtin target in the pinned nightly. rustup does not ship a prebuilt std component for it yet, so RISC-V builds use rust-src plus -Zbuild-std=core,alloc:

rustup toolchain install nightly-2026-07-09 \
    --profile minimal \
    --component rust-src \
    --component clippy \
    --component rustfmt \
    --component llvm-tools-preview

2. Build

cargo build -Zbuild-std=core,alloc                  # libraries + default-member examples
cargo check -Zbuild-std=core,alloc --workspace --exclude wifi_softap --features hisi-rf/chip-ws63
cargo check -Zbuild-std=core,alloc -p wifi_softap   # AP role is a separate feature-unification lane
cargo build -Zbuild-std=core,alloc -p blinky --release

Lint / format:

cargo clippy -Zbuild-std=core,alloc --workspace --exclude wifi_softap --features hisi-rf/chip-ws63 -- -D warnings
cargo clippy -Zbuild-std=core,alloc -p wifi_softap -- -D warnings
cargo fmt --all -- --check

3. Start your own project

Scaffold a fresh app outside this repo with cargo generate from the hisi-rs-template starter — it wires up the toolchain, target, linker scripts, a QEMU cargo run runner, and the right crates.io deps for the chip you pick:

cargo install cargo-generate
cargo generate --git https://github.com/hispark-rs/hisi-rs-template
#   chip    = ws63 | bs21 | bs21e | bs22 | bs20   (BS2X SKUs share one HAL)
#   starter = blinky | uart_hello | async (embassy; WS63 + BS2X)

Run without hardware (software-in-the-loop)

hisi-riscv-qemu is a QEMU fork with an in-tree WS63 machine (-M ws63) that models the CPU + xlinx custom ISA, memory map, interrupt controller, and the established 35-peripheral SVD model. The PAC now also exposes BT_EM_CTL; QEMU parity for that newly modeled register block is still pending. It runs ws63-rs firmware (and real vendor C-SDK firmware) and is the software-in-the-loop stand-in for the current roadmap's baseline/HIL support track:

# in a sibling checkout of hisi-riscv-qemu
bash scripts/build.sh
WS63_RS=../ws63-rs bash scripts/smoke-test.sh   # boots ws63-rs examples + asserts behaviour

Async & embassy

hisi-hal has an async layer (no heap, no global executor required), built on embedded-hal-async / embedded-io-async. It runs on the no-atomics WS63 core via portable-atomic + critical-section, but the public surface is deliberately split:

  • async — stable blocking-backed async trait impls for SPI/I2C.
  • async + unstable — interrupt/waker helpers such as block_on, IrqSignal, GPIO wait, timer delay, UART async I/O, and DMA/LSADC async hooks.
  • embassy + unstable — the embassy-time driver and embassy examples.

See docs/src/reference/10-stable-api.md for the current boundary.

Releasing

Each published crate self-publishes from its own repository: bump + tag vX.Y.Z in ws63-pac / hisi-hal / hisi-riscv-rt, and that repo's .github/workflows/release.yml publishes it to crates.io (using its own CRATES_IO_TOKEN). The monorepo v* tag cuts only a firmware GitHub Release — it does not publish the library crates.

Documentation

License

MIT for the Rust code (see each crate's Cargo.toml). The closed-source vendor blobs under crates/chips/ws63/ws63-radio-sys/ws63-RF carry HiSilicon's own license and are not MIT — that delivery stays language-neutral and is only linked, never modified.

Releases

Packages

Contributors

Languages