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/sys/arm_compat/fs.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

74 lines
2.5 KiB
Rust

// SPDX-License-Identifier: Apache-2.0 OR MIT
use core::ffi::CStr;
use super::{OpenMode, sys_flen, sys_open, sys_seek};
pub(crate) use super::{sys_remove as unlink, sys_rename as rename};
use crate::{
fd::{BorrowedFd, OwnedFd},
fs, io,
};
pub(crate) struct Metadata {
size: u64,
}
impl Metadata {
#[inline]
pub(crate) fn size(&self) -> u64 {
self.size
}
}
pub(crate) fn metadata(fd: BorrowedFd<'_>) -> io::Result<Metadata> {
Ok(Metadata { size: sys_flen(fd)? as u64 })
}
pub(crate) fn open(path: &CStr, options: &fs::OpenOptions) -> io::Result<OwnedFd> {
match (options.write, options.append) {
(true, false) => {}
(false, false) => {
if options.truncate || options.create {
return Err(io::Error::EINVAL);
}
}
(_, true) => {
if options.truncate {
return Err(io::Error::EINVAL);
}
}
}
// Refs: https://github.com/openocd-org/openocd/blob/HEAD/src/target/semihosting_common.c
let mode = match (options.read, options.write, options.append, options.create, options.truncate)
{
(true, false, false, false, false) => OpenMode::RDONLY_BINARY,
(true, true, false, false, false) => OpenMode::RDWR_BINARY,
(false, true, false, true, true) => OpenMode::WRONLY_TRUNC_BINARY,
(true, true, false, true, true) => OpenMode::RDWR_TRUNC_BINARY,
(false, true, true, true, false) => OpenMode::WRONLY_APPEND_BINARY,
(true, true, true, true, false) => OpenMode::RDWR_APPEND_BINARY,
_ => return Err(io::Error::UNSUPPORTED_PLATFORM),
};
sys_open(path, mode)
}
// TODO(arm_compat): Arm semihosting doesn't provide Large-file support (LFS).
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
pub(crate) fn seek(fd: BorrowedFd<'_>, pos: io::SeekFrom) -> io::Result<u64> {
let abs_pos = match pos {
io::SeekFrom::Start(pos) => pos,
io::SeekFrom::End(offset) => {
let len = sys_flen(fd)? as u64;
let pos = (len as i64).saturating_add(offset);
if pos.is_negative() {
return Err(io::Error::EINVAL);
}
pos as u64
} // io::SeekFrom::Current(_offset) => todo!(),
};
// sys_seek may succeed without this guard, but make the behavior consistent with other platforms.
let abs_pos = isize::try_from(abs_pos).map_err(|_| io::Error::EINVAL)?;
unsafe { sys_seek(fd, abs_pos as usize)? }
Ok(abs_pos as u64)
}