This repository has been archived on 2026-08-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
donglora/vendor/semihosting/src/utils.rs
T
swaitsandClaude Opus 4.6 3102fc747a 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>
2026-03-29 20:42:54 -06:00

144 lines
6.3 KiB
Rust

// SPDX-License-Identifier: Apache-2.0 OR MIT
use core::mem::MaybeUninit;
// rustfmt-compatible cfg_select/cfg_if alternative
// Note: This macro is cfg_sel!({ }), not cfg_sel! { }.
// An extra brace is used in input to make contents rustfmt-able.
macro_rules! cfg_sel {
({#[cfg(else)] { $($output:tt)* }}) => {
$($output)*
};
({
#[cfg($cfg:meta)]
{ $($output:tt)* }
$($( $rest:tt )+)?
}) => {
#[cfg($cfg)]
cfg_sel! {{#[cfg(else)] { $($output)* }}}
$(
#[cfg(not($cfg))]
cfg_sel! {{ $($rest)+ }}
)?
};
}
// <[_]>::assume_init_ref requires Rust 1.93.
/// # Safety
///
/// Calling this when the content is not yet fully initialized causes undefined
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
/// the slice really is in an initialized state.
#[allow(dead_code)]
#[inline(always)]
pub(crate) const unsafe fn slice_assume_init_ref<T>(s: &[MaybeUninit<T>]) -> &[T] {
// SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
// `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
// reference and thus guaranteed to be valid for reads.
unsafe { &*(s as *const [MaybeUninit<T>] as *const [T]) }
}
// <[_]>::assume_init_mut requires Rust 1.93.
/// # Safety
///
/// Calling this when the content is not yet fully initialized causes undefined
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
/// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot
/// be used to initialize a `MaybeUninit` slice.
#[inline(always)]
pub(crate) unsafe fn slice_assume_init_mut<T>(s: &mut [MaybeUninit<T>]) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
// mutable reference which is also guaranteed to be valid for writes.
unsafe { &mut *(s as *mut [MaybeUninit<T>] as *mut [T]) }
}
// This module provides core::ptr strict_provenance/exposed_provenance polyfill for pre-1.84 rustc.
pub(crate) mod ptr {
cfg_sel!({
#[cfg(not(semihosting_no_strict_provenance))]
{
pub(crate) use core::ptr::{
with_exposed_provenance, with_exposed_provenance_mut, without_provenance_mut,
};
}
#[cfg(else)]
{
#[inline(always)]
#[must_use]
pub(crate) const fn without_provenance_mut<T>(addr: usize) -> *mut T {
// An int-to-pointer transmute currently has exactly the intended semantics: it creates a
// pointer without provenance. Note that this is *not* a stable guarantee about transmute
// semantics, it relies on sysroot crates having special status.
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
// pointer).
#[cfg(miri)]
unsafe {
core::mem::transmute(addr)
}
// Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mod.rs#L607
#[cfg(not(miri))]
{
addr as *mut T
}
}
#[inline(always)]
#[must_use]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub(crate) fn with_exposed_provenance<T>(addr: usize) -> *const T {
addr as *const T
}
#[inline(always)]
#[must_use]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub(crate) fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T {
addr as *mut T
}
pub(crate) trait PtrExt<T: ?Sized>: Copy {
#[must_use]
fn addr(self) -> usize;
}
impl<T: ?Sized> PtrExt<T> for *const T {
#[inline(always)]
#[must_use]
fn addr(self) -> usize {
// A pointer-to-integer transmute currently has exactly the right semantics: it returns the
// address without exposing the provenance. Note that this is *not* a stable guarantee about
// transmute semantics, it relies on sysroot crates having special status.
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
// provenance).
#[cfg(miri)]
unsafe {
core::mem::transmute(self.cast::<()>())
}
// Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mut_ptr.rs#L210
#[cfg(not(miri))]
{
self.cast::<()>() as usize
}
}
}
impl<T: ?Sized> PtrExt<T> for *mut T {
#[inline(always)]
#[must_use]
fn addr(self) -> usize {
// A pointer-to-integer transmute currently has exactly the right semantics: it returns the
// address without exposing the provenance. Note that this is *not* a stable guarantee about
// transmute semantics, it relies on sysroot crates having special status.
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
// provenance).
#[cfg(miri)]
unsafe {
core::mem::transmute(self.cast::<()>())
}
// Using transmute doesn't work with CHERI: https://github.com/kent-weak-memory/rust/blob/0c0ca909de877f889629057e1ddf139527446d75/library/core/src/ptr/mut_ptr.rs#L210
#[cfg(not(miri))]
{
self.cast::<()>() as usize
}
}
}
}
});
}