feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support: - Splash screen on boot (1.5s) with project name, version, board - Dashboard showing radio state, config, counters, RSSI/SNR - RSSI history sparkline (64-sample ring buffer, 2px-wide bars) - DisplayOn/DisplayOff host commands routed via dedicated channel - Pure render functions against generic DrawTarget (no hardware coupling) - Display on/off control bypasses radio task entirely Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
17624 files changed
+4564928
-38
No files matched your search
+84
@@ -0,0 +1,84 @@
|
||||
<!-- Copyright 2025 The Fuchsia Authors
|
||||
|
||||
Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
|
||||
<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
|
||||
license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
|
||||
This file may not be copied, modified, or distributed except according to
|
||||
those terms. -->
|
||||
|
||||
# Unsafe Code Guidelines
|
||||
|
||||
`unsafe` code is extremely dangerous and should be avoided unless absolutely
|
||||
necessary. When it is absolutely necessary to write `unsafe` code, it should be
|
||||
done extremely carefully.
|
||||
|
||||
This document covers guidelines for writing unsafe code, including pointer casts
|
||||
and safety comments.
|
||||
|
||||
## Pointer Casts
|
||||
|
||||
- **Avoid `&slice[0] as *const T`**: Use `slice.as_ptr()`. Accessing subsequent
|
||||
elements via pointer arithmetic on a single-element pointer is UB.
|
||||
```rust
|
||||
let slice = &[1, 2];
|
||||
|
||||
// BAD: Derived from reference to single element.
|
||||
let ptr = &slice[0] as *const i32;
|
||||
// SAFETY: UB! `ptr` has provenance only for the first element.
|
||||
// Accessing `ptr.add(1)` is out of bounds for this provenance.
|
||||
let val = unsafe { *ptr.add(1) };
|
||||
|
||||
// GOOD: Derived from the slice itself.
|
||||
let ptr = slice.as_ptr();
|
||||
// SAFETY: Safe because `ptr` has provenance for the entire slice.
|
||||
let val = unsafe { *ptr.add(1) };
|
||||
```
|
||||
- **Avoid converting `&mut T` to `*const T`**: This reborrows as a shared
|
||||
reference, restricting permissions. Cast `&mut T` to `*mut T` first.
|
||||
```rust
|
||||
let mut val = 42;
|
||||
let r = &mut val;
|
||||
|
||||
// BAD: `r as *const i32` creates a shared reborrow.
|
||||
// The resulting pointer loses write provenance.
|
||||
let ptr = r as *const i32 as *mut i32;
|
||||
// SAFETY: UB! Writing to a pointer derived from a shared reborrow.
|
||||
unsafe { *ptr = 0 };
|
||||
|
||||
// GOOD: `r as *mut i32` preserves write provenance.
|
||||
let ptr = r as *mut i32;
|
||||
// SAFETY: Safe because `ptr` retains mutable provenance.
|
||||
unsafe { *ptr = 0 };
|
||||
```
|
||||
|
||||
## Safety Comments
|
||||
|
||||
Every `unsafe` block must be documented with a `// SAFETY:` comment.
|
||||
- **Requirement:** The comment must prove soundness using *only* text from the
|
||||
stable [Rust Reference](https://doc.rust-lang.org/reference/) or [standard
|
||||
library documentation](https://doc.rust-lang.org/std/).
|
||||
- **Citation:** You must cite and quote the relevant text from the
|
||||
documentation. Citations must cite a specific version of the documentation
|
||||
(e.g. https://doc.rust-lang.org/1.91.0/reference/ or
|
||||
https://doc.rust-lang.org/1.91.0/std/).
|
||||
- **Prohibition:** Do not rely on "common sense" or behavior not guaranteed by
|
||||
the docs.
|
||||
```rust
|
||||
// BAD: Missing justification for "obvious" properties.
|
||||
// SAFETY: `ptr` and `field` are from the same object.
|
||||
let offset = unsafe { field.cast::<u8>().offset_from(ptr.cast::<u8>()) };
|
||||
|
||||
// GOOD: Explicitly justifies every requirement, even trivial ones.
|
||||
// SAFETY:
|
||||
// - `ptr` and `field` are derived from the same allocated object [1].
|
||||
// - The distance between them is trivially a multiple of `u8`'s size (1) [2],
|
||||
// satisfying `offset_from`'s alignment requirement [1].
|
||||
//
|
||||
// [1] Per https://doc.rust-lang.org/1.91.0/std/primitive.pointer.html#method.offset_from:
|
||||
//
|
||||
// Both pointers must be derived from the same allocated object, and the
|
||||
// distance between them must be a multiple of the element size.
|
||||
//
|
||||
// [2] https://doc.rust-lang.org/1.91.0/reference/type-layout.html#primitive-data-layout
|
||||
let offset = unsafe { field.cast::<u8>().offset_from(ptr.cast::<u8>()) };
|
||||
```
|
||||
Reference in new issue
Block a user