diff --git a/Cargo.toml b/Cargo.toml --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ [dependencies] linked_list_allocator = "0.6.6" + +[features] +panic_console = [] [dev-dependencies] corepack = { version = "0.4.0", default-features = false, features = ["alloc"] } diff --git a/src/lang_items.rs b/src/lang_items.rs index ab2c945..deef73b 100644 --- a/src/lang_items.rs +++ b/src/lang_items.rs @@ -18,10 +18,14 @@ //! `rustc_main`. That's covered by the `_start` function in the root of this //! crate. +#[cfg(feature = "panic_console")] +use crate::console::Console; use crate::led; use crate::timer; use crate::timer::Duration; use core::alloc::Layout; +#[cfg(feature = "panic_console")] +use core::fmt::Write; use core::panic::PanicInfo; #[lang = "start"] @@ -42,11 +46,7 @@ } } -#[panic_handler] -fn panic_handler(_info: &PanicInfo) -> ! { +fn flash_all_leds() -> ! { - // Signal a panic using the LowLevelDebug capsule (if available). - super::debug::low_level_status_code(1); - // Flash all LEDs (if available). loop { for led in led::all() { @@ -60,6 +59,34 @@ } } +#[cfg(feature = "panic_console")] +#[panic_handler] +fn panic_handler(info: &PanicInfo) -> ! { + // Signal a panic using the LowLevelDebug capsule (if available). + super::debug::low_level_status_code(1); + + let mut console = Console::new(); + writeln!(console, "{}", info).ok(); + // Force the kernel to report the panic cause, by reading an invalid address. + // The memory protection unit should be setup by the Tock kernel to prevent apps from accessing + // address zero. + unsafe { + core::ptr::read_volatile(0 as *const usize); + } + // We still flash the LEDs in case for some reason the previous line didn't cause a crash in + // the kernel. + flash_all_leds(); +} + +#[cfg(not(feature = "panic_console"))] +#[panic_handler] +fn panic_handler(_info: &PanicInfo) -> ! { + // Signal a panic using the LowLevelDebug capsule (if available). + super::debug::low_level_status_code(1); + + flash_all_leds(); +} + #[alloc_error_handler] fn cycle_leds(_: Layout) -> ! { loop {