make all syscalls ffi compat

This commit is contained in:
2025-10-05 18:24:44 -06:00
parent af238b2847
commit ddcdd5942a
4 changed files with 73 additions and 14 deletions

View File

@@ -25,11 +25,12 @@ pub fn get_key() -> KeyEvent {
} }
pub mod display { pub mod display {
use abi_sys::CPixel;
use embedded_graphics::{ use embedded_graphics::{
Pixel, Pixel,
geometry::{Dimensions, Point}, geometry::{Dimensions, Point},
pixelcolor::{Rgb565, RgbColor}, pixelcolor::{Rgb565, RgbColor},
prelude::{DrawTarget, Size}, prelude::{DrawTarget, IntoStorage, Size},
primitives::Rectangle, primitives::Rectangle,
}; };
@@ -42,8 +43,27 @@ pub mod display {
abi_sys::lock_display(lock); abi_sys::lock_display(lock);
} }
const BUF_SIZE: usize = 1024; // tune this for performance
fn draw_iter(pixels: &[Pixel<Rgb565>]) { fn draw_iter(pixels: &[Pixel<Rgb565>]) {
abi_sys::draw_iter(pixels.as_ptr(), pixels.len()) let mut cpixels: [CPixel; BUF_SIZE] = [const {
CPixel {
x: 0,
y: 0,
color: 0,
}
}; BUF_SIZE];
for (px, cpx) in pixels.iter().zip(cpixels.iter_mut()) {
let Pixel(pos, color) = px;
let color: u16 = color.into_storage(); // convert Rgb565 -> u16
*cpx = CPixel {
x: pos.x,
y: pos.y,
color,
};
}
abi_sys::draw_iter(cpixels.as_ptr(), cpixels.len())
} }
pub struct Display; pub struct Display;
@@ -68,7 +88,6 @@ pub mod display {
where where
I: IntoIterator<Item = Pixel<Self::Color>>, I: IntoIterator<Item = Pixel<Self::Color>>,
{ {
const BUF_SIZE: usize = 1024; // tune this for performance
let mut buf: [Pixel565; BUF_SIZE] = [Pixel(Point::new(0, 0), Rgb565::BLACK); BUF_SIZE]; let mut buf: [Pixel565; BUF_SIZE] = [Pixel(Point::new(0, 0), Rgb565::BLACK); BUF_SIZE];
let mut count = 0; let mut count = 0;

View File

@@ -1,10 +1,16 @@
#![no_std] #![no_std]
use embedded_graphics::{Pixel, pixelcolor::Rgb565}; use embedded_graphics::{
Pixel,
pixelcolor::Rgb565,
prelude::{IntoStorage, Point},
};
use embedded_sdmmc::DirEntry; use embedded_sdmmc::DirEntry;
use strum::{EnumCount, EnumIter}; use strum::EnumIter;
#[derive(Clone, Copy, EnumIter, EnumCount)] pub const ABI_CALL_TABLE_COUNT: usize = 9;
#[derive(Clone, Copy, EnumIter)]
#[repr(u8)] #[repr(u8)]
pub enum CallAbiTable { pub enum CallAbiTable {
PrintString = 0, PrintString = 0,
@@ -17,11 +23,12 @@ pub enum CallAbiTable {
ReadFile = 7, ReadFile = 7,
FileLen = 8, FileLen = 8,
} }
pub type EntryFn = fn(); pub type EntryFn = fn();
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
#[unsafe(link_section = ".syscall_table")] #[unsafe(link_section = ".syscall_table")]
pub static mut CALL_ABI_TABLE: [usize; CallAbiTable::COUNT] = [0; CallAbiTable::COUNT]; pub static mut CALL_ABI_TABLE: [usize; ABI_CALL_TABLE_COUNT] = [0; ABI_CALL_TABLE_COUNT];
pub type PrintAbi = extern "C" fn(ptr: *const u8, len: usize); pub type PrintAbi = extern "C" fn(ptr: *const u8, len: usize);
@@ -50,10 +57,37 @@ pub extern "C" fn lock_display(lock: bool) {
f(lock); f(lock);
} }
pub type DrawIterAbi = extern "C" fn(ptr: *const Pixel<Rgb565>, len: usize); #[repr(C)]
#[derive(Copy, Clone)]
pub struct CPixel {
pub x: i32,
pub y: i32,
pub color: u16,
}
impl Into<CPixel> for Pixel<Rgb565> {
fn into(self) -> CPixel {
CPixel {
x: self.0.x,
y: self.0.y,
color: self.1.into_storage(),
}
}
}
impl Into<Pixel<Rgb565>> for CPixel {
fn into(self) -> Pixel<Rgb565> {
let r5 = ((self.color >> 11) & 0x1F) as u8;
let g6 = ((self.color >> 5) & 0x3F) as u8;
let b5 = (self.color & 0x1F) as u8;
Pixel(Point::new(self.x, self.y), Rgb565::new(r5, g6, b5))
}
}
pub type DrawIterAbi = extern "C" fn(ptr: *const CPixel, len: usize);
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub extern "C" fn draw_iter(ptr: *const Pixel<Rgb565>, len: usize) { pub extern "C" fn draw_iter(ptr: *const CPixel, len: usize) {
let f: DrawIterAbi = let f: DrawIterAbi =
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) }; unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) };
f(ptr, len); f(ptr, len);

4
cbindgen.toml Normal file
View File

@@ -0,0 +1,4 @@
language = "C"
[macro_expansion]
bitflags = true

View File

@@ -1,6 +1,6 @@
use abi_sys::{ use abi_sys::{
DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest, SleepAbi, CPixel, DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest,
keyboard::*, SleepAbi, keyboard::*,
}; };
use alloc::{string::ToString, vec::Vec}; use alloc::{string::ToString, vec::Vec};
use core::sync::atomic::Ordering; use core::sync::atomic::Ordering;
@@ -43,10 +43,12 @@ pub extern "C" fn lock_display(lock: bool) {
const _: DrawIterAbi = draw_iter; const _: DrawIterAbi = draw_iter;
// TODO: maybe return result // TODO: maybe return result
pub extern "C" fn draw_iter(pixels: *const Pixel<Rgb565>, len: usize) { pub extern "C" fn draw_iter(cpixels: *const CPixel, len: usize) {
// SAFETY: caller guarantees `ptr` is valid for `len` bytes // SAFETY: caller guarantees `ptr` is valid for `len` bytes
let pixels = unsafe { core::slice::from_raw_parts(pixels, len) }; let cpixels = unsafe { core::slice::from_raw_parts(cpixels, len) };
unsafe { FRAMEBUFFER.draw_iter(pixels.iter().copied()).unwrap() }
let iter = cpixels.iter().copied().map(|c: CPixel| c.into());
unsafe { FRAMEBUFFER.draw_iter(iter).unwrap() }
} }
pub static mut KEY_CACHE: Queue<KeyEvent, 32> = Queue::new(); pub static mut KEY_CACHE: Queue<KeyEvent, 32> = Queue::new();