| use crate::os::xous::ffi::Connection; |
| use core::sync::atomic::{AtomicU32, Ordering}; |
| |
| /// Group `usize` bytes into a `usize` and return it, beginning |
| /// from `offset` * sizeof(usize) bytes from the start. For example, |
| /// `group_or_null([1,2,3,4,5,6,7,8], 1)` on a 32-bit system will |
| /// return a usize with 5678 packed into it. |
| fn group_or_null(data: &[u8], offset: usize) -> usize { |
| let start = offset * core::mem::size_of::<usize>(); |
| let mut out_array = [0u8; core::mem::size_of::<usize>()]; |
| if start < data.len() { |
| for (dest, src) in out_array.iter_mut().zip(&data[start..]) { |
| *dest = *src; |
| } |
| } |
| usize::from_le_bytes(out_array) |
| } |
| |
| pub(crate) enum LogScalar<'a> { |
| /// A panic occurred, and a panic log is forthcoming |
| BeginPanic, |
| |
| /// Some number of bytes will be appended to the log message |
| AppendPanicMessage(&'a [u8]), |
| } |
| |
| impl<'a> Into<[usize; 5]> for LogScalar<'a> { |
| fn into(self) -> [usize; 5] { |
| match self { |
| LogScalar::BeginPanic => [1000, 0, 0, 0, 0], |
| LogScalar::AppendPanicMessage(c) => |
| // Text is grouped into 4x `usize` words. The id is 1100 plus |
| // the number of characters in this message. |
| // Ignore errors since we're already panicking. |
| { |
| [ |
| 1100 + c.len(), |
| group_or_null(&c, 0), |
| group_or_null(&c, 1), |
| group_or_null(&c, 2), |
| group_or_null(&c, 3), |
| ] |
| } |
| } |
| } |
| } |
| |
| pub(crate) enum LogLend { |
| StandardOutput = 1, |
| StandardError = 2, |
| } |
| |
| impl Into<usize> for LogLend { |
| fn into(self) -> usize { |
| self as usize |
| } |
| } |
| |
| /// Return a `Connection` to the log server, which is used for printing messages to |
| /// the console and reporting panics. If the log server has not yet started, this |
| /// will block until the server is running. It is safe to call this multiple times, |
| /// because the address is shared among all threads in a process. |
| pub(crate) fn log_server() -> Connection { |
| static LOG_SERVER_CONNECTION: AtomicU32 = AtomicU32::new(0); |
| |
| let cid = LOG_SERVER_CONNECTION.load(Ordering::Relaxed); |
| if cid != 0 { |
| return cid.into(); |
| } |
| |
| let cid = crate::os::xous::ffi::connect("xous-log-server ".try_into().unwrap()).unwrap(); |
| LOG_SERVER_CONNECTION.store(cid.into(), Ordering::Relaxed); |
| cid |
| } |