diff --git a/Cargo.lock b/Cargo.lock index 130e238..da46856 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,7 @@ dependencies = [ name = "abi" version = "0.1.0" dependencies = [ + "embedded-graphics", "shared", ] diff --git a/abi/Cargo.toml b/abi/Cargo.toml index 80cc90d..e7aaf0e 100644 --- a/abi/Cargo.toml +++ b/abi/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" edition = "2024" [dependencies] +embedded-graphics = "0.8.1" shared = { path = "../shared" } diff --git a/abi/src/lib.rs b/abi/src/lib.rs index f97455e..2ed0f97 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -1,11 +1,16 @@ #![no_std] -use core::ffi::c_void; +pub use embedded_graphics::{ + Pixel, + geometry::Point, + pixelcolor::{Rgb565, RgbColor}, +}; use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers}; // Instead of extern, declare a static pointer in a dedicated section #[unsafe(no_mangle)] #[unsafe(link_section = ".user_reloc")] +#[allow(non_upper_case_globals)] pub static mut call_abi_ptr: usize = 0; // Helper to call it @@ -16,5 +21,8 @@ pub unsafe fn call_abi(call: *const Syscall) { #[repr(C)] pub enum Syscall { - DrawPixel { x: u32, y: u32, color: u16 }, + DrawIter { + pixels: *const Pixel, + len: usize, + }, } diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index 1f8c3ba..dcc1bed 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -3,6 +3,7 @@ use defmt::info; use embassy_futures::block_on; use embedded_graphics::{ Drawable, + draw_target::DrawTarget, pixelcolor::Rgb565, prelude::{Point, RgbColor, Size}, primitives::{PrimitiveStyle, Rectangle, StyledDrawable}, @@ -15,19 +16,17 @@ pub extern "C" fn call_abi(call: *const Syscall) { info!("called abi"); let call = unsafe { &*call }; match call { - Syscall::DrawPixel { x, y, color } => { - draw_pixel(*x, *y, *color); + Syscall::DrawIter { pixels, len } => { + // SAFETY: we're trusting the user program here + let slice = unsafe { core::slice::from_raw_parts(*pixels, *len) }; + + let framebuffer = block_on(FRAMEBUFFER.lock()); + framebuffer + .borrow_mut() + .as_mut() + .unwrap() + .draw_iter(slice.iter().copied()) + .unwrap(); } } } - -fn draw_pixel(x: u32, y: u32, color: u16) { - info!("draw pixel abi called"); - let framebuffer = block_on(FRAMEBUFFER.lock()); - Rectangle::new(Point::new(x as i32, y as i32), Size::new(1, 1)) - .draw_styled( - &PrimitiveStyle::with_fill(Rgb565::RED), - *framebuffer.borrow_mut().as_mut().unwrap(), - ) - .unwrap(); -} diff --git a/user-apps/calculator/Cargo.toml b/user-apps/calculator/Cargo.toml index 13d39be..8b3311f 100644 --- a/user-apps/calculator/Cargo.toml +++ b/user-apps/calculator/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] -abi = { path ="../../abi" } +abi = { path = "../../abi" } diff --git a/user-apps/calculator/src/main.rs b/user-apps/calculator/src/main.rs index 3c26e28..3a174be 100644 --- a/user-apps/calculator/src/main.rs +++ b/user-apps/calculator/src/main.rs @@ -1,7 +1,7 @@ #![no_std] #![no_main] -use abi::{Syscall, call_abi}; +use abi::{Pixel, Point, Rgb565, RgbColor, Syscall, call_abi}; use core::panic::PanicInfo; #[panic_handler] @@ -11,14 +11,23 @@ fn panic(_info: &PanicInfo) -> ! { #[unsafe(no_mangle)] pub extern "C" fn _start() { - for i in 0..300 { - for o in 0..300 { - let call = Syscall::DrawPixel { - x: i, - y: o, - color: 0, - }; - unsafe { call_abi(&call) }; - } + // Local pixel buffer + let mut pixels = [Pixel(Point { x: 50, y: 50 }, Rgb565::RED); 300]; + for (i, p) in pixels.iter_mut().enumerate() { + *p = Pixel( + Point { + x: i as i32, + y: i as i32, + }, + Rgb565::RED, + ) } + + // Construct syscall with raw pointer + length + let call = Syscall::DrawIter { + pixels: pixels.as_ptr(), // raw pointer + len: pixels.len(), // number of elements + }; + + unsafe { call_abi(&call) }; }