use C abi for syscalls
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user