Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Rivet RTOS board support: ESP32-S3 real hardware (plan.md Phases 22-24).
Implements the Group B (rivet::port::board) contract for a genuine
ESP32-S3 dev board — no QEMU model exists for Xtensa in this
environment, so unlike every other board in this workspace, nothing
here has ever run in a simulator; every piece is validated by flashing
and reading the real serial transcript.
Why no esp-hal dependency
An earlier version of this crate depended on esp-hal for its
well-tested clock-tree and watchdog-disable bring-up (esp_hal:: init()). That does not coexist with Rivet owning its own preemptive-
tick interrupt: esp-hal::interrupt::xtensa defines
__level_N_interrupt for every level 1 through 7 as part of its own
generic peripheral-interrupt dispatch, and xtensa-lx-rt only allows
exactly one definition of each — confirmed as a hard multiple definition link error at two different levels tried, not assumed.
Watchdog disable is instead hand-rolled directly against the esp32s3
PAC: the exact register sequence and magic unlock keys below were
cross-checked against esp-hal's own source for correctness, without
linking esp-hal itself.
CPU clock: not yet measured
[CPU_HZ] is a documented assumption (the boot ROM's XTAL-derived
default), not something this crate independently measures or
configures — tick cadence is therefore approximate for now, not
exact. Correctness of scheduling itself does not depend on this being
precise (every tick still fires and is handled), only real-world
timing accuracy does. Tracked as a follow-up once basic preemption is
proven on hardware.
This board's mask ROM needs a JTAG-assisted boot, every boot
Confirmed live on the N16R8 devkit this session (chip revision v0.2),
reproduces after a full USB power cycle with no debugger ever
attached — this is a real, persistent property of this chip, not a
debugging artifact: on reset, before any flashed firmware (or even
the 2nd-stage bootloader) ever runs, Espressif's own mask ROM
main() reads the CPU's PRID special register, finds it equal to
0xabab (the value ROM treats as "running under a simulator"), and
spins forever in a tight loop waiting for an external debugger to
write the real boot entry point into a fixed hardware register
(0x600c0004) — normal SPI-flash boot is never attempted. Nothing
in this crate, rivet-arch-xtensa, or rivet itself can fix this:
it happens entirely inside ROM, before any of our code is reachable.
scripts/esp32s3-jtag-unblock.sh (repo root) automates the
workaround — reset, halt in the spin loop, write the ELF's real
entry point into that register, resume — and was verified to let
the flashed app run to completion (traced via JTAG all the way to
__rivet_board_exit). Needed on every boot, not just once.