use C abi for syscalls

This commit is contained in:
2025-09-26 23:39:19 -06:00
parent bf3b37783f
commit 7bd6012748
5 changed files with 61 additions and 52 deletions

View File

@@ -1,4 +1,6 @@
use abi_sys::{DrawIterAbi, GetKeyAbi, LockDisplay, PrintAbi, RngRequest, SleepAbi};
use abi_sys::{
DrawIterAbi, GenRand, GetKeyAbi, LockDisplay, Modifiers, PrintAbi, RngRequest, SleepAbi,
};
use core::sync::atomic::Ordering;
use embassy_rp::clocks::{RoscRng, clk_sys_freq};
use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565};
@@ -9,18 +11,20 @@ use crate::{
display::{FB_PAUSED, FRAMEBUFFER},
};
// ensure the abi and the kernel fn signatures are the same
const _: PrintAbi = print;
const _: SleepAbi = sleep;
const _: LockDisplay = lock_display;
const _: DrawIterAbi = draw_iter;
const _: GetKeyAbi = get_key;
pub extern "C" fn print(ptr: *const u8, len: usize) {
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
let slice = unsafe { core::slice::from_raw_parts(ptr, len) };
pub extern "Rust" fn print(msg: &str) {
defmt::info!("{:?}", msg);
if let Ok(msg) = core::str::from_utf8(slice) {
defmt::info!("print: {}", msg);
} else {
defmt::warn!("print: <invalid utf8>");
}
}
pub extern "Rust" fn sleep(ms: u64) {
const _: SleepAbi = sleep;
pub extern "C" fn sleep(ms: u64) {
let cycles_per_ms = clk_sys_freq() / 1000;
let total_cycles = ms * cycles_per_ms as u64;
@@ -29,20 +33,33 @@ pub extern "Rust" fn sleep(ms: u64) {
}
}
pub extern "Rust" fn lock_display(lock: bool) {
const _: LockDisplay = lock_display;
pub extern "C" fn lock_display(lock: bool) {
FB_PAUSED.store(lock, Ordering::Relaxed);
}
const _: DrawIterAbi = draw_iter;
// TODO: maybe return result
pub extern "Rust" fn draw_iter(pixels: &[Pixel<Rgb565>]) {
pub extern "C" fn draw_iter(pixels: *const Pixel<Rgb565>, len: usize) {
let pixels = unsafe { core::slice::from_raw_parts(pixels, len) };
unsafe { FRAMEBUFFER.draw_iter(pixels.iter().copied()).unwrap() }
}
pub extern "Rust" fn get_key() -> Option<KeyEvent> {
unsafe { KEY_CACHE.dequeue() }
const _: GetKeyAbi = get_key;
pub extern "C" fn get_key() -> KeyEvent {
if let Some(event) = unsafe { KEY_CACHE.dequeue() } {
event
} else {
KeyEvent {
key: abi_sys::KeyCode::Unknown(0),
state: abi_sys::KeyState::Idle,
mods: Modifiers::empty(),
}
}
}
pub extern "Rust" fn gen_rand(req: &mut RngRequest) {
const _: GenRand = gen_rand;
pub extern "C" fn gen_rand(req: &mut RngRequest) {
let mut rng = RoscRng;
match req {