diff --git a/abi_sys/src/lib.rs b/abi_sys/src/lib.rs index 2f583ac..b7ac704 100644 --- a/abi_sys/src/lib.rs +++ b/abi_sys/src/lib.rs @@ -8,20 +8,21 @@ use embedded_graphics::{ use embedded_sdmmc::DirEntry; use strum::EnumIter; -pub const ABI_CALL_TABLE_COUNT: usize = 9; +pub const ABI_CALL_TABLE_COUNT: usize = 10; #[derive(Clone, Copy, EnumIter)] #[repr(u8)] pub enum CallAbiTable { PrintString = 0, SleepMs = 1, - LockDisplay = 2, - DrawIter = 3, - GetKey = 4, - GenRand = 5, - ListDir = 6, - ReadFile = 7, - FileLen = 8, + GetMs = 2, + LockDisplay = 3, + DrawIter = 4, + GetKey = 5, + GenRand = 6, + ListDir = 7, + ReadFile = 8, + FileLen = 9, } pub type EntryFn = fn(); @@ -39,15 +40,23 @@ pub extern "C" fn print(ptr: *const u8, len: usize) { f(ptr, len); } -pub type SleepAbi = extern "C" fn(ms: u64); +pub type SleepMsAbi = extern "C" fn(ms: u64); #[unsafe(no_mangle)] pub extern "C" fn sleep(ms: u64) { - let f: SleepAbi = + let f: SleepMsAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::SleepMs as usize]) }; f(ms); } +pub type GetMsAbi = extern "C" fn() -> u64; + +#[unsafe(no_mangle)] +pub extern "C" fn get_ms() -> u64 { + let f: GetMsAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::GetMs as usize]) }; + f() +} + pub type LockDisplay = extern "C" fn(lock: bool); #[unsafe(no_mangle)] diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index df6f4e9..3bed7c0 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -1,10 +1,11 @@ use abi_sys::{ - CPixel, DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest, - SleepAbi, keyboard::*, + CPixel, DrawIterAbi, FileLen, GenRand, GetMsAbi, ListDir, LockDisplay, PrintAbi, ReadFile, + RngRequest, SleepMsAbi, keyboard::*, }; use alloc::{string::ToString, vec::Vec}; use core::sync::atomic::Ordering; use embassy_rp::clocks::{RoscRng, clk_sys_freq}; +use embassy_time::Instant; use embedded_graphics::draw_target::DrawTarget; use embedded_sdmmc::{DirEntry, LfnBuffer}; use heapless::spsc::Queue; @@ -26,7 +27,7 @@ pub extern "C" fn print(ptr: *const u8, len: usize) { } } -const _: SleepAbi = sleep; +const _: SleepMsAbi = 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; @@ -36,6 +37,15 @@ pub extern "C" fn sleep(ms: u64) { } } +pub static mut MS_SINCE_LAUNCH: Option = None; + +const _: GetMsAbi = get_ms; +pub extern "C" fn get_ms() -> u64 { + Instant::now() + .duration_since(unsafe { MS_SINCE_LAUNCH.unwrap() }) + .as_millis() +} + const _: LockDisplay = lock_display; pub extern "C" fn lock_display(lock: bool) { FB_PAUSED.store(lock, Ordering::Relaxed); diff --git a/kernel/src/elf.rs b/kernel/src/elf.rs index 0bc6591..2fcec1b 100644 --- a/kernel/src/elf.rs +++ b/kernel/src/elf.rs @@ -198,6 +198,7 @@ fn patch_abi( let ptr = match call { CallAbiTable::PrintString => abi::print as usize, CallAbiTable::SleepMs => abi::sleep as usize, + CallAbiTable::GetMs => abi::get_ms as usize, CallAbiTable::LockDisplay => abi::lock_display as usize, CallAbiTable::DrawIter => abi::draw_iter as usize, CallAbiTable::GetKey => abi::get_key as usize, diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 431fc50..57490ec 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -18,7 +18,7 @@ mod usb; mod utils; use crate::{ - abi::KEY_CACHE, + abi::{KEY_CACHE, MS_SINCE_LAUNCH}, display::{FRAMEBUFFER, display_handler, init_display}, peripherals::{ conf_peripherals, @@ -56,7 +56,7 @@ use embassy_rp::{ use embassy_sync::{ blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel, signal::Signal, }; -use embassy_time::{Delay, Timer}; +use embassy_time::{Delay, Instant, Timer}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_sdmmc::SdCard as SdmmcSdCard; use static_cell::StaticCell; @@ -142,6 +142,7 @@ async fn userland_task() { MSC_SHUTDOWN.signal(()); } + unsafe { MS_SINCE_LAUNCH = Some(Instant::now()) }; defmt::info!("Executing Binary"); entry();