Skip to main content

Crate rpi_kickstart

Crate rpi_kickstart 

Source
Expand description

The bring-up an application does before it is an application, for bare-metal Raspberry Pi boards built on rpi-hal.

rpi-hal stops at the peripheral: it hands out a Uart, a Mailbox, an Sd. What every board then does with them is the same program written again — a console the whole image can print to, a heap sized from what the firmware reports, a card mounted and a settings file read off it, a site served out of RAM, a clock that something has to set. This crate is that program, once.

§Everything is opt-in, and everything is replaceable

Each capability is its own feature and its own module, and none of them are on by default: a board states what it is, and pays for nothing else. Where a piece has a plausible second implementation — the time source above all, which may be the network on one board and a DS3231 on the next — what this crate owns is the sink the rest of the image reads through, and filling it is the application’s to choose.

The same principle draws the line at the executor. An #[embassy_executor::task] cannot be generic, so this crate never declares one; it exposes async fns and the application wraps them in tasks with its own concrete types. Routing, the global allocator and the panic handler stay with the application for the same reason — they are single, program-wide choices that a library taking them away cannot give back.

§What an application must provide

  • rpi-hal’s rt feature, which supplies the boot sequence, the vector table and the critical-section implementation.
  • rpi-hal’s mmu feature (on by default) for anything using atomics, which includes every embassy executor.
  • A #[global_allocator] and a #[panic_handler]. A program may have only one of each, so neither can come from a library.

Modules§

auth
Password login for a board’s web interface — see the module’s own documentation for what it protects against and what it does not. Password login for a board’s web interface: one shared password, a PBKDF2 verifier stored in its settings, and a session cookie handed out in exchange for it.
clock
The wall clock — see the module’s own documentation for why it is a sink with no source of its own, and why it reads None until set. Wall-clock time, which a Pi does not otherwise have.
config
Reading a board’s settings file — see the module’s own documentation for why the semantic checks run after parsing rather than inside it. Reading and writing a board’s settings file.
console
The console every module logs to — see the module’s own documentation for why its sink is a trait object and its clock is passed in.
entropy
Hardware entropy, and the getrandom backend the crypto stack needs — see the module’s own documentation for what enabling it decides for the whole program. Entropy for the crypto stack, from the SoC’s hardware RNG.
heap
The global heap — see the module’s own documentation for why it declares the #[global_allocator] and what that decides for the rest of the program. The global heap.
https
A minimal HTTPS client — see the module’s own documentation for why it is one request per connection, and why the body comes back whatever the status. A minimal HTTPS client: one request, one response, connection closed.
mdns
An mDNS responder for one name — see the module’s own documentation for the half of the multicast plumbing the board still has to do. An mDNS responder for one name, so a board can be reached as <name>.local instead of as an address.
metrics
Writing Prometheus’s text exposition format — see the module’s own documentation for decimals without a float formatter, and why a label value is only ever written escaped. Writing Prometheus’s text exposition format.
net
Getting a board onto the network, whichever way it can — see the module’s own documentation for why “is Ethernet available” is two questions and both are deadlines. Getting a board onto the network, whichever way it can.
notify
Outbound notifications and the channels that deliver them — see the module’s own documentation for what stays the board’s. Outbound notifications: the message, and the channels that deliver it.
ota
Over-the-air updates: the upload route and the reboot after it — see the module’s own documentation for the one response shape every board answers with. Over-the-air updates: the upload route, and the reboot after it.
site
The board’s web assets, read off the card into RAM — see the module’s own documentation for why the site lives on the card at all. A board’s web assets, read off the card at boot and served from RAM.
sntp
Setting the clock from an NTP server — see the module’s own documentation for what its reply checks do and do not protect against. Setting the wall clock from an NTP server.
splash
A boot logo baked into the kernel image — see the module’s own documentation for why it is run-length-encoded RGB565, and for the encoder a board’s build.rs calls. A boot logo baked into the kernel image, and the host-side encoder that puts it there.
storage
Mounting the card’s FAT volume — see the module’s own documentation for what it costs in RAM and what time the files it writes carry. The card: finding the FAT volume on it and mounting it.
tls
TLS client connections with real certificate verification — see the module’s own documentation for the three things a Pi has to supply, one of them an unaudited crypto provider. TLS client connections: rustls with real certificate-chain verification, over an embassy-net TCP socket.
web
Serving HTTP with picoserve — see the module’s own documentation for why this is pieces of a router rather than a server task. Serving HTTP: the socket loop, and the pieces a board builds its router from.

Macros§

build_info
A BuildInfo for the crate it is written in: its version, and what metrics::build::emit — behind metrics-build, in its build.rs — recorded.
logln
Logs a line to the console, stamped with the uptime and with a trailing CRLF.