AugustoRoman[m]: Simplified Code is: ``` // Using Mutex/Option wrapper as suggested by https://embassy.dev/book/dev/sharing_peripherals.html#_sharing_using_a_mutex static HUB75: Mutex>> = Mutex::new(None); static DISPLAY: TripleBuffer = TripleBuffer::new(); ... #[cortex_m_rt::entry] fn main() -> ! { ... let hub75 = Hub75::new(...); { HUB75.try_lock().unwrap().replace(hub75); } ... // spawn core0_display and others } #[embassy_executor::task] async fn core0_display() { let mut hub75_lock = HUB75.lock().await; let hub75 = hub75_lock.as_mut().unwrap(); loop { DISPLAY.view(|display| async { // ERROR IS HERE hub75.draw_frame(0, &display.buffer).await; // hub75 lasts forever, hub75.draw_frame(1, &display.buffer).await; // display is temporary. }).await; // Should be OK? } } ... impl Hub75<'static, PIO> { pub async fn draw_frame(&mut self, bit: usize, frame: &[u32; 64 * 32]) { ... } } ... pub struct TripleBuffer { buffers: [Mutex; 3], readable: Mutex, spare: Mutex, writeable: Mutex, } pub struct FrameBuffer { pub buffer: [u32; (WIDTH*HEIGHT) as usize] } struct ReadableContainer { buffer_idx: usize } struct SpareContainer { buffer_idx: usize, is_published: bool } struct WriteableContainer { buffer_idx: usize, is_dirty: bool } impl TripleBuffer { pub const fn new() -> Self { ... } pub async fn view(&self, op: F) where F: FnOnce(&FrameBuffer) -> Fut, Fut: Future, { let mut rc = self.readable.lock().await; { let mut spare = self.spare.lock().await; if spare.is_published { swap(&mut spare.buffer_idx, &mut rc.buffer_idx); } } let buf = &self.buffers[rc.buffer_idx].lock().await; op(&buf).await; _ = rc; // does this matter? make sure it's still alive, but probably doesn't matter. } ... } ```