From ec25ee86014d021d0838e8c8addf41bf1d604d46 Mon Sep 17 00:00:00 2001 From: sawyer bristol Date: Thu, 4 Sep 2025 18:33:43 -0600 Subject: [PATCH] fix framebuffer crash --- kernel/src/abi.rs | 22 ++++++++++++++-------- kernel/src/display.rs | 30 +++++++++++++----------------- kernel/src/main.rs | 3 +-- kernel/src/ui.rs | 19 ++++++------------- 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index 4463097..889a0f3 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -24,17 +24,23 @@ pub extern "Rust" fn print(msg: &str) { defmt::info!("{:?}", msg); } +// TODO: maybe return result pub extern "Rust" fn draw_iter(pixels: &[Pixel]) { - let framebuffer = block_on(FRAMEBUFFER.lock()); - framebuffer - .borrow_mut() - .as_mut() - .unwrap() - .draw_iter(pixels.iter().copied()) - .unwrap(); + for _ in 0..10 { + if let Some(mut framebuffer) = FRAMEBUFFER.try_lock().ok() { + for _ in 0..10 { + // kernel takes() framebuffer + if let Some(framebuffer) = framebuffer.as_mut() { + framebuffer.draw_iter(pixels.iter().copied()).unwrap(); + } + break; + } + break; + } + cortex_m::asm::nop(); + } } pub extern "Rust" fn get_key() -> Option { - defmt::info!("get key called"); unsafe { KEY_CACHE.dequeue() } } diff --git a/kernel/src/display.rs b/kernel/src/display.rs index 388f9bf..7f27811 100644 --- a/kernel/src/display.rs +++ b/kernel/src/display.rs @@ -1,10 +1,9 @@ -use core::cell::RefCell; use embassy_rp::{ gpio::{Level, Output}, peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, spi::{Async, Spi}, }; -use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex}; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; use embassy_time::{Delay, Timer}; use embedded_hal_bus::spi::ExclusiveDevice; use st7365p_lcd::{FrameBuffer, ST7365P}; @@ -22,8 +21,7 @@ pub const SCREEN_HEIGHT: usize = 320; type FB = FrameBuffer; static FRAMEBUFFER_CELL: StaticCell = StaticCell::new(); -pub static FRAMEBUFFER: Mutex>> = - Mutex::new(RefCell::new(None)); +pub static FRAMEBUFFER: Mutex> = Mutex::new(None); pub async fn init_display( spi: Spi<'static, SPI1, Async>, @@ -45,25 +43,23 @@ pub async fn init_display( display.set_custom_orientation(0x40).await.unwrap(); framebuffer.draw(&mut display).await.unwrap(); display.set_on().await.unwrap(); - FRAMEBUFFER - .lock() - .await - .swap(&RefCell::new(Some(framebuffer))); + FRAMEBUFFER.lock().await.replace(framebuffer); display } pub async fn display_handler(mut display: DISPLAY) { loop { - FRAMEBUFFER - .lock() - .await - .borrow_mut() - .as_mut() - .unwrap() - .partial_draw_batched(&mut display) - .await - .unwrap(); + let fb: &mut FB = { + let mut guard = FRAMEBUFFER.lock().await; + guard.take().unwrap() // take ownership + }; // guard dropped + + fb.partial_draw_batched(&mut display).await.unwrap(); + + // Put it back + FRAMEBUFFER.lock().await.replace(fb); + Timer::after_millis(32).await; // 30 fps } } diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 57b696e..27451df 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -181,8 +181,6 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) { ); let display = init_display(spi, display.cs, display.data, display.reset).await; - DRIVERS_READY.signal(()); - let display_fut = display_handler(display); { @@ -204,6 +202,7 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) { let usb_fut = usb_handler(usb); ENABLE_SCSI.store(true, core::sync::atomic::Ordering::Relaxed); + DRIVERS_READY.signal(()); join3(usb_fut, display_fut, async { loop { Timer::after_millis(100).await; diff --git a/kernel/src/ui.rs b/kernel/src/ui.rs index acb80fd..18c8d1a 100644 --- a/kernel/src/ui.rs +++ b/kernel/src/ui.rs @@ -51,6 +51,9 @@ impl UI UI UI